aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncaen <mail@duncano.de>2016-06-26 23:10:37 +0200
committerDuncaen <mail@duncano.de>2016-06-26 23:11:07 +0200
commite88a009620a604d57d85bd53b971cfa77e44315e (patch)
treee36c04e54d4d4cd281b772d3db34df1bb381d383
parent788dd4b64a25b2705f962c37962363c22d9c49f9 (diff)
downloadopendoas-e88a009620a604d57d85bd53b971cfa77e44315e.tar.gz
add --without-pam configure option to allow passwd/shadow auth
-rw-r--r--bsd.prog.mk6
-rwxr-xr-xconfigure19
-rw-r--r--doas.c52
3 files changed, 67 insertions, 10 deletions
diff --git a/bsd.prog.mk b/bsd.prog.mk
index f5b3efe..03dcfb8 100644
--- a/bsd.prog.mk
+++ b/bsd.prog.mk
@@ -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
diff --git a/configure b/configure
index 1bb827f..9387d30 100755
--- 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,13 +284,26 @@ 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().
#
src='
diff --git a/doas.c b/doas.c
index e74881b..33be571 100644
--- 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)