-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SELINUX_CHILD: only cap_set*id is required
:packaging:A set of capabilities required by privileged binaries was further reduced to: ``` krb5_child cap_dac_read_search,cap_setgid,cap_setuid=p ldap_child cap_dac_read_search=p selinux_child cap_setgid,cap_setuid=ep sssd_pam cap_dac_read_search=p ```
- Loading branch information
1 parent
852b0fd
commit 5c407f3
Showing
3 changed files
with
47 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,9 +22,10 @@ | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "config.h" | ||
|
||
#include <sys/types.h> | ||
#include <unistd.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <popt.h> | ||
#include <sys/prctl.h> | ||
|
@@ -236,6 +237,8 @@ int main(int argc, const char *argv[]) | |
const char *username; | ||
const char *opt_logger = NULL; | ||
long chain_id; | ||
uid_t ruid, euid, suid; | ||
gid_t rgid, egid, sgid; | ||
|
||
struct poptOption long_options[] = { | ||
POPT_AUTOHELP | ||
|
@@ -291,10 +294,7 @@ int main(int argc, const char *argv[]) | |
DEBUG_INIT(debug_level, opt_logger); | ||
sss_set_debug_backtrace_enable((backtrace == 0) ? false : true); | ||
|
||
DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n"); | ||
DEBUG(SSSDBG_TRACE_INTERNAL, | ||
"Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n", | ||
geteuid(), getegid()); | ||
sss_log_process_caps("Starting"); | ||
|
||
/* The functions semanage_genhomedircon and getseuserbyname use gepwnam_r | ||
* and they might fail to return values if they are not in memory cache. | ||
|
@@ -312,31 +312,6 @@ int main(int argc, const char *argv[]) | |
"fail.\n"); | ||
} | ||
|
||
/* libsemanage calls access(2) which works with real IDs, not effective. | ||
* We need to switch also the real ID to 0. | ||
*/ | ||
if (getuid() != 0) { | ||
ret = setuid(0); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setuid failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
|
||
if (getgid() != 0) { | ||
ret = setgid(0); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setgid failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
|
||
DEBUG(SSSDBG_TRACE_INTERNAL, | ||
"Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n", | ||
getuid(), getgid()); | ||
|
||
main_ctx = talloc_new(NULL); | ||
if (main_ctx == NULL) { | ||
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); | ||
|
@@ -376,8 +351,6 @@ int main(int argc, const char *argv[]) | |
goto fail; | ||
} | ||
|
||
DEBUG(SSSDBG_TRACE_FUNC, "performing selinux operations\n"); | ||
|
||
/* When using domain_resolution_order the username will always be | ||
* fully-qualified, what has been causing some SELinux issues as mappings | ||
* for user 'admin' are not applied for '[email protected]'. | ||
|
@@ -396,6 +369,32 @@ int main(int argc, const char *argv[]) | |
username = passwd->pw_name; | ||
} | ||
|
||
/* libsemanage calls access(2) which works with real IDs, not effective. | ||
* We need to switch also the real ID to 0. | ||
*/ | ||
if (getuid() != 0) { | ||
sss_set_cap_effective(CAP_SETUID, true); | ||
ret = setresuid(0, 0, -1); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setuid() failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
if (getgid() != 0) { | ||
sss_set_cap_effective(CAP_SETGID, true); | ||
setgroups(0, NULL); | ||
ret = setresgid(0, 0, -1); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setgid() failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
sss_drop_all_caps(); | ||
|
||
sss_log_process_caps("Performing selinux operations"); | ||
|
||
needs_update = seuser_needs_update(username, ibuf->seuser, | ||
ibuf->mls_range); | ||
if (needs_update == true) { | ||
|
@@ -406,6 +405,15 @@ int main(int argc, const char *argv[]) | |
} | ||
} | ||
|
||
if (getresuid(&ruid, &euid, &suid) == 0) { | ||
setresuid(suid, suid, suid); | ||
} | ||
if (getresgid(&rgid, &egid, &sgid) == 0) { | ||
setresgid(sgid, sgid, sgid); | ||
} | ||
|
||
sss_log_process_caps("Sending response"); | ||
|
||
ret = prepare_response(main_ctx, ret, &resp); | ||
if (ret != EOK) { | ||
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to prepare response buffer.\n"); | ||
|