There are two approaches to dropping root privileges:
- drop the privileges temporarily, and get them back at a later time - in case the application needs to perform some elevated work after initialization
- drop the privileges permanently - in case the application has finished the elevated work at initialization
Dropping root permissions temporarily
The following code snippet does the privilege dropping in C:int drop_root_effective(void) { struct passwd *pw; pw = getpwnam("nobody"); assert(pw != NULL); if(pw == NULL) { return 0; } if(setegid(pw->pw_gid) != 0 || seteuid(pw->pw_uid) != 0 ) { return 0; } return 1; }The function above changes the effective group and user IDs of the program to the user "nobody" - which is a default non-privileged user on Linux systems. It is important to drop first the group id via setegid and then the user id via seteuid, as after dropping the user id, the call to setegid will fail (you lost your permission).
In case the application needs to do some processing using elevated privileges, it can gain them back using the following snippet:
int get_root(void) { if(seteuid(0) != 0 || setegid(0) != 0) { return 0; } return 1; }Calling setegid and seteuid with 0 as parameter will gain you back the root privileges.
Dropping root permissions permanently
The C code is as follows:int drop_root_permanent(void) { struct passwd *pw; pw = getpwnam("nobody"); assert(pw != NULL); if(pw == NULL) { return 0; } if(setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0 ) { return 0; } return 1; }After calling setgid and setuid you shouldn't be able to get the root permissions back. If paranoid, you can double-check by using the get_root function above, with a negative check.
On newer kernels one can stop using root permissions by setting different capabilities for the application.
No comments:
Post a Comment