]> git.armaanb.net Git - opendoas.git/commitdiff
open pam sessions with right user and remove setusercontext shim
authorDuncaen <mail@duncano.de>
Wed, 8 Jun 2016 15:50:28 +0000 (17:50 +0200)
committerDuncaen <mail@duncano.de>
Wed, 8 Jun 2016 16:03:37 +0000 (18:03 +0200)
before this change the sessions were opened as the user running doas.
Now it sets its uid to root and then opens a pam session for the target
user.
The setusercontext shim was removed, because pam handles all this and
its easier to just call setresuid and setresgid instead.

configure
doas.c
doas_pam.c
includes.h
libopenbsd/openbsd.h
libopenbsd/setusercontext.c [deleted file]
pam.d__doas__linux

index cc23132af55b28df8f411a9574ecfacc87dda662..3e346951157a2146299a55f792fa434e52e910e0 100755 (executable)
--- a/configure
+++ b/configure
@@ -280,18 +280,6 @@ int main(void) {
                printf 'LDFLAGS  +=     -lpam\n' >>$CONFIG_MK
        }
 
-#
-# Check for login_cap.h.
-#
-src='
-#include <login_cap.h>
-int main(void) {
-       return 0;
-}'
-check_func "login_cap_h" "$src" || {
-       printf 'OPENBSD  +=     setusercontext.o\n' >>$CONFIG_MK
-}
-
 #
 # Check for execvpe().
 #
diff --git a/doas.c b/doas.c
index 3e158246a2a42c7356a5ce5951364b3dd489318e..f1b2ec058be2bb7d992679c523ca0b08334e094a 100644 (file)
--- a/doas.c
+++ b/doas.c
@@ -439,6 +439,10 @@ main(int argc, char **argv, char **envp)
                errc(1, EPERM, NULL);
        }
 
+       pw = getpwuid(target);
+       if (!pw)
+               errx(1, "no passwd entry for target");
+
 #ifdef HAVE_BSD_AUTH_H
        if (!(rule->options & NOPASS)) {
                if (nflag)
@@ -473,9 +477,8 @@ main(int argc, char **argv, char **envp)
                explicit_bzero(rbuf, sizeof(rbuf));
        }
 #elif HAVE_PAM_APPL_H
-       if (!doas_pam(myname, !nflag, rule->options & NOPASS)) {
-               syslog(LOG_AUTHPRIV | LOG_NOTICE,
-                               "failed auth for %s", myname);
+       if (!doas_pam(pw->pw_name, myname, !nflag, rule->options & NOPASS)) {
+               syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
                errc(1, EPERM, NULL);
        }
 #else
@@ -486,14 +489,19 @@ main(int argc, char **argv, char **envp)
        if (pledge("stdio rpath getpw exec id", NULL) == -1)
                err(1, "pledge");
 
-       pw = getpwuid(target);
-       if (!pw)
-               errx(1, "no passwd entry for target");
-
+#ifdef HAVE_BSD_AUTH_H
        if (setusercontext(NULL, pw, target, LOGIN_SETGROUP |
            LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
            LOGIN_SETUSER) != 0)
                errx(1, "failed to set user context for target");
+#else
+       if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0)
+               errx(1, "setgid");
+       if (initgroups(pw->pw_name, pw->pw_gid) != 0)
+               errx(1, "initgroups");
+       if (setresuid(target, target, target) != 0)
+               errx(1, "setuid");
+#endif
 
        if (pledge("stdio rpath exec", NULL) == -1)
                err(1, "pledge");
index f8b6e63f402595bf5bcd87db0138a45e17330f4f..4f2731d5e133d12b664a63709c470b17d025a9be 100644 (file)
@@ -39,6 +39,12 @@ static pam_handle_t *pamh = NULL;
 static sig_atomic_t volatile caught_signal = 0;
 static char doas_prompt[128];
 
+static void
+catchsig(int sig)
+{
+       caught_signal = sig;
+}
+
 static char *
 prompt(const char *msg, int echo_on, int *pam)
 {
@@ -48,7 +54,7 @@ prompt(const char *msg, int echo_on, int *pam)
 
        /* overwrite default prompt if it matches "Password:[ ]" */
        if (strncmp(msg,"Password:", 9) == 0 &&
-                       (msg[9] == '\0' || (msg[9] == ' ' && msg[10] == '\0')))
+           (msg[9] == '\0' || (msg[9] == ' ' && msg[10] == '\0')))
                prompt = doas_prompt;
        else
                prompt = msg;
@@ -86,7 +92,7 @@ doas_pam_conv(int nmsgs, const struct pam_message **msgs,
                case PAM_ERROR_MSG:
                case PAM_TEXT_INFO:
                        if (fprintf(style == PAM_ERROR_MSG ? stderr : stdout,
-                                       "%s\n", msgs[i]->msg) < 0)
+                           "%s\n", msgs[i]->msg) < 0)
                                goto fail;
                        break;
 
