Imported Upstream version 1.8.4p4
[debian/sudo] / plugins / sudoers / auth / bsdauth.c
index 60616e2bb106e46a820dd55d1be1944c7ec998b9..5e90898aa8a4836d22435753ca0b6e32e06b0475 100644 (file)
 #include "sudoers.h"
 #include "sudo_auth.h"
 
-extern char *login_style;              /* from sudo.c */
+# ifndef LOGIN_DEFROOTCLASS
+#  define LOGIN_DEFROOTCLASS   "daemon"
+# endif
+
+extern char *login_style;              /* from sudoers.c */
+
+struct bsdauth_state {
+    auth_session_t *as;
+    login_cap_t *lc;
+};
 
 int
 bsdauth_init(struct passwd *pw, sudo_auth *auth)
 {
-    static auth_session_t *as;
-    extern login_cap_t *lc;                    /* from sudo.c */
+    static struct bsdauth_state state;
+    debug_decl(bsdauth_init, SUDO_DEBUG_AUTH)
+
+    /* Get login class based on auth user, which may not be invoking user. */
+    if (pw->pw_class && *pw->pw_class)
+       state.lc = login_getclass(pw->pw_class);
+    else
+       state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
+    if (state.lc == NULL) {
+       log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
+           _("unable to get login class for user %s"), pw->pw_name);
+       debug_return_int(AUTH_FATAL);
+    }
 
-    if ((as = auth_open()) == NULL) {
+    if ((state.as = auth_open()) == NULL) {
        log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
            _("unable to begin bsd authentication"));
-       return AUTH_FATAL;
+       login_close(state.lc);
+       debug_return_int(AUTH_FATAL);
     }
 
     /* XXX - maybe sanity check the auth style earlier? */
-    login_style = login_getstyle(lc, login_style, "auth-sudo");
+    login_style = login_getstyle(state.lc, login_style, "auth-sudo");
     if (login_style == NULL) {
        log_error(NO_EXIT|NO_MAIL, _("invalid authentication type"));
-       auth_close(as);
-       return AUTH_FATAL;
+       auth_close(state.as);
+       login_close(state.lc);
+       debug_return_int(AUTH_FATAL);
     }
 
-     if (auth_setitem(as, AUTHV_STYLE, login_style) < 0 ||
-       auth_setitem(as, AUTHV_NAME, pw->pw_name) < 0 ||
-       auth_setitem(as, AUTHV_CLASS, login_class) < 0) {
+     if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
+       auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
+       auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
        log_error(NO_EXIT|NO_MAIL, _("unable to setup authentication"));
-       auth_close(as);
-       return AUTH_FATAL;
+       auth_close(state.as);
+       login_close(state.lc);
+       debug_return_int(AUTH_FATAL);
     }
 
-    auth->data = (void *) as;
-    return AUTH_SUCCESS;
+    auth->data = (void *) &state;
+    debug_return_int(AUTH_SUCCESS);
 }
 
 int
@@ -93,7 +116,8 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
     size_t len;
     int authok = 0;
     sigaction_t sa, osa;
-    auth_session_t *as = (auth_session_t *) auth->data;
+    auth_session_t *as = ((struct bsdauth_state *) auth->data)->as;
+    debug_decl(bsdauth_verify, SUDO_DEBUG_AUTH)
 
     /* save old signal handler */
     sigemptyset(&sa.sa_mask);
@@ -140,22 +164,26 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
     (void) sigaction(SIGCHLD, &osa, NULL);
 
     if (authok)
-       return AUTH_SUCCESS;
+       debug_return_int(AUTH_SUCCESS);
 
     if (!pass)
-       return AUTH_INTR;
+       debug_return_int(AUTH_INTR);
 
     if ((s = auth_getvalue(as, "errormsg")) != NULL)
        log_error(NO_EXIT|NO_MAIL, "%s", s);
-    return AUTH_FAILURE;
+    debug_return_int(AUTH_FAILURE);
 }
 
 int
 bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
 {
-    auth_session_t *as = (auth_session_t *) auth->data;
+    struct bsdauth_state *state = auth->data;
+    debug_decl(bsdauth_cleanup, SUDO_DEBUG_AUTH)
 
-    auth_close(as);
+    if (state != NULL) {
+       auth_close(state->as);
+       login_close(state->lc);
+    }
 
-    return AUTH_SUCCESS;
+    debug_return_int(AUTH_SUCCESS);
 }