diff options
-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 | } |