From: Todd C. Miller Date: Mon, 23 Feb 2015 18:12:43 +0000 (-0700) Subject: On AIX use the value of auth_type in /etc/security/login.cfg to X-Git-Tag: SUDO_1_8_13^2~38 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e11f32fd423febd518572577b9b3c8da6a7b5269;p=sudo On AIX use the value of auth_type in /etc/security/login.cfg to determine whether to use LAM or PAM unless the user specified the --with-pam or --with-aixauth configure flags. --- diff --git a/INSTALL b/INSTALL index a13fdd504..0fa413781 100644 --- a/INSTALL +++ b/INSTALL @@ -381,10 +381,11 @@ Authentication options: link without it. --with-aixauth - Enable support for the AIX 4.x general authentication function. - This will use the authentication scheme specified for the user - on the machine. It is on by default for AIX systems that - support it. + Enable support for the AIX general authentication function. + This will use the authentication scheme specified for the + user on the machine. By default, sudo will use either AIX + authentication or PAM depending on the value of the auth_type + setting in the /etc/security/login.cfg file. --with-bsdauth Enable support for BSD authentication. This is the default diff --git a/NEWS b/NEWS index f7d5d31e1..dc1e498e9 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,10 @@ What's new in Sudo 1.8.13 use passwd (or shadow) file authentication on systems where the crypt() function returns NULL for invalid salts. + * On AIX, sudo now uses the value of the auth_type setting in + /etc/security/login.cfg to determine whether to use LAM or PAM + for user authentication. + What's new in Sudo 1.8.12 * The embedded copy of zlib has been upgraded to version 1.2.8 and diff --git a/configure b/configure index b2dd6d877..a2ee36d4b 100755 --- a/configure +++ b/configure @@ -14514,25 +14514,11 @@ done OSDEFS="${OSDEFS} -D_ALL_SOURCE -D_LINUX_SOURCE_COMPAT" SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -Wl,-bI:\$(srcdir)/aixcrypt.exp" - # On AIX 6 and higher default to PAM, else default to LAM - if test $OSMAJOR -ge 6; then - if test X"$with_pam" = X""; then - AUTH_EXCL_DEF="PAM" - fi - else - if test X"$with_aixauth" = X""; then - for ac_func in authenticate -do : - ac_fn_c_check_func "$LINENO" "authenticate" "ac_cv_func_authenticate" -if test "x$ac_cv_func_authenticate" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_AUTHENTICATE 1 -_ACEOF - AUTH_EXCL_DEF="AIX_AUTH" -fi -done - - fi + # For AIX we build in support for both LAM and PAM + # and choose which to use based on auth_type in + # /etc/security/login.cfg + if test X"${with_pam}${with_aixauth}" = X""; then + AUTH_EXCL_DEF="AIX_AUTH PAM" fi # AIX analog of nsswitch.conf, enabled by default @@ -15210,10 +15196,6 @@ fi AUTH_REG=${AUTH_REG# } AUTH_EXCL=${AUTH_EXCL# } if test -n "$AUTH_EXCL"; then - set -- $AUTH_EXCL - if test $# != 1; then - as_fn_error $? "More than one mutually exclusive authentication method specified: $AUTH_EXCL" "$LINENO" 5 - fi if test -n "$AUTH_REG"; then as_fn_error $? "Cannot mix mutually exclusive ($AUTH_EXCL) and regular ($AUTH_REG) authentication methods" "$LINENO" 5 fi @@ -21693,7 +21675,18 @@ fi fi if test ${with_aixauth-'no'} != "no"; then - if test X"$with_aixauth" != X"maybe" -o X"$AUTH_EXCL" = X""; then + for ac_func in authenticate +do : + ac_fn_c_check_func "$LINENO" "authenticate" "ac_cv_func_authenticate" +if test "x$ac_cv_func_authenticate" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_AUTHENTICATE 1 +_ACEOF + with_aixauth=yes +fi +done + + if test "${with_aixauth}" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: using AIX general authentication" >&5 $as_echo "$as_me: using AIX general authentication" >&6;} $as_echo "#define HAVE_AIXAUTH 1" >>confdefs.h diff --git a/configure.ac b/configure.ac index 6aac79dce..21d96d9fe 100644 --- a/configure.ac +++ b/configure.ac @@ -1680,15 +1680,11 @@ case "$host" in OSDEFS="${OSDEFS} -D_ALL_SOURCE -D_LINUX_SOURCE_COMPAT" SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -Wl,-bI:\$(srcdir)/aixcrypt.exp" - # On AIX 6 and higher default to PAM, else default to LAM - if test $OSMAJOR -ge 6; then - if test X"$with_pam" = X""; then - AUTH_EXCL_DEF="PAM" - fi - else - if test X"$with_aixauth" = X""; then - AC_CHECK_FUNCS([authenticate], [AUTH_EXCL_DEF="AIX_AUTH"]) - fi + # For AIX we build in support for both LAM and PAM + # and choose which to use based on auth_type in + # /etc/security/login.cfg + if test X"${with_pam}${with_aixauth}" = X""; then + AUTH_EXCL_DEF="AIX_AUTH PAM" fi # AIX analog of nsswitch.conf, enabled by default @@ -2104,10 +2100,6 @@ dnl AUTH_REG=${AUTH_REG# } AUTH_EXCL=${AUTH_EXCL# } if test -n "$AUTH_EXCL"; then - set -- $AUTH_EXCL - if test $# != 1; then - AC_MSG_ERROR([More than one mutually exclusive authentication method specified: $AUTH_EXCL]) - fi if test -n "$AUTH_REG"; then AC_MSG_ERROR([Cannot mix mutually exclusive ($AUTH_EXCL) and regular ($AUTH_REG) authentication methods]) fi @@ -3222,10 +3214,12 @@ fi dnl dnl AIX general authentication -dnl If set to "maybe" only enable if no other exclusive method in use. +dnl We may build in support for both AIX LAM and PAM and select +dnl which one to use at run-time. dnl if test ${with_aixauth-'no'} != "no"; then - if test X"$with_aixauth" != X"maybe" -o X"$AUTH_EXCL" = X""; then + AC_CHECK_FUNCS([authenticate], [with_aixauth=yes]) + if test "${with_aixauth}" = "yes"; then AC_MSG_NOTICE([using AIX general authentication]) AC_DEFINE(HAVE_AIXAUTH) AUTH_OBJS="$AUTH_OBJS aix_auth.lo"; diff --git a/plugins/sudoers/auth/aix_auth.c b/plugins/sudoers/auth/aix_auth.c index 0895bf9c3..7202e81c2 100644 --- a/plugins/sudoers/auth/aix_auth.c +++ b/plugins/sudoers/auth/aix_auth.c @@ -39,6 +39,7 @@ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ +#include #include #include @@ -49,6 +50,90 @@ * For a description of the AIX authentication API, see * http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/libs/basetrf1/authenticate.htm */ + +#define AIX_AUTH_UNKNOWN 0 +#define AIX_AUTH_STD 1 +#define AIX_AUTH_PAM 2 + +static int +sudo_aix_authtype(void) +{ + size_t linesize = 0; + ssize_t len; + char *cp, *line = NULL; + bool in_stanza = false; + int authtype = AIX_AUTH_UNKNOWN; + FILE *fp; + debug_decl(sudo_aix_authtype, SUDOERS_DEBUG_AUTH) + + if ((fp = fopen("/etc/security/login.cfg", "r")) != NULL) { + while (authtype == AIX_AUTH_UNKNOWN && (len = getline(&line, &linesize, fp)) != -1) { + /* First remove comments. */ + if ((cp = strchr(line, '#')) != NULL) { + *cp = '\0'; + len = (ssize_t)(cp - line); + } + + /* Next remove trailing newlines and whitespace. */ + while (len > 0 && isspace((unsigned char)line[len - 1])) + line[--len] = '\0'; + + /* Skip blank lines. */ + if (len == 0) + continue; + + /* Match start of the usw stanza. */ + if (!in_stanza) { + if (strncmp(line, "usw:", 4) == 0) + in_stanza = true; + continue; + } + + /* Check for end of the usw stanza. */ + if (!isblank((unsigned char)line[0])) { + in_stanza = false; + break; + } + + /* Skip leading blanks. */ + cp = line; + do { + cp++; + } while (isblank((unsigned char)*cp)); + + /* Match "auth_type = (PAM_AUTH|STD_AUTH)". */ + if (strncmp(cp, "auth_type", 9) != 0) + continue; + cp += 9; + while (isblank((unsigned char)*cp)) + cp++; + if (*cp++ != '=') + continue; + while (isblank((unsigned char)*cp)) + cp++; + if (strcmp(cp, "PAM_AUTH") == 0) + authtype = AIX_AUTH_PAM; + else if (strcmp(cp, "STD_AUTH") == 0) + authtype = AIX_AUTH_STD; + } + free(line); + fclose(fp); + } + + debug_return_int(authtype); +} + +int +sudo_aix_init(struct passwd *pw, sudo_auth *auth) +{ + debug_decl(sudo_aix_init, SUDOERS_DEBUG_AUTH) + + /* Check auth_type in /etc/security/login.cfg. */ + if (sudo_aix_authtype() == AIX_AUTH_PAM) + debug_return_int(AUTH_FAILURE); + debug_return_int(AUTH_SUCCESS); +} + int sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth) { diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c index 3bf1b6b21..ad7c6bfa4 100644 --- a/plugins/sudoers/auth/sudo_auth.c +++ b/plugins/sudoers/auth/sudo_auth.c @@ -49,6 +49,9 @@ static sudo_auth auth_switch[] = { /* Standalone entries first */ +#ifdef HAVE_AIXAUTH + AUTH_ENTRY("aixauth", FLAG_STANDALONE, sudo_aix_init, NULL, sudo_aix_verify, sudo_aix_cleanup, NULL, NULL) +#endif #ifdef HAVE_PAM AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session) #endif @@ -58,9 +61,6 @@ static sudo_auth auth_switch[] = { #ifdef HAVE_SIA_SES_INIT AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, sudo_sia_cleanup, NULL, NULL) #endif -#ifdef HAVE_AIXAUTH - AUTH_ENTRY("aixauth", FLAG_STANDALONE, NULL, NULL, sudo_aix_verify, sudo_aix_cleanup, NULL, NULL) -#endif #ifdef HAVE_FWTK AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, sudo_fwtk_cleanup, NULL, NULL) #endif @@ -109,20 +109,6 @@ sudo_auth_init(struct passwd *pw) if (auth_switch[0].name == NULL) debug_return_int(0); - /* Make sure we haven't mixed standalone and shared auth methods. */ - standalone = IS_STANDALONE(&auth_switch[0]); - if (standalone && auth_switch[1].name != NULL) { - audit_failure(NewArgc, NewArgv, N_("invalid authentication methods")); - log_warningx(SLOG_SEND_MAIL, - N_("Invalid authentication methods compiled into sudo! " - "You may not mix standalone and non-standalone authentication.")); - debug_return_int(-1); - } - - /* Set FLAG_ONEANDONLY if there is only one auth method. */ - if (auth_switch[1].name == NULL) - SET(auth_switch[0].flags, FLAG_ONEANDONLY); - /* Initialize auth methods and unconfigure the method if necessary. */ for (auth = auth_switch; auth->name; auth++) { if (auth->init && !IS_DISABLED(auth)) { @@ -134,6 +120,50 @@ sudo_auth_init(struct passwd *pw) break; /* assume error msg already printed */ } } + + /* + * Make sure we haven't mixed standalone and shared auth methods. + * If there are multiple standalone methods, only use the first one. + */ + if ((standalone = IS_STANDALONE(&auth_switch[0]))) { + bool found = false; + for (auth = auth_switch; auth->name; auth++) { + if (IS_DISABLED(auth)) + continue; + if (!IS_STANDALONE(auth)) { + audit_failure(NewArgc, NewArgv, + N_("invalid authentication methods")); + log_warningx(SLOG_SEND_MAIL, + N_("Invalid authentication methods compiled into sudo! " + "You may not mix standalone and non-standalone authentication.")); + debug_return_int(-1); + } + if (!found) { + /* Found first standalone method. */ + found = true; + continue; + } + /* Disable other standalone methods. */ + SET(auth->flags, FLAG_DISABLED); + } + } + + /* Set FLAG_ONEANDONLY if there is only one auth method. */ + for (auth = auth_switch; auth->name; auth++) { + /* Find first enabled auth method. */ + if (!IS_DISABLED(auth)) { + sudo_auth *first = auth; + /* Check for others. */ + for (; auth->name; auth++) { + if (!IS_DISABLED(auth)) + break; + } + if (auth->name == NULL) + SET(first->flags, FLAG_ONEANDONLY); + break; + } + } + debug_return_int(status == AUTH_FATAL ? -1 : 0); } diff --git a/plugins/sudoers/auth/sudo_auth.h b/plugins/sudoers/auth/sudo_auth.h index aabf5976c..e2e48b404 100644 --- a/plugins/sudoers/auth/sudo_auth.h +++ b/plugins/sudoers/auth/sudo_auth.h @@ -56,6 +56,7 @@ extern sudo_conv_t sudo_conv; int bsdauth_init(struct passwd *pw, sudo_auth *auth); int bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth); int bsdauth_cleanup(struct passwd *pw, sudo_auth *auth); +int sudo_aix_init(struct passwd *pw, sudo_auth *auth); int sudo_aix_verify(struct passwd *pw, char *pass, sudo_auth *auth); int sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth); int sudo_fwtk_init(struct passwd *pw, sudo_auth *auth);