]> git.armaanb.net Git - opendoas.git/blobdiff - doas.c
bump to version v0.3.2
[opendoas.git] / doas.c
diff --git a/doas.c b/doas.c
index ee1b341f7ba8b9eb13426a5dd16a70568a642805..b5f8049e3baff80ea544c20437548d6e4fa16320 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,18 +378,60 @@ main(int argc, char **argv)
                explicit_bzero(rbuf, sizeof(rbuf));
        }
 #elif HAVE_PAM_APPL_H
-       if (!doas_pam(pw->pw_name, myname, !nflag, rule->options & NOPASS)) {
+       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 |
@@ -398,11 +439,11 @@ main(int argc, char **argv)
                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");
+               errx(1, "setresgid");
        if (initgroups(pw->pw_name, pw->pw_gid) != 0)
                errx(1, "initgroups");
        if (setresuid(target, target, target) != 0)
-               errx(1, "setuid");
+               errx(1, "setresuid");
 #endif
 
        if (pledge("stdio rpath exec", NULL) == -1)