summaryrefslogtreecommitdiffhomepage
path: root/libbb/change_identity.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/change_identity.c')
-rw-r--r--libbb/change_identity.c23
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 @@
/* Become the user and group(s) specified by PW. */
void FAST_FUNC change_identity(const struct passwd *pw)
{
- if (initgroups(pw->pw_name, pw->pw_gid) == -1)
- bb_perror_msg_and_die("can't set groups");
+ int res;
+
+ res = initgroups(pw->pw_name, pw->pw_gid);
endgrent(); /* helps to close a fd used internally by libc */
+
+ if (res != 0) {
+ /*
+ * If initgroups() fails because a system call is unimplemented
+ * then we are running on a Linux kernel compiled without multiuser
+ * support (CONFIG_MULTIUSER is not defined).
+ *
+ * If we are running without multiuser support *and* the target uid
+ * already matches the current uid then we can skip the change of
+ * identity.
+ */
+ if (errno == ENOSYS && pw->pw_uid == getuid()) {
+ return;
+ }
+
+ bb_perror_msg_and_die("can't set groups");
+ }
+
xsetgid(pw->pw_gid);
xsetuid(pw->pw_uid);
}