GNOME Bugzilla – Bug 171188
gdm erroneously removes ~/.Xauthority
Last modified: 2010-06-04 19:37:37 UTC
Please describe the problem: Hi, I was hunting the problem why gdm always removes my ~/.Xauthority file when logging in an generates a temporary one in /tmp. Reason: In line 623 of daemon/auth.c there's a bug: user_auth_exists = (d->userauth != NULL && access (d->userauth, F_OK) == 0); gdm believes that the file existed before only if access return 0. In my case, my home directoy had permissions of drwxr-x--- which returns an EACCESS for the access call, although gdm is running as root. gdm therefore believes that the file had not existed before and was then created by gdm, it therefore removes it then. Two bugs: - gdm should use the Xauthority file even if access fails, because it is running as root. Just try to open it for reading. - gdm should not remove the file if it existed before. Steps to reproduce: 1. Create home directory with existing .Xauthority 2. chgrp directory to root and chmod to drwxr-x--- 3. login and .Xauthority is gone Actual results: .Xauthority is removed by gdm Expected results: .Xauthority is not removed and used for Xauthorization Does this happen every time? yes Other information:
I think this might not be a bug, but a feature. I'm guessing that your $HOME directory is remote-NFS mounted. On my system where my $HOME directory has 700 permissions and the access() returns that I do have access to the file. So the fact that access() is not returning the same value on yours is what makes me believe your $HOME is remote mounted. If this is the case, you could change the NeverPlaceCookiesOnNFS gdm.conf setting to false. However, saving your cookie over NFS is not recommended, it is insecure and easily sniffable over a network. But if you want it to work that way, you can resolve this problem by configuring GDM to allow cookies over NFS. The fact that gdm erases your .Xauthority file is perhaps bad form, but if your GDM configuration doesn't allow you to use Xserver cookies over NFS, I'm not sure it is really so bad. I can't think of a good reason to keep the file around, but if you can tell me why it should I can fix GDM so it won't delete the file.
The home directory is _not_ NFS mounted, it is on the local hard disk.
That's weird. This makes me think that access() works differently on different operating systems. I wouldn't have guessed that to be the case. Anyway, can you try changing your NeverPlaceCookiesOnNFS value so it is true and see if that resolves your problem? Looking at the logic in GDM, it looks like GDM will think the file is NFS mounted if access() fails, but the file can be read.
I'm sorry, a typo - change the setting to "false" (not "true" as I said in my last comment) and see if that makes things work.
Oh, and you should also make sure that your AUTH file is valid. GDM will not accept the file if it isn't owned by the right user, has 0600 permissions and is smaller than GdmUserMaxFile. Also, most things that would cause GDM to reject your auth file would get logged with a debug message if you have "enable=true" set in your gdm.conf file (and restart GDM via gdm-restart). So turning on debug might verify exactly what is causing the file to be rejected.
Of course the AUTH file is valid. But it doesn't matter, since the file is not read.
I'm happy to work with you to try and resolve this problem, but you don't seem to be responding to my questions, which makes it hard for me to understand the nature of the problem. I'm currently guessing that the problem is caused by the access() function working differently on your OS, but I could be wrong. Have you tried changing the value of NeverPlaceCookiesOnNFS in the gdm.conf file to see if that makes things work better? If gdm2 is confused and thinks your $HOME directory is NFS mounted, then this should be a workaround for you. If we determine that this is the problem, then we can look into making the logic smarter about being able to identfy whether a home directory is NFS mounted. I suspect this is the case, since gdm2 interprets the access() function failing as an indication that your $HOME directory is NFS mounted. If this does not fix your problem, turning on debug in the gdm.conf file might cause some useful messages to get logged to your system messages file. Does this reveal anything to you?
1. The problem occurs on my business notebook and I am at home, so I had to configure a second machine to show the same problem. 2. No, changing NeverPlaceCookiesOnNFS doesn't make a difference. 3. Debugging doesn't reveal more than I already know. 4. I don't need further debugging because I have already spotted the bug and given with my bug submission. The bug is simply that the function access does not exactly work the way the code writer assumed. If the permissions and the group of the home directory are not as expected, then access can return a value != 0 although the ~/.Xauthority exists, i.e. when access returns EPERM. man 2 access is the solution. 5. To make it easier I'll attach a traceroute output, where you can also see the syslog messages. regards Hadmut
Created attachment 45303 [details] Traceroute ~/.Xauthority exists, but access() returns a value != 0 access("/mnt/pluto/home/hadmut/.Xauthority", F_OK) = -1 EACCES (Permission denied) gdm erroneously interprets this as if the file did not existed and then removes it. (BTW: Why does gdm remove a file if it believes that it does not exist?)
Okay, let's step through the auth.c logic a bit more closely. 1) It sets up d->userauth. If GdmUserAuthDir is setup it uses that directory, if not it uses the homedir. 2) user_auth_exists flag gets setup up. It's TRUE if d->userauth != NULL and access (d->userauth, F_OK) returns 0. In your case, this flage would be false. Note that this user_auth_exists is only used in the if-test in #3 below. If gdm2 thinks your file is valid, it should enter the else and never use this flag. So the face that this is not returning 0 isn't really the problem, I think. 3) It hits this if-test: if (automatic_tmp_dir || authdir == NULL || ! gdm_file_check ("gdm_auth_user_add", user, authdir, GdmUserAuthFile, TRUE, FALSE, GdmUserMaxFile, GdmRelaxPerms) || ! gdm_auth_file_check ("gdm_auth_user_add", user, d->userauth, TRUE /* absentok */, NULL) || ! try_open_append (d->userauth) || GdmNeverPlaceCookiesOnNFS && ! try_open_read_as_root (d->userauth))) { automatic_tmp_dir only gets set if GdmUserAuthDir is set up in gdm.conf, which I don't think is the case in your system? Is it? authdir should probably not be NULL unless gdm_auth_user_add is being passed in a homedir value of NULL, which is unlikely. The gdm_auth_file_check calls syslog if there are any problems so you should be seeing errors in the system log if errors are happening there. You say you aren't, so I am guessing this isn't the problem. I'd be surprised if the try_open_append function is failing unless root doesn't have access to append to the file. If it doesn't, then You say you have tested setting GdmNeverPlaceCookiesOnNFS to false, so the last section of the if-test shouldn't be where the failure is happening. So, I'm a bit confused why this if-test is failing. I suppose it would be good to fix up the code so it prints more useful debug messages so it is easier to highlight exactly why a failure is happening. In order to fix your issue, I think we need to understand exactly why this if-test is failing on your system. We can do this in one of two ways, I think. Either you can add some "gdm_debug" statements to the code so that it prints out exactly which part(s) of the if-test are failing, or I can go ahead and update the code to do this and provide you with a patch (or you can rebuild from CVS head). Either way, you'll need to recompile the code to build the output. Can you do this? I think the reason gdm deletes the file is that if it isn't going to be used by GDM, then it is not really a useful file on the system.
I have a problem which is related to this - I think. I have GdmNeverPlaceCookiesOnNFS set to false, but still I can't update the .Xauthority file over NFS. Instead, an existing .Xauthority file is removed. I can see from adding debug printing to the the code that what fails is the gdm_safe_fopen_ap call. Shouldn't this be run as seteuid(user)? BTW, this is on a Fedora Core 4, but has been a problem for as long as I can remember. The solution so far has been to no_root_squash the machines, not a very safe solution...........
Upgrading to critical since this really should get fixed.
Is this problem still present? 2.23 uses a very different code to handle auth and it only seems to ever touch gdm's private directory. Sorry for bug spam, trying to find a bug I could hack on and this one seems to be obsolete.
I think this problem does exist in 2.20 still. Considering that this bug relates to security and is of Critical Severity, I think we should keep it open for a while. Due to the security ramifications of this bug, I think it would be good to fix this issue, even though it is in the "old" version of GDM. Since GDM 2.21+ uses very different code, it probably doesn't have the same issue. However would be good if someone could test and verify.
Thanks for taking the time to report this bug. However, you are using a version that is too old and not supported anymore. GNOME developers are no longer working on that version, so unfortunately there will not be any bug fixes for the version that you use. By upgrading to a newer version of GNOME you could receive bug fixes and new functionality. You may need to upgrade your Linux distribution to obtain a newer version of GNOME. Please feel free to reopen this bug if the problem still occurs with a newer version of GNOME.