diff --git a/src/common/uid.c b/src/common/uid.c index 2c1149e335ff3b575b9a02520a5fb4f621953886..7597fb644d17c5fcc09240061c13f3a42ce0c9a1 100644 --- a/src/common/uid.c +++ b/src/common/uid.c @@ -111,6 +111,24 @@ uid_to_string (uid_t uid) return ustring; } +gid_t +gid_from_uid (uid_t uid) +{ + struct passwd pwd, *result; + char buffer[PW_BUF_SIZE]; + gid_t gid; + int rc; + + rc = getpwuid_r(uid, &pwd, buffer, PW_BUF_SIZE, &result); + if (result == NULL) { + gid = (gid_t) -1; + } else { + gid = result->pw_gid; + } + + return gid; +} + gid_t gid_from_string (char *name) { diff --git a/src/common/uid.h b/src/common/uid.h index 7826e2558b89009e2700688835f323f842a4fbb7..8021390f52054214ef2a9779634b3dbd79d2289b 100644 --- a/src/common/uid.h +++ b/src/common/uid.h @@ -60,6 +60,12 @@ */ uid_t uid_from_string (char *name); +/* + * Return the primary group id for a given user id, or + * (gid_t) -1 on failure. + */ +gid_t gid_from_uid (uid_t uid); + /* * Same as uid_from_name(), but for group name/id. */ diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c index 2f69c0bca3dd5fb2a0aad94a10adc046c841fd74..70e59ef9fcc1aeca38e5783a63ba4f67f961d627 100644 --- a/src/slurmctld/controller.c +++ b/src/slurmctld/controller.c @@ -194,7 +194,7 @@ inline static void _update_cred_key(void); inline static void _usage(char *prog_name); static bool _wait_for_server_thread(void); static void * _assoc_cache_mgr(void *no_data); -static int _become_slurm_user(void); +static void _become_slurm_user(void); typedef struct connection_arg { int newsockfd; @@ -231,11 +231,7 @@ int main(int argc, char *argv[]) * able to write a core dump. */ _init_pidfile(); - - if (_become_slurm_user() < 0) - fatal("Unable to assume slurm user (%s:%d) identity", - slurmctld_conf.slurm_user_name, - slurmctld_conf.slurm_user_id); + _become_slurm_user(); if (stat(slurmctld_conf.mail_prog, &stat_buf) != 0) error("Configured MailProg is invalid"); @@ -1751,42 +1747,46 @@ static void *_assoc_cache_mgr(void *no_data) return NULL; } -static int _become_slurm_user(void) +static void _become_slurm_user(void) { - uid_t uid; - gid_t gid; - const char *username; - struct passwd *pwd; - - uid = slurmctld_conf.slurm_user_id; - username = slurmctld_conf.slurm_user_name; - - if ((pwd = getpwuid (uid)) == NULL) - return error("getpwuid(%d): %m", (int) uid); - - gid = pwd->pw_gid; - - /* - * Warning: we can't call initgroups here becuase we don't - * have proper perms. However, this probably means slurmctld - * was already started as the slurm user, so this is most - * likely safe. - */ - if (getuid() == uid && getgid() == gid) - return (0); + gid_t slurm_user_gid; - if (setgid (gid) < 0) - return error("Failed to set gid to slurm gid (%d): %m", - (int) gid); + /* Determine SlurmUser gid */ + slurm_user_gid = gid_from_uid(slurmctld_conf.slurm_user_id); + if (slurm_user_gid == (gid_t) -1) { + fatal("Failed to determine gid of SlurmUser(%d)", + slurm_user_gid); + } - if (initgroups(username, gid) < 0) - return error("initgroups: %m"); + /* Initialize supplementary groups ID list for SlurmUser */ + if (getuid() == 0) { + /* root does not need supplementary groups */ + if ((slurmctld_conf.slurm_user_id == 0) && + (setgroups(0, NULL) != 0)) { + fatal("Failed to drop supplementary groups, " + "setgroups: %m"); + } else if ((slurmctld_conf.slurm_user_id != getuid()) && + initgroups(slurmctld_conf.slurm_user_name, + slurm_user_gid)) { + fatal("Failed to set supplementary groups, " + "initgroups: %m"); + } + } else { + info("Not running as root. Can't drop supplementary groups"); + } - if (setuid(uid) < 0) - return error("Failed to setuid to slurm uid (%d): %m", - (int) uid); + /* Set GID to GID of SlurmUser */ + if ((slurm_user_gid != getegid()) && + (setgid(slurm_user_gid))) { + fatal("Failed to set GID to %d", slurm_user_gid); + } - return (0); + /* Set UID to UID of SlurmUser */ + if ((slurmctld_conf.slurm_user_id != getuid()) && + (setuid(slurmctld_conf.slurm_user_id))) { + fatal("Can not set uid to SlurmUser(%d): %m", + slurmctld_conf.slurm_user_id); + } } diff --git a/src/slurmd/slurmd/slurmd.c b/src/slurmd/slurmd/slurmd.c index 94125ed53e38de31dc269ccf6a3930118a5a3581..aaa1ed0b469d9fdca08209ca97803fdd3a5f05f1 100644 --- a/src/slurmd/slurmd/slurmd.c +++ b/src/slurmd/slurmd/slurmd.c @@ -44,6 +44,7 @@ #endif #include <fcntl.h> +#include <grp.h> #include <string.h> #include <stdlib.h> #include <pthread.h> @@ -164,6 +165,18 @@ main (int argc, char *argv[]) for (i=3; i<256; i++) (void) close(i); + /* + * Drop supplementary groups. + */ + if (geteuid() == 0) { + if (setgroups(0, NULL) != 0) { + fatal("Failed to drop supplementary groups, " + "setgroups: %m"); + } + } else { + info("Not running as root. Can't drop supplementary groups"); + } + /* * Create and set default values for the slurmd global * config variable "conf"