]> git.armaanb.net Git - opendoas.git/commitdiff
add --without-pam configure option to allow passwd/shadow auth
authorDuncaen <mail@duncano.de>
Sun, 26 Jun 2016 21:10:37 +0000 (23:10 +0200)
committerDuncaen <mail@duncano.de>
Sun, 26 Jun 2016 21:11:07 +0000 (23:11 +0200)
bsd.prog.mk
configure
doas.c

index f5b3efe9fd5fb11e9dbc012dfcec42d353f41494..03dcfb8142285e0135c98347e2edf95669e64484 100644 (file)
@@ -18,14 +18,14 @@ ${PROG}: ${OBJS} libopenbsd.a
 
 install: ${PROG} ${PAM_DOAS} ${MAN}
        mkdir -p -m 0755 ${DESTDIR}${BINDIR}
-       mkdir -p -m 0755 ${DESTDIR}${PAMDIR}
+       [ -n "${PAM_DOAS}" ] && mkdir -p -m 0755 ${DESTDIR}${PAMDIR}
        mkdir -p -m 0755 ${DESTDIR}${MANDIR}/man1
        mkdir -p -m 0755 ${DESTDIR}${MANDIR}/man5
        cp -f ${PROG} ${DESTDIR}${BINDIR}
        chown ${BINOWN}:${BINGRP} ${DESTDIR}${BINDIR}/${PROG}
        chmod ${BINMODE} ${DESTDIR}${BINDIR}/${PROG}
-       cp ${PAM_DOAS} ${DESTDIR}${PAMDIR}/doas
-       chmod 0644 ${DESTDIR}${PAMDIR}/doas
+       [ -n "${PAM_DOAS}" ] && cp ${PAM_DOAS} ${DESTDIR}${PAMDIR}/doas || true
+       [ -n "${PAM_DOAS}" ] && chmod 0644 ${DESTDIR}${PAMDIR}/doas
        cp -f doas.1 ${DESTDIR}${MANDIR}/man1
        cp -f doas.conf.5 ${DESTDIR}${MANDIR}/man5
 
index 1bb827fc8e11cd5f2ef713f5ad152c9ecb10b4d4..9387d300b6618e4b6ea0fb016c92f1f8f106bcc1 100755 (executable)
--- a/configure
+++ b/configure
@@ -45,6 +45,7 @@ for x; do
        --target) TARGET=$var;;
        --enable-debug) DEBUG=yes;;
        --enable-static) BUILD_STATIC=yes;;
+       --without-pam) WITHOUT_PAM=yes;;
        --help|-h) usage;;
        *) die "Error: unknown option $opt";;
        esac
@@ -96,7 +97,8 @@ case "$OS" in
        linux)
                OS_CFLAGS="$OS_CFLAGS -D_DEFAULT_SOURCE -D_GNU_SOURCE -DUID_MAX=60000 -DGID_MAX=60000"
                printf 'CURDIR   :=     .\n' >>$CONFIG_MK
-               printf 'PAM_DOAS  =     pam.d__doas__linux\n' >>$CONFIG_MK
+               [ -z "$WITHOUT_PAM" ] && \
+                       printf 'PAM_DOAS  =     pam.d__doas__linux\n' >>$CONFIG_MK
                ;;
 esac
 
@@ -282,12 +284,25 @@ src='
 int main(void) {
        return 0;
 }'
-[ -z "$have_bsd_auth_h" ] && \
+[ -z "$WITHOUT_PAM" -a -z "$have_bsd_auth_h" ] && \
        check_func "pam_appl_h" "$src" && {
                printf 'SRCS     +=     pam.c\n' >>$CONFIG_MK
                printf 'LDFLAGS  +=     -lpam\n' >>$CONFIG_MK
        }
 
+#
+# Check for shadow.h.
+#
+src='
+#include <shadow.h>
+int main(void) {
+       return 0;
+}'
+[ -z "$WITHOUT_PAM" -a -z "$have_bsd_auth_h" ] || \
+       check_func "shadow_h" "$src" && {
+               printf 'LDFLAGS  +=     -lcrypt\n' >>$CONFIG_MK
+       }
+
 #
 # Check for execvpe().
 #
diff --git a/doas.c b/doas.c
index e74881b7652b6dc114c2ce9874484164bb615d8f..33be571de3bd542fe9eef95303f612380e357a54 100644 (file)
--- a/doas.c
+++ b/doas.c
@@ -28,6 +28,9 @@
 #include <grp.h>
 #include <syslog.h>
 #include <errno.h>
+#if HAVE_SHADOW_H
+#include <shadow.h>
+#endif
 
 #include "includes.h"
 
@@ -341,10 +344,6 @@ main(int argc, char **argv)
                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)
@@ -379,24 +378,67 @@ main(int argc, char **argv)
                explicit_bzero(rbuf, sizeof(rbuf));
        }
 #elif HAVE_PAM_APPL_H
+       pw = getpwuid(target);
+       if (!pw)
+               errx(1, "no passwd entry for target");
+
        if (!pamauth(pw->pw_name, myname, !nflag, rule->options & NOPASS)) {
                syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
                errc(1, EPERM, NULL);
        }
-#else
+#elif HAVE_SHADOW_H
+       const char *pass;
+
        if (!(rule->options & NOPASS)) {
+               if (nflag)
                        errx(1, "Authorization required");
+
+               pass = pw->pw_passwd;
+               if (pass[0] == 'x' && pass[1] == '\0') {
+                       struct spwd *sp;
+                       if (!(sp = getspnam(myname)))
+                               errx(1, "Authorization failed");
+                       pass = sp->sp_pwdp;
+               }
+
+               char *challenge, *response, rbuf[1024], cbuf[128], host[HOST_NAME_MAX + 1];
+               if (gethostname(host, sizeof(host)))
+                       snprintf(host, sizeof(host), "?");
+               snprintf(cbuf, sizeof(cbuf),
+                               "\rdoas (%.32s@%.32s) password: ", myname, host);
+               challenge = cbuf;
+
+               response = readpassphrase(challenge, rbuf, sizeof(rbuf), RPP_REQUIRE_TTY);
+               if (response == NULL && errno == ENOTTY) {
+                       syslog(LOG_AUTHPRIV | LOG_NOTICE,
+                           "tty required for %s", myname);
+                       errx(1, "a tty is required");
+               }
+               if (strcmp(crypt(response, pass), pass) != 0) {
+                       syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname);
+                       errc(1, EPERM, NULL);
+               }
+               explicit_bzero(rbuf, sizeof(rbuf));
+       }
+#else
+       if (!(rule->options & NOPASS))
+               errx(1, "Authorization required");
 #endif /* HAVE_BSD_AUTH_H */
 
        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
+       warn(pw->pw_name);
        if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0)
                errx(1, "setresgid");
        if (initgroups(pw->pw_name, pw->pw_gid) != 0)