@@ -117,14 +123,8 @@ fail:
        return PAM_CONV_ERR;
 }
 
-static void
-catchsig(int sig)
-{
-       caught_signal = sig;
-}
-
 int
-doas_pam(char *name, int interactive, int nopass)
+doas_pam(const char *user, const char* ruser, int interactive, int nopass)
 {
        static const struct pam_conv conv = {
                .conv = doas_pam_conv,
@@ -134,23 +134,22 @@ doas_pam(char *name, int interactive, int nopass)
        pid_t child;
        int ret;
 
-       if (!name)
+       if (!user || !ruser)
                return 0;
 
-       ret = pam_start(PAM_SERVICE_NAME, name, &conv, &pamh);
-       if (ret != PAM_SUCCESS)
-               errx(1, "pam_start(\"%s\", \"%s\", ?, ?): failed\n",
-                               PAM_SERVICE_NAME, name);
+       /* pam needs the real root */
+       if(setuid(0))
+               errx(1, "setuid");
 
-       ret = pam_set_item(pamh, PAM_USER, name);
+       ret = pam_start(PAM_SERVICE_NAME, ruser, &conv, &pamh);
        if (ret != PAM_SUCCESS)
-               errx(1, "pam_set_item(?, PAM_USER, \"%s\"): %s\n",
-                               name, pam_strerror(pamh, ret));
+               errx(1, "pam_start(\"%s\", \"%s\", ?, ?): failed\n",
+                   PAM_SERVICE_NAME, ruser);
 
-       ret = pam_set_item(pamh, PAM_RUSER, name);
+       ret = pam_set_item(pamh, PAM_RUSER, ruser);
        if (ret != PAM_SUCCESS)
-               errx(1, "pam_set_item(?, PAM_RUSER, \"%s\"): %s\n",
-                               name, pam_strerror(pamh, ret));
+               warn("pam_set_item(?, PAM_RUSER, \"%s\"): %s\n",
+                   pam_strerror(pamh, ret), ruser);
 
        if (isatty(0) && (ttydev = ttyname(0)) != NULL) {
                if (strncmp(ttydev, "/dev/", 5))
@@ -160,8 +159,8 @@ doas_pam(char *name, int interactive, int nopass)
 
                ret = pam_set_item(pamh, PAM_TTY, tty);
                if (ret != PAM_SUCCESS)
-                       errx(1, "pam_set_item(?, PAM_TTY, \"%s\"): %s\n",
-                                       tty, pam_strerror(pamh, ret));
+                       warn("pam_set_item(?, PAM_TTY, \"%s\"): %s\n",
+                           tty, pam_strerror(pamh, ret));
        }
 
        if (!nopass) {
@@ -173,14 +172,12 @@ doas_pam(char *name, int interactive, int nopass)
                if (gethostname(host, sizeof(host)))
                        snprintf(host, sizeof(host), "?");
                snprintf(doas_prompt, sizeof(doas_prompt),
-                               "\rdoas (%.32s@%.32s) password: ", name, host);
+                   "\rdoas (%.32s@%.32s) password: ", ruser, host);
 
                /* authenticate */
                ret = pam_authenticate(pamh, 0);
                if (ret != PAM_SUCCESS) {
-                       ret = pam_end(pamh, ret);
-                       if (ret != PAM_SUCCESS)
-                               errx(1, "pam_end(): %s\n", pam_strerror(pamh, ret));
+                       pam_end(pamh, ret);
                        return 0;
                }
        }
@@ -193,10 +190,14 @@ doas_pam(char *name, int interactive, int nopass)
        if (ret != PAM_SUCCESS)
                return 0;
 
+       ret = pam_set_item(pamh, PAM_USER, user);
+       if (ret != PAM_SUCCESS)
+               warn("pam_set_item(?, PAM_USER, \"%s\"): %s\n", user,
+                   pam_strerror(pamh, ret));
+
        ret = pam_setcred(pamh, PAM_ESTABLISH_CRED);
        if (ret != PAM_SUCCESS)
-               errx(1, "pam_setcred(?, PAM_ESTABLISH_CRED): %s\n",
-                               pam_strerror(pamh, ret));
+               warn("pam_setcred(?, PAM_ESTABLISH_CRED): %s\n", pam_strerror(pamh, ret));
 
        /* open session */
        ret = pam_open_session(pamh, 0);
@@ -233,10 +234,10 @@ doas_pam(char *name, int interactive, int nopass)
 
        /* unblock SIGTERM and SIGALRM to catch them */
        sigemptyset(&sigs);
-       if(sigaddset(&sigs, SIGTERM) ||
-                       sigaddset(&sigs, SIGALRM) ||
-                       sigaction(SIGTERM, &act, &oldact) ||
-                       sigprocmask(SIG_UNBLOCK, &sigs, NULL)) {
+       if (sigaddset(&sigs, SIGTERM) ||
+           sigaddset(&sigs, SIGALRM) ||
+           sigaction(SIGTERM, &act, &oldact) ||
+           sigprocmask(SIG_UNBLOCK, &sigs, NULL)) {
                warn("failed to set signal handler");
                caught_signal = 1;
        }
@@ -246,7 +247,7 @@ doas_pam(char *name, int interactive, int nopass)
                if (waitpid(child, &status, 0) != -1) {
                        if (WIFSIGNALED(status)) {
                                fprintf(stderr, "%s%s\n", strsignal(WTERMSIG(status)),
-                                               WCOREDUMP(status) ? " (core dumped)" : "");
+                                   WCOREDUMP(status) ? " (core dumped)" : "");
                                status = WTERMSIG(status) + 128;
                        } else {
                                status = WEXITSTATUS(status);
index e9ebf6364da8d6365097b9511862bcc8ec76d62a..776a94030a9a51bea613512e1c04d77b8e3dcc97 100644 (file)
@@ -20,7 +20,7 @@
 #include "openbsd.h"
 
 #ifdef HAVE_PAM_APPL_H
-int doas_pam(char *name, int interactive, int nopass);
+int doas_pam(const char *user, const char *ruser, int interactive, int nopass);
 #endif
 
 #endif /* INCLUDES_H */
index 87be1c056dc1f590938cb77cdf41eaab06a68dfc..05868444a8c9d1847e7a353f97657b854293f941 100644 (file)
@@ -8,23 +8,6 @@
 
 /* API definitions lifted from OpenBSD src/include */
 
-/* login_cap.h */
-#ifndef HAVE_LOGIN_CAP_H
-#define        LOGIN_SETGROUP          0x0001  /* Set group */
-#define        LOGIN_SETLOGIN          0x0002  /* Set login */
-#define        LOGIN_SETPATH           0x0004  /* Set path */
-#define        LOGIN_SETPRIORITY       0x0008  /* Set priority */
-#define        LOGIN_SETRESOURCES      0x0010  /* Set resource limits */
-#define        LOGIN_SETUMASK          0x0020  /* Set umask */
-#define        LOGIN_SETUSER           0x0040  /* Set user */
-#define        LOGIN_SETENV            0x0080  /* Set environment */
-#define        LOGIN_SETALL            0x00ff  /* Set all. */
-
-typedef struct login_cap login_cap_t;
-struct passwd;
-int setusercontext(login_cap_t *, struct passwd *, uid_t, unsigned int);
-#endif /* !HAVE_LOGIN_CAP_H */
-
 /* pwd.h */
 #define _PW_NAME_LEN 63
 
diff --git a/libopenbsd/setusercontext.c b/libopenbsd/setusercontext.c
deleted file mode 100644 (file)
index 6b05dd5..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2015 Nathan Holstein <nathan.holstein@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <pwd.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <grp.h>
-
-#include "includes.h"
-
-int
-setusercontext(login_cap_t *lc, struct passwd *pw, uid_t uid, unsigned int flags)
-{
-       int ret;
-
-       if (lc != NULL || pw == NULL ||
-                       (flags & ~(LOGIN_SETGROUP | LOGIN_SETPRIORITY |
-                                  LOGIN_SETRESOURCES | LOGIN_SETUMASK |
-                                  LOGIN_SETUSER)) != 0) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       if (flags & LOGIN_SETGROUP) {
-               if ((ret = setgid(pw->pw_gid)) != 0)
-                       return ret;
-               if ((ret = initgroups(pw->pw_name, pw->pw_gid)) != 0)
-                       return ret;
-       }
-
-       if (flags & LOGIN_SETPRIORITY) {
-               if ((ret = setpriority(PRIO_PROCESS, getpid(), 0)) != 0)
-                       return ret;
-               if ((ret = setpriority(PRIO_USER, uid, 0)) != 0)
-                       return ret;
-       }
-
-       if (flags & LOGIN_SETRESOURCES) {
-       }
-
-       if (flags & LOGIN_SETUMASK)
-               umask(S_IWGRP | S_IWOTH);
-
-       if (flags & LOGIN_SETUSER)
-               return setuid(uid);
-
-       return 0;
-}
-
index 9781fb291bae16d01e93f979713222309fba81e8..813a0e4ec9998170d0bccb73b5562aeac65784c1 100644 (file)
@@ -1,10 +1,9 @@
 #%PAM-1.0
-auth            sufficient      pam_timestamp.so timestamp_timeout=300 verbose debug
-auth            sufficient      pam_rootok.so
+auth            sufficient      pam_timestamp.so timestamp_timeout=300
 auth            required        pam_unix.so
 account         required        pam_unix.so
 session         optional        pam_xauth.so
 session         optional        pam_umask.so     usergroups umask=022
-session         optional        pam_timestamp.so timestamp_timeout=300 debug
+session         optional        pam_timestamp.so timestamp_timeout=300
 session         required        pam_env.so
 session         required        pam_unix.so