Imported Upstream version 1.8.4p4
[debian/sudo] / src / selinux.c
index dc519731a48c91a33437d1cfb8c1ae32cfb5f958..23ffbd0f7e63fc85af396fd0ae0924e8476966e5 100644 (file)
@@ -64,8 +64,9 @@ static int
 audit_role_change(const security_context_t old_context,
     const security_context_t new_context, const char *ttyn)
 {
-    int au_fd, rc;
+    int au_fd, rc = -1;
     char *message;
+    debug_decl(audit_role_change, SUDO_DEBUG_SELINUX)
 
     au_fd = audit_open();
     if (au_fd == -1) {
@@ -73,21 +74,19 @@ audit_role_change(const security_context_t old_context,
         if (errno != EINVAL && errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT
 )
             error(1, _("unable to open audit system"));
-       return -1;
+    } else {
+       /* audit role change using the same format as newrole(1) */
+       easprintf(&message, "newrole: old-context=%s new-context=%s",
+           old_context, new_context);
+       rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
+           message, NULL, NULL, ttyn, 1);
+       if (rc <= 0)
+           warning(_("unable to send audit message"));
+       efree(message);
+       close(au_fd);
     }
 
-    /* audit role change using the same format as newrole(1) */
-    easprintf(&message, "newrole: old-context=%s new-context=%s",
-       old_context, new_context);
-    rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
-       message, NULL, NULL, ttyn, 1);
-    if (rc <= 0)
-       warning(_("unable to send audit message"));
-
-    efree(message);
-    close(au_fd);
-
-    return rc;
+    debug_return_int(rc);
 }
 #endif
 
@@ -103,6 +102,7 @@ selinux_restore_tty(void)
 {
     int retval = 0;
     security_context_t chk_tty_context = NULL;
+    debug_decl(selinux_restore_tty, SUDO_DEBUG_SELINUX)
 
     if (se_state.ttyfd == -1 || se_state.new_tty_context == NULL)
        goto skip_relabel;
@@ -130,7 +130,7 @@ skip_relabel:
        freecon(chk_tty_context);
        chk_tty_context = NULL;
     }
-    return retval;
+    debug_return_int(retval);
 }
 
 /*
@@ -147,12 +147,13 @@ relabel_tty(const char *ttyn, int ptyfd)
     security_context_t tty_con = NULL;
     security_context_t new_tty_con = NULL;
     int fd;
+    debug_decl(relabel_tty, SUDO_DEBUG_SELINUX)
 
     se_state.ttyfd = ptyfd;
 
     /* It is perfectly legal to have no tty. */
     if (ptyfd == -1 && ttyn == NULL)
-       return 0;
+       debug_return_int(0);
 
     /* If sudo is not allocating a pty for the command, open current tty. */
     if (ptyfd == -1) {
@@ -222,7 +223,7 @@ relabel_tty(const char *ttyn, int ptyfd)
     se_state.ttyn = ttyn;
     se_state.tty_context = tty_con;
     se_state.new_tty_context = new_tty_con;
-    return 0;
+    debug_return_int(0);
 
 bad:
     if (se_state.ttyfd != -1 && se_state.ttyfd != ptyfd) {
@@ -230,7 +231,7 @@ bad:
        se_state.ttyfd = -1;
     }
     freecon(tty_con);
-    return -1;
+    debug_return_int(-1);
 }
 
 /*
@@ -243,18 +244,19 @@ get_exec_context(security_context_t old_context, const char *role, const char *t
     security_context_t new_context = NULL;
     context_t context = NULL;
     char *typebuf = NULL;
+    debug_decl(get_exec_context, SUDO_DEBUG_SELINUX)
     
     /* We must have a role, the type is optional (we can use the default). */
     if (!role) {
        warningx(_("you must specify a role for type %s"), type);
        errno = EINVAL;
-       return NULL;
+       goto bad;
     }
     if (!type) {
        if (get_default_type(role, &typebuf)) {
            warningx(_("unable to get default type for role %s"), role);
            errno = EINVAL;
-           return NULL;
+           goto bad;
        }
        type = typebuf;
     }
@@ -293,13 +295,13 @@ get_exec_context(security_context_t old_context, const char *role, const char *t
 #endif
 
     context_free(context);
-    return new_context;
+    debug_return_ptr(new_context);
 
 bad:
-    free(typebuf);
+    efree(typebuf);
     context_free(context);
     freecon(new_context);
-    return NULL;
+    debug_return_ptr(NULL);
 }
 
 /* 
@@ -314,6 +316,7 @@ selinux_setup(const char *role, const char *type, const char *ttyn,
     int ptyfd)
 {
     int rval = -1;
+    debug_decl(selinux_setup, SUDO_DEBUG_SELINUX)
 
     /* Store the caller's SID in old_context. */
     if (getprevcon(&se_state.old_context)) {
@@ -354,40 +357,50 @@ selinux_setup(const char *role, const char *type, const char *ttyn,
     rval = 0;
 
 done:
-    return rval;
+    debug_return_int(rval);
 }
 
 void
-selinux_execve(const char *path, char *argv[], char *envp[])
+selinux_execve(const char *path, char *const argv[], char *const envp[],
+    int noexec)
 {
     char **nargv;
     int argc, serrno;
+    debug_decl(selinux_execve, SUDO_DEBUG_SELINUX)
 
     if (setexeccon(se_state.new_context)) {
        warning(_("unable to set exec context to %s"), se_state.new_context);
        if (se_state.enforcing)
-           return;
+           debug_return;
     }
 
 #ifdef HAVE_SETKEYCREATECON
     if (setkeycreatecon(se_state.new_context)) {
        warning(_("unable to set key creation context to %s"), se_state.new_context);
        if (se_state.enforcing)
-           return;
+           debug_return;
     }
 #endif /* HAVE_SETKEYCREATECON */
 
+    /*
+     * Build new argv with sesh as argv[0].
+     * If argv[0] ends in -noexec, sesh will disable execute
+     * for the command it runs.
+     */
     for (argc = 0; argv[argc] != NULL; argc++)
        continue;
-
-    /* Build new argv with sesh as argv[0]. */
     nargv = emalloc2(argc + 2, sizeof(char *));
-    nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh";
+    if (noexec)
+       nargv[0] = *argv[0] == '-' ? "-sesh-noexec" : "sesh-noexec";
+    else
+       nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh";
     nargv[1] = (char *)path;
     memcpy(&nargv[2], &argv[1], argc * sizeof(char *)); /* copies NULL */
 
-    execve(_PATH_SUDO_SESH, nargv, envp);
+    /* sesh will handle noexec for us. */
+    sudo_execve(_PATH_SUDO_SESH, nargv, envp, 0);
     serrno = errno;
     free(nargv);
     errno = serrno;
+    debug_return;
 }