diff options
Diffstat (limited to 'libbb/change_identity.c')
| -rw-r--r-- | libbb/change_identity.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/libbb/change_identity.c b/libbb/change_identity.c index 619db09a8..d48d86326 100644 --- a/libbb/change_identity.c +++ b/libbb/change_identity.c | |||
| @@ -33,9 +33,28 @@ | |||
| 33 | /* Become the user and group(s) specified by PW. */ | 33 | /* Become the user and group(s) specified by PW. */ |
| 34 | void FAST_FUNC change_identity(const struct passwd *pw) | 34 | void FAST_FUNC change_identity(const struct passwd *pw) |
| 35 | { | 35 | { |
| 36 | if (initgroups(pw->pw_name, pw->pw_gid) == -1) | 36 | int res; |
| 37 | bb_perror_msg_and_die("can't set groups"); | 37 | |
| 38 | res = initgroups(pw->pw_name, pw->pw_gid); | ||
| 38 | endgrent(); /* helps to close a fd used internally by libc */ | 39 | endgrent(); /* helps to close a fd used internally by libc */ |
| 40 | |||
| 41 | if (res != 0) { | ||
| 42 | /* | ||
| 43 | * If initgroups() fails because a system call is unimplemented | ||
| 44 | * then we are running on a Linux kernel compiled without multiuser | ||
| 45 | * support (CONFIG_MULTIUSER is not defined). | ||
| 46 | * | ||
| 47 | * If we are running without multiuser support *and* the target uid | ||
| 48 | * already matches the current uid then we can skip the change of | ||
| 49 | * identity. | ||
| 50 | */ | ||
| 51 | if (errno == ENOSYS && pw->pw_uid == getuid()) { | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | bb_perror_msg_and_die("can't set groups"); | ||
| 56 | } | ||
| 57 | |||
| 39 | xsetgid(pw->pw_gid); | 58 | xsetgid(pw->pw_gid); |
| 40 | xsetuid(pw->pw_uid); | 59 | xsetuid(pw->pw_uid); |
| 41 | } | 60 | } |
