GNOME Bugzilla – Bug 308050
Failure to start user sessions
Last modified: 2005-06-20 16:33:06 UTC
Distribution/Version: 3.99.5 GDM is completely unable to start a session for a user since the update to 2.8.0.0. After entering a user name and a password, the login dialog appears again and no error is reported on the screen (although it's sent to syslog). It just says "Cannot set effective user/group id". I guess this is a NetBSD specific problem. The issue arises due to the fact that daemon/slave.c code makes two subsequent calls to setegid/seteuid, although the second pair of them is not strictly required. The problem is that these two extra calls are only needed in a branch of the conditional used to check for the home directory, as it raises privileges to the superuser and must be dropped again later. However, if everything is correct, no extra calls should be made to change privileges. Consider the following example, which illustrates what GDM is trying to do (modulo the egid stuff): #include <stdio.h> #include <unistd.h> int main() { if (seteuid(100) == -1) printf("setting 1 failed\n"); if (seteuid(100) == -1) printf("setting 2 failed\n"); return 0; } When run as root under NetBSD, it says: dawn# ./a.out setting 2 failed Moving the offending code block inside the home directory conditional makes GDM work nicely again.
Created attachment 47897 [details] [review] Sample patch.
On 04/25, the patch that fixed bug #301821 moved the seteuid/setegid calls to before the user's $HOME directory check. That patch added the calls before the check, but didn't remove the calls from after the check. It is needless to call these functions twice. So removing the second call, which is more appropriate than the suggested patch that moves the second call into if-test logic.
Are you sure? What happens if the user's home directory does not exist? As I see in the code, he will see a window asking for confirmation to continue the login process. If answered negatively, then there is no problem because the session ends at that point. However, if answered affirmatively, the login will continue, and the user will have higher privileges than he ought to have; that is, user root and gdm's group. (Notice the seteuid(0) and setegid(GdmGroupId) calls inside the conditional.)
Thanks for catching this. I applied the patch that you provided, with some comments. I did miss the seteuid(0)/setgid(GdmGroupId).