]> granicus.if.org Git - sudo/commitdiff
On AIX use the value of auth_type in /etc/security/login.cfg to
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 23 Feb 2015 18:12:43 +0000 (11:12 -0700)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 23 Feb 2015 18:12:43 +0000 (11:12 -0700)
determine whether to use LAM or PAM unless the user specified the
--with-pam or --with-aixauth configure flags.

INSTALL
NEWS
configure
configure.ac
plugins/sudoers/auth/aix_auth.c
plugins/sudoers/auth/sudo_auth.c
plugins/sudoers/auth/sudo_auth.h

diff --git a/INSTALL b/INSTALL
index a13fdd504b96c25d6695ac8c3b27f96b984c299e..0fa413781a96a24f47d023ad9eef7396f6c4a36c 100644 (file)
--- 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 f7d5d31e11f5489107e03a47218a63d7af8c5bec..dc1e498e97ccc479e2a4a41400564379dae582a9 100644 (file)
--- 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
index b2dd6d877fd0038e9b04dcedb1af349530f6e37e..a2ee36d4b58fa3be7eaa72a63b9be00713d7b737 100755 (executable)
--- 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
 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
 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
index 6aac79dcefaaa578109f25844bdad249123aa4da..21d96d9fe98c970be8a0c3232f5c7a858484b11c 100644 (file)
@@ -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";
index 0895bf9c30468242d7f02a584027154e6fd4597c..7202e81c26120e3ef90e2daaaf9c6b26a18ed1b2 100644 (file)
@@ -39,6 +39,7 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
+#include <ctype.h>
 #include <pwd.h>
 #include <usersec.h>
 
  * 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)
 {
index 3bf1b6b21987253564836ff958ceabe90375544e..ad7c6bfa42c6bb820756baaec3298b491dbb063d 100644 (file)
@@ -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);
 }
 
index aabf5976cc398b319d11d26c7671273af78f413e..e2e48b4040bd466c84d838897c577bf608fa8818 100644 (file)
@@ -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);