diff --git a/src/monitor/monitor_bootstrap.c b/src/monitor/monitor_bootstrap.c index 6bbee881e9c..4aa4c4107c7 100644 --- a/src/monitor/monitor_bootstrap.c +++ b/src/monitor/monitor_bootstrap.c @@ -90,7 +90,7 @@ int bootstrap_monitor_process(uid_t target_uid, gid_t target_gid) */ sss_log(SSS_LOG_WARNING, "'sssd.conf::"CONFDB_MONITOR_USER_RUNAS"' " "option is deprecated. Run under '"SSSD_USER"' initially instead."); - ret = become_user(target_uid, target_gid); /* drops all caps */ + ret = become_user(target_uid, target_gid, false); /* drops all caps */ if (ret != 0) { sss_log(SSS_LOG_ALERT, "Failed to change uid:gid"); return 1; diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index cb5a1bea224..5c1850e9c7f 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -152,7 +152,7 @@ static errno_t k5c_become_user(uid_t uid, gid_t gid, bool is_posix) "Will not drop privileges for a non-POSIX user\n"); return EOK; } - return become_user(uid, gid); + return become_user(uid, gid, true); } static krb5_error_code set_lifetime_options(struct cli_opts *cli_opts, diff --git a/src/tests/cwrap/test_become_user.c b/src/tests/cwrap/test_become_user.c index e63cde9d728..1ffc95917af 100644 --- a/src/tests/cwrap/test_become_user.c +++ b/src/tests/cwrap/test_become_user.c @@ -43,7 +43,7 @@ void test_become_user(void **state) pid = fork(); if (pid == 0) { /* Change the UID in a child */ - ret = become_user(sssd->pw_uid, sssd->pw_gid); + ret = become_user(sssd->pw_uid, sssd->pw_gid, false); assert_int_equal(ret, EOK); /* Make sure we have the requested UID and GID now and there @@ -55,7 +55,7 @@ void test_become_user(void **state) assert_int_equal(getgid(), sssd->pw_gid); /* Another become_user is a no-op */ - ret = become_user(sssd->pw_uid, sssd->pw_gid); + ret = become_user(sssd->pw_uid, sssd->pw_gid, false); assert_int_equal(ret, EOK); assert_int_equal(getgroups(0, NULL), 0); diff --git a/src/util/become_user.c b/src/util/become_user.c index c3f726d1894..d2bd7cfd12c 100644 --- a/src/util/become_user.c +++ b/src/util/become_user.c @@ -25,10 +25,10 @@ #include "util/util.h" #include -errno_t become_user(uid_t uid, gid_t gid) +errno_t become_user(uid_t uid, gid_t gid, bool keep_set_uid) { uid_t cuid; - int ret; + int ret = EOK; DEBUG(SSSDBG_FUNC_DATA, "Trying to become user [%"SPRIuid"][%"SPRIgid"].\n", uid, gid); @@ -37,7 +37,7 @@ errno_t become_user(uid_t uid, gid_t gid) cuid = geteuid(); if (uid == cuid) { DEBUG(SSSDBG_FUNC_DATA, "Already user [%"SPRIuid"].\n", uid); - return EOK; + goto done; } /* drop supplementary groups first */ @@ -46,7 +46,7 @@ errno_t become_user(uid_t uid, gid_t gid) ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setgroups failed [%d][%s].\n", ret, strerror(ret)); - return ret; + goto done; } /* change GID so that root cannot be regained (changes saved GID too) */ @@ -55,20 +55,23 @@ errno_t become_user(uid_t uid, gid_t gid) ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresgid failed [%d][%s].\n", ret, strerror(ret)); - return ret; + goto done; } /* change UID so that root cannot be regained (changes saved UID too) */ /* this call also takes care of dropping CAP_SETUID, so this is a PNR */ - ret = setresuid(uid, uid, uid); + ret = setresuid(uid, uid, (keep_set_uid ? -1 : uid)); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresuid failed [%d][%s].\n", ret, strerror(ret)); - return ret; + goto done; } - return EOK; +done: + sss_drop_all_caps(); + + return ret; } struct sss_creds { diff --git a/src/util/util.h b/src/util/util.h index aad112b5cca..e3c973d77c7 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -744,7 +744,7 @@ errno_t mod_defaults_list(TALLOC_CTX *mem_ctx, const char **defaults_list, char **mod_list, char ***_list); /* from become_user.c */ -errno_t become_user(uid_t uid, gid_t gid); +errno_t become_user(uid_t uid, gid_t gid, bool keep_set_uid); struct sss_creds; errno_t switch_creds(TALLOC_CTX *mem_ctx, uid_t uid, gid_t gid,