From: Todd C. Miller Date: Thu, 12 Jan 2012 19:23:42 +0000 (-0500) Subject: Fetch the login class for the user we authenticate specifically X-Git-Tag: SUDO_1_7_9~43 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=07278b4375de0b897c53945af23237d7650df5e0;p=sudo Fetch the login class for the user we authenticate specifically when using BSD authentication. That user may have a different login class than what we will use to run the command. When setting the login class for the command, use the target user's struct passwd, not the invoking user's. --HG-- branch : 1.7 --- diff --git a/auth/bsdauth.c b/auth/bsdauth.c index fd244a7d8..e255afa08 100644 --- a/auth/bsdauth.c +++ b/auth/bsdauth.c @@ -51,39 +51,61 @@ #include "sudo.h" #include "sudo_auth.h" +#ifndef LOGIN_DEFROOTCLASS +# define LOGIN_DEFROOTCLASS "daemon" +#endif + extern char *login_style; /* from sudo.c */ +struct bsdauth_state { + auth_session_t *as; + login_cap_t *lc; +}; + int bsdauth_init(pw, auth) struct passwd *pw; sudo_auth *auth; { - static auth_session_t *as; - extern login_cap_t *lc; /* from sudo.c */ + static struct bsdauth_state state; + + /* 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); + return 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"); + login_close(state.lc); return 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); + auth_close(state.as); + login_close(state.lc); return 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); + auth_close(state.as); + login_close(state.lc); return AUTH_FATAL; } - auth->data = (void *) as; + auth->data = (void *) &state; return AUTH_SUCCESS; } @@ -98,7 +120,7 @@ bsdauth_verify(pw, prompt, 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; /* save old signal handler */ sigemptyset(&sa.sa_mask); @@ -160,9 +182,12 @@ bsdauth_cleanup(pw, auth) struct passwd *pw; sudo_auth *auth; { - auth_session_t *as = (auth_session_t *) auth->data; + struct bsdauth_state *state = auth->data; - auth_close(as); + if (state != NULL) { + auth_close(state->as); + login_close(state->lc); + } return AUTH_SUCCESS; } diff --git a/sudo.c b/sudo.c index f494a61e2..87728abdf 100644 --- a/sudo.c +++ b/sudo.c @@ -309,7 +309,7 @@ main(argc, argv, envp) set_fqdn(); /* deferred until after sudoers is parsed */ /* Set login class if applicable. */ - set_loginclass(sudo_user.pw); + set_loginclass(runas_pw ? runas_pw : sudo_user.pw); /* Update initial shell now that runas is set. */ if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) @@ -1131,6 +1131,9 @@ set_loginclass(pw) { int errflags; + if (!def_use_loginclass) + return; + /* * Don't make it a fatal error if the user didn't specify the login * class themselves. We do this because if login.conf gets @@ -1152,12 +1155,13 @@ set_loginclass(pw) (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS; } + /* Make sure specified login class is valid. */ lc = login_getclass(login_class); if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { log_error(errflags, "unknown login class: %s", login_class); - if (!lc) - lc = login_getclass(NULL); /* needed for login_getstyle() later */ + def_use_loginclass = FALSE; } + login_close(lc); } #else static void