next up previous
Next: Running other programs Up: Application layer issues Previous: General section on CGI

Properly dropping privilege

XXX: Shouldn't that go to the solutions chapter?

When you write a daemon that is supposed to drop privilege at some point, you must be careful to do this in the proper sequence. First, you must set the uid after setting group ids; otherwise, setting the gid will fail because you've already dropped your root privilege.

Second, you must make sure you also initialize your supplementary groups. This is a common mistake that has affected a number of network servers, including inetd.

Thus, the proper way to drop privilege in a server is this:

        pwd = getpwnam(username);
        if (pwd == NULL)
                fatal("user not found: %s", username);
        if (initgroups(username, pwd->pw_gid) < 0
         || setgid(pwd->pw_gid) < 0
         || setuid(pwd->pw_uid) < 0)
                fatal("unable to drop privilege: %m");

If you don't care about supplementary groups, you can clear the list of groups altogether by using setgroups(0, NULL).

If your server is also supposed to change its root directory, the call to chroot must happen after initgroups() and before setuid().



Olaf Kirch 2002-01-16