version 1.1.1.2, 2012/05/29 12:26:49
|
version 1.1.1.5, 2014/06/15 16:12:55
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 2009-2010 Todd C. Miller <Todd.Miller@courtesan.com> | * Copyright (c) 2009-2013 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 2008 Dan Walsh <dwalsh@redhat.com> |
* Copyright (c) 2008 Dan Walsh <dwalsh@redhat.com> |
* |
* |
* Borrowed heavily from newrole source code |
* Borrowed heavily from newrole source code |
Line 74 audit_role_change(const security_context_t old_context
|
Line 74 audit_role_change(const security_context_t old_context
|
/* Kernel may not have audit support. */ |
/* Kernel may not have audit support. */ |
if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT |
if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT |
) |
) |
error(1, _("unable to open audit system")); | fatal(U_("unable to open audit system")); |
} else { |
} else { |
/* audit role change using the same format as newrole(1) */ |
/* audit role change using the same format as newrole(1) */ |
easprintf(&message, "newrole: old-context=%s new-context=%s", |
easprintf(&message, "newrole: old-context=%s new-context=%s", |
Line 82 audit_role_change(const security_context_t old_context
|
Line 82 audit_role_change(const security_context_t old_context
|
rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE, |
rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE, |
message, NULL, NULL, ttyn, 1); |
message, NULL, NULL, ttyn, 1); |
if (rc <= 0) |
if (rc <= 0) |
warning(_("unable to send audit message")); | warning(U_("unable to send audit message")); |
efree(message); |
efree(message); |
close(au_fd); |
close(au_fd); |
} |
} |
Line 110 selinux_restore_tty(void)
|
Line 110 selinux_restore_tty(void)
|
|
|
/* Verify that the tty still has the context set by sudo. */ |
/* Verify that the tty still has the context set by sudo. */ |
if ((retval = fgetfilecon(se_state.ttyfd, &chk_tty_context)) < 0) { |
if ((retval = fgetfilecon(se_state.ttyfd, &chk_tty_context)) < 0) { |
warning(_("unable to fgetfilecon %s"), se_state.ttyn); | warning(U_("unable to fgetfilecon %s"), se_state.ttyn); |
goto skip_relabel; |
goto skip_relabel; |
} |
} |
|
|
if ((retval = strcmp(chk_tty_context, se_state.new_tty_context))) { |
if ((retval = strcmp(chk_tty_context, se_state.new_tty_context))) { |
warningx(_("%s changed labels"), se_state.ttyn); | warningx(U_("%s changed labels"), se_state.ttyn); |
goto skip_relabel; |
goto skip_relabel; |
} |
} |
|
|
if ((retval = fsetfilecon(se_state.ttyfd, se_state.tty_context)) < 0) |
if ((retval = fsetfilecon(se_state.ttyfd, se_state.tty_context)) < 0) |
warning(_("unable to restore context for %s"), se_state.ttyn); | warning(U_("unable to restore context for %s"), se_state.ttyn); |
|
|
skip_relabel: |
skip_relabel: |
if (se_state.ttyfd != -1) { |
if (se_state.ttyfd != -1) { |
Line 160 relabel_tty(const char *ttyn, int ptyfd)
|
Line 160 relabel_tty(const char *ttyn, int ptyfd)
|
if (ptyfd == -1) { |
if (ptyfd == -1) { |
se_state.ttyfd = open(ttyn, O_RDWR|O_NONBLOCK); |
se_state.ttyfd = open(ttyn, O_RDWR|O_NONBLOCK); |
if (se_state.ttyfd == -1) { |
if (se_state.ttyfd == -1) { |
warning(_("unable to open %s, not relabeling tty"), ttyn); | warning(U_("unable to open %s, not relabeling tty"), ttyn); |
if (se_state.enforcing) |
if (se_state.enforcing) |
goto bad; |
goto bad; |
} |
} |
Line 169 relabel_tty(const char *ttyn, int ptyfd)
|
Line 169 relabel_tty(const char *ttyn, int ptyfd)
|
} |
} |
|
|
if (fgetfilecon(se_state.ttyfd, &tty_con) < 0) { |
if (fgetfilecon(se_state.ttyfd, &tty_con) < 0) { |
warning(_("unable to get current tty context, not relabeling tty")); | warning(U_("unable to get current tty context, not relabeling tty")); |
if (se_state.enforcing) |
if (se_state.enforcing) |
goto bad; |
goto bad; |
} |
} |
|
|
if (tty_con && (security_compute_relabel(se_state.new_context, tty_con, |
if (tty_con && (security_compute_relabel(se_state.new_context, tty_con, |
SECCLASS_CHR_FILE, &new_tty_con) < 0)) { |
SECCLASS_CHR_FILE, &new_tty_con) < 0)) { |
warning(_("unable to get new tty context, not relabeling tty")); | warning(U_("unable to get new tty context, not relabeling tty")); |
if (se_state.enforcing) |
if (se_state.enforcing) |
goto bad; |
goto bad; |
} |
} |
|
|
if (new_tty_con != NULL) { |
if (new_tty_con != NULL) { |
if (fsetfilecon(se_state.ttyfd, new_tty_con) < 0) { |
if (fsetfilecon(se_state.ttyfd, new_tty_con) < 0) { |
warning(_("unable to set new tty context")); | warning(U_("unable to set new tty context")); |
if (se_state.enforcing) |
if (se_state.enforcing) |
goto bad; |
goto bad; |
} |
} |
Line 193 relabel_tty(const char *ttyn, int ptyfd)
|
Line 193 relabel_tty(const char *ttyn, int ptyfd)
|
/* Reopen pty that was relabeled, std{in,out,err} are reset later. */ |
/* Reopen pty that was relabeled, std{in,out,err} are reset later. */ |
se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY, 0); |
se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY, 0); |
if (se_state.ttyfd == -1) { |
if (se_state.ttyfd == -1) { |
warning(_("unable to open %s"), ttyn); | warning(U_("unable to open %s"), ttyn); |
if (se_state.enforcing) |
if (se_state.enforcing) |
goto bad; |
goto bad; |
} |
} |
Line 206 relabel_tty(const char *ttyn, int ptyfd)
|
Line 206 relabel_tty(const char *ttyn, int ptyfd)
|
close(se_state.ttyfd); |
close(se_state.ttyfd); |
se_state.ttyfd = open(ttyn, O_RDWR|O_NONBLOCK); |
se_state.ttyfd = open(ttyn, O_RDWR|O_NONBLOCK); |
if (se_state.ttyfd == -1) { |
if (se_state.ttyfd == -1) { |
warning(_("unable to open %s"), ttyn); | warning(U_("unable to open %s"), ttyn); |
goto bad; |
goto bad; |
} |
} |
(void)fcntl(se_state.ttyfd, F_SETFL, |
(void)fcntl(se_state.ttyfd, F_SETFL, |
Line 249 get_exec_context(security_context_t old_context, const
|
Line 249 get_exec_context(security_context_t old_context, const
|
|
|
/* We must have a role, the type is optional (we can use the default). */ |
/* We must have a role, the type is optional (we can use the default). */ |
if (!role) { |
if (!role) { |
warningx(_("you must specify a role for type %s"), type); | warningx(U_("you must specify a role for type %s"), type); |
errno = EINVAL; |
errno = EINVAL; |
goto bad; |
goto bad; |
} |
} |
if (!type) { |
if (!type) { |
if (get_default_type(role, &typebuf)) { |
if (get_default_type(role, &typebuf)) { |
warningx(_("unable to get default type for role %s"), role); | warningx(U_("unable to get default type for role %s"), role); |
errno = EINVAL; |
errno = EINVAL; |
goto bad; |
goto bad; |
} |
} |
Line 273 get_exec_context(security_context_t old_context, const
|
Line 273 get_exec_context(security_context_t old_context, const
|
* type we will be running the command as. |
* type we will be running the command as. |
*/ |
*/ |
if (context_role_set(context, role)) { |
if (context_role_set(context, role)) { |
warning(_("failed to set new role %s"), role); | warning(U_("failed to set new role %s"), role); |
goto bad; |
goto bad; |
} |
} |
if (context_type_set(context, type)) { |
if (context_type_set(context, type)) { |
warning(_("failed to set new type %s"), type); | warning(U_("failed to set new type %s"), type); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 286 get_exec_context(security_context_t old_context, const
|
Line 286 get_exec_context(security_context_t old_context, const
|
*/ |
*/ |
new_context = estrdup(context_str(context)); |
new_context = estrdup(context_str(context)); |
if (security_check_context(new_context) < 0) { |
if (security_check_context(new_context) < 0) { |
warningx(_("%s is not a valid context"), new_context); | warningx(U_("%s is not a valid context"), new_context); |
errno = EINVAL; |
errno = EINVAL; |
goto bad; |
goto bad; |
} |
} |
Line 321 selinux_setup(const char *role, const char *type, cons
|
Line 321 selinux_setup(const char *role, const char *type, cons
|
|
|
/* Store the caller's SID in old_context. */ |
/* Store the caller's SID in old_context. */ |
if (getprevcon(&se_state.old_context)) { |
if (getprevcon(&se_state.old_context)) { |
warning(_("failed to get old_context")); | warning(U_("failed to get old_context")); |
goto done; |
goto done; |
} |
} |
|
|
se_state.enforcing = security_getenforce(); |
se_state.enforcing = security_getenforce(); |
if (se_state.enforcing < 0) { |
if (se_state.enforcing < 0) { |
warning(_("unable to determine enforcing mode.")); | warning(U_("unable to determine enforcing mode.")); |
goto done; |
goto done; |
} |
} |
|
|
Line 339 selinux_setup(const char *role, const char *type, cons
|
Line 339 selinux_setup(const char *role, const char *type, cons
|
goto done; |
goto done; |
|
|
if (relabel_tty(ttyn, ptyfd) < 0) { |
if (relabel_tty(ttyn, ptyfd) < 0) { |
warning(_("unable to setup tty context for %s"), se_state.new_context); | warning(U_("unable to set tty context to %s"), se_state.new_context); |
goto done; |
goto done; |
} |
} |
|
|
Line 366 selinux_execve(const char *path, char *const argv[], c
|
Line 366 selinux_execve(const char *path, char *const argv[], c
|
int noexec) |
int noexec) |
{ |
{ |
char **nargv; |
char **nargv; |
|
const char *sesh; |
int argc, serrno; |
int argc, serrno; |
debug_decl(selinux_execve, SUDO_DEBUG_SELINUX) |
debug_decl(selinux_execve, SUDO_DEBUG_SELINUX) |
|
|
|
sesh = sudo_conf_sesh_path(); |
|
if (sesh == NULL) { |
|
warningx("internal error: sesh path not set"); |
|
errno = EINVAL; |
|
debug_return; |
|
} |
|
|
if (setexeccon(se_state.new_context)) { |
if (setexeccon(se_state.new_context)) { |
warning(_("unable to set exec context to %s"), se_state.new_context); | warning(U_("unable to set exec context to %s"), se_state.new_context); |
if (se_state.enforcing) |
if (se_state.enforcing) |
debug_return; |
debug_return; |
} |
} |
|
|
#ifdef HAVE_SETKEYCREATECON |
#ifdef HAVE_SETKEYCREATECON |
if (setkeycreatecon(se_state.new_context)) { |
if (setkeycreatecon(se_state.new_context)) { |
warning(_("unable to set key creation context to %s"), se_state.new_context); | warning(U_("unable to set key creation context to %s"), se_state.new_context); |
if (se_state.enforcing) |
if (se_state.enforcing) |
debug_return; |
debug_return; |
} |
} |
Line 399 selinux_execve(const char *path, char *const argv[], c
|
Line 407 selinux_execve(const char *path, char *const argv[], c
|
memcpy(&nargv[2], &argv[1], argc * sizeof(char *)); /* copies NULL */ |
memcpy(&nargv[2], &argv[1], argc * sizeof(char *)); /* copies NULL */ |
|
|
/* sesh will handle noexec for us. */ |
/* sesh will handle noexec for us. */ |
sudo_execve(_PATH_SUDO_SESH, nargv, envp, 0); | sudo_execve(sesh, nargv, envp, false); |
serrno = errno; |
serrno = errno; |
free(nargv); |
free(nargv); |
errno = serrno; |
errno = serrno; |