]> granicus.if.org Git - sudo/commitdiff
In struct sudo_auth, turn need_root and configured into flags and
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 14 Aug 1999 15:36:47 +0000 (15:36 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 14 Aug 1999 15:36:47 +0000 (15:36 +0000)
add a flag to specify an auth method is running alone (the only
one).  Pass auth methods their sudo_auth pointer, not the data
pointer.  This allows us to get at the flags and tell if we are the
only auth method.  That, in turn, allows the method to be able to
decide what should/should not be a fatal error.  Currently only
rfc1938 uses it this way, which allows us to kill the OTP_ONLY
define and te hackery that went with it.  With access to the
sudo_auth struct, methods can also get at a string holding their
cannonical name (useful in error messages).

15 files changed:
auth/API
auth/afs.c
auth/aix_auth.c
auth/dce.c
auth/fwtk.c
auth/kerb4.c
auth/kerb5.c
auth/pam.c
auth/passwd.c
auth/rfc1938.c
auth/secureware.c
auth/securid.c
auth/sia.c
auth/sudo_auth.c
auth/sudo_auth.h

index bf6d4e5e949da86c22a2a3edf253d6f248b69579..88991b66c6bbbd259ba83e9d7475565270400486 100644 (file)
--- a/auth/API
+++ b/auth/API
@@ -1,4 +1,4 @@
-NOTE: the sudo auth API is subject to change
+NOTE: the Sudo auth API is subject to change
 
 Purpose: to provide a simple API for authentication methods that
          encapsulates things nicely without turning into a maze
@@ -7,26 +7,19 @@ Purpose: to provide a simple API for authentication methods that
 The sudo_auth struct looks like this:
 
 typedef struct sudo_auth {
-    int need_root;              /* must run as root? */
-    int configured;             /* auth type configured on this host? */
-    int status;                 /* status from verify routine */
+    short flags;                /* /* various flags, see below */
+    short status;               /* status from verify routine */
     char *name;                        /* name of the method in string form */
-    void *data;                 /* method-specific data pointer */
+    VOID *data;                 /* method-specific data pointer */
 
-    int (*init) __P((struct passwd *pw, char **prompt, void **data));
-    int (*setup) __P((struct passwd *pw, char **prompt, void **data));
-    int (*verify) __P((struct passwd *pw, char *p, void **data));
-    int (*cleanup) __P((struct passwd *pw, int status, void **data));
+    int (*init) __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+    int (*setup) __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+    int (*verify) __P((struct passwd *pw, char *p, sudo_auth *auth));
+    int (*cleanup) __P((struct passwd *pw, int status, sudo_auth *auth));
 } sudo_auth;
 
 The variables in the struct are as follows:
-    need_root  Boolean flag that determines whether or not the auth functions
-               run with an euid of 0 or the uid of the invoking user.
-
-    configured Boolean flag that is true if the auth method has
-               been configured and false if not.  All auth methods
-               start out with this set to true.  If an "init" or "setup"
-               functions fails, "configured" is set to false.
+    flags      Bitwise binary flags, see below.
 
     status     Contains the return value from the last run of
                the "verify" function.  Starts out as AUTH_FAILURE.
@@ -37,6 +30,20 @@ The variables in the struct are as follows:
                all the functions of an auth method and is usually
                initialized in the "init" or "setup" routines.
 
+Possible values of sudo_auth.flags:
+    FLAG_ROOT          Whether or not the auth functions should run with
+                       an euid of 0 or the uid of the invoking user.
+
+    FLAG_CONFIGURED    If set then the auth method is assumed to have been
+                       configured successfully.  All auth methods start out
+                       with this set.  If an "init" or "setup" function
+                       fails, this bit is cleared.
+
+    FLAG_ONEANDONLY    If set, this indicates that the method is the
+                       only one in use.  Can be used by auth functions
+                       to determine whether to return a fatal or nonfatal
+                       error.
+
 The member functions can return the following values:
     AUTH_SUCCESS       Function succeeded.  For a ``verify'' function
                        this means the user correctly authenticated.
@@ -54,34 +61,34 @@ The member functions can return the following values:
 
 The functions in the struct are as follows:
 
-    int init(struct passwd *pw, char **prompt, void **data)
+    int init(struct passwd *pw, char **prompt, sudo_auth *auth)
         Function to do any one-time initialization for the auth
         method.  All of the "init" functions are run before anything
         else.  A pointer to the prompt string may be used to add
         method-specific info to the prompt.
 
-    int setup(struct passwd *pw, char **prompt, void **data)
+    int setup(struct passwd *pw, char **prompt, sudo_auth *auth)
         Function to do method-specific setup.  All the "setup"
         routines are run before any of the "verify" routines.  A
         pointer to the prompt string may be used to add method-specific
         info to the prompt.
 
-    int verify(struct passwd *pw, char *p, void **data)
+    int verify(struct passwd *pw, char *p, sudo_auth *auth)
         Function to do user verification for this auth method.  For
         standalone auth methods ``p'' is the prompt string.  For
         normal auth methods, ``p'' is the password the user entered.
         Note that standalone auth methods are responsible for
         rerading the password themselves.
 
-    int cleanup(struct passwd *pw, int status, void **data)
+    int cleanup(struct passwd *pw, sudo_auth *auth)
         Function to do per-auth method cleanup.  This is only run
         at the end of the authentication process, after the user
         has completely failed or succeeded to authenticate.
-       The ``status'' variable contains the result of the last
-       authentication attempt.
+       The ``auth->status'' variable contains the result of the
+       last authentication attempt which may be interesting.
 
 A note about standalone methods.  Some authentication methods can't
-coexist with anyh others.  This may be because they encapsulate other
+coexist with any others.  This may be because they encapsulate other
 methods (pam, sia) or because they have a special way of interacting
 with the user (securid).
 
@@ -95,8 +102,10 @@ in sudo_auth.h.  For instance, for a method, ``fooauth'', add:
 
 #elif defined(HAVE_FOOAUTH)
 #  define AUTH_STANDALONE \
-        AUTH_ENTRY(1, "foo", foo_init, foo_setup, foo_verify, foo_cleanup)
+        AUTH_ENTRY(FLAG_ROOT, "foo", \
+           foo_init, foo_setup, foo_verify, foo_cleanup)
 
+If the method doesn't need to run as root, replace FLAG_ROOT with 0.
 If you don't have a init/setup/cleanup routine, just use a NULL for that
 field.
 
@@ -105,14 +114,15 @@ sudo_auth.c.  If ``fooauth'' is a normal auth method, its entry
 would look like:
 
 #  ifdef HAVE_FOOAUTH
-    AUTH_ENTRY(1, "foo", foo_init, foo_setup, foo_verify, foo_cleanup)
+    AUTH_ENTRY(FLAG_ROOT, "foo", foo_init, foo_setup, foo_verify, foo_cleanup)
 #  endif
 
-Again, if you don't have a init/setup/cleanup routine, just use a NULL
-for that field.
+Again, if the method doesn't need to run as root, replace FLAG_ROOT
+with 0.  Likewise, if you don't have a init/setup/cleanup routine,
+just use a NULL for that field.
 
-NOTE:  in general, you should not make a method both ``standalone'' and
-       ``normal'' unless you *really* know what you are doing.  See
-       the ``rfc1938'' method for an example of how to do this.
-       In most cases, you are better off using the --without-passwd
-       configure argument.
+NOTE:  You should not make a method both ``standalone'' and
+       ``normal''.  Just use the --without-passwd configure argument
+       to disable passwd/shadow file checking and then have your
+       auth routines check the FLAG_ONEANDONLY flag to see if
+       they are running standalone and act accordingly.
index 82b1d1619fcccf735bb9fb4387d17d833428b1ec..6f13e536857210950433f3a5f802d91ce11aaac0 100644 (file)
@@ -62,10 +62,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-afs_verify(pw, pass, data)
+afs_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
     struct ktc_encryptionKey afs_key;
     struct ktc_token afs_token;
index 914639fe57226aed92b21a3bf536ce8cdc1547fb..1e53fa6385e5c9f4620e91bd667fda59e6ab0d87 100644 (file)
@@ -59,10 +59,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-aixauth_verify(pw, prompt, data)
+aixauth_verify(pw, prompt, auth)
     struct passwd *pw;
     char *prompt;
-    void **data;
+    sudo_auth *auth;
 {
     char *message, *pass;
     int reenter = 1;
index 2f959fe4aa96b0737fadcd26682a0fbdd08fc99d..0c841095fa27d3379054bb55e4c6e6f7fc6d0a96 100644 (file)
@@ -79,10 +79,10 @@ static const char rcsid[] = "$Sudo$";
 static int check_dce_status __P((error_status_t, char *));
 
 int
-dce_verify(pw, plain_pw, data)
+dce_verify(pw, plain_pw, auth)
     struct passwd *pw;
     char *plain_pw;
-    void **data;
+    sudo_auth *auth;
 {
     struct passwd              temp_pw;
     sec_passwd_rec_t           password_rec;
index be1a635743646e28d2790d8b044743705ba714af..9e80c63cc80a33c366aa57d2399af614bb61d1f7 100644 (file)
@@ -61,10 +61,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-fwtk_init(pw, promptp, data)
+fwtk_init(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     static Cfg *confp;                 /* Configuration entry struct */
     char resp[128];                    /* Response from the server */
@@ -96,10 +96,10 @@ fwtk_init(pw, promptp, data)
 }
 
 int
-fwtk_verify(pw, prompt, data)
+fwtk_verify(pw, prompt, auth)
     struct passwd *pw;
     char *prompt;
-    void **data;
+    sudo_auth *auth;
 {
     char *pass;                                /* Password from the user */
     char buf[SUDO_PASS_MAX + 12];      /* General prupose buffer */
@@ -145,10 +145,9 @@ fwtk_verify(pw, prompt, data)
 }
 
 int
-fwtk_cleanup(pw, status, data)
+fwtk_cleanup(pw, auth)
     struct passwd *pw;
-    int status;
-    void **data;
+    sudo_auth *auth;
 {
 
     auth_close();
index b57434d846a4c25de9ba6cbae12d75b3e7b4c6f9..2503ee51affaf10bd7b4aacd582d7ffb3eab5031 100644 (file)
@@ -60,10 +60,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-kerb4_init(pw, promptp, data)
+kerb4_init(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     static char realm[REALM_SZ];
 
@@ -76,19 +76,19 @@ kerb4_init(pw, promptp, data)
        return(AUTH_FAILURE);
 
     /* Stash a pointer to the realm (used in kerb4_verify) */
-    *data = realm;
+    auth->data = (VOID *) realm;
 
     return(AUTH_SUCCESS);
 }
 
 int
-kerb4_verify(pw, pass, data)
+kerb4_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
     char tkfile[sizeof(_PATH_SUDO_TIMEDIR) + 4 + MAX_UID_T_LEN];
-    char *realm = *data;
+    char *realm = (char *) auth->data;
     int error;
 
     /*
index c11a679d1c0a809d22ac830f81c13e7b84d65ae4..48a075f8051c4df1d4cf8bbc4cf0451f9f0548b6 100644 (file)
@@ -69,10 +69,10 @@ static krb5_context sudo_context = NULL;
 static int verify_krb_v5_tgt __P((krb5_ccache));
 
 int
-kerb5_init(pw, promptp, data)
+kerb5_init(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     char *lrealm;
     krb5_error_code retval;
@@ -85,12 +85,11 @@ kerb5_init(pw, promptp, data)
            "unable to initialize Kerberos V context");
        return(AUTH_FATAL);
     }
-    *data = (void *) &sudo_context;    /* save a pointer to the context */
+    auth->data = (VOID *) &sudo_context; /* save a pointer to the context */
 
     krb5_init_ets(sudo_context);
 
     if (retval = krb5_get_default_realm(sudo_context, &lrealm)) {
-       set_perms(PERM_USER, 0);
        log_error(NO_EXIT|NO_MAIL, 
            "unable to get default Kerberos V realm");
        return(AUTH_FATAL);
@@ -110,10 +109,10 @@ kerb5_init(pw, promptp, data)
 }
 
 int
-kerb5_verify(pw, pass, data)
+kerb5_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
     krb5_error_code    retval;
     krb5_principal     princ;
index 71bdf974bda15e98495eb34afad95dcf4e8f114a..4228b5b346a799087a70f6cf5e5449343950e9c7 100644 (file)
@@ -61,14 +61,14 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 static int sudo_conv __P((int, PAM_CONST struct pam_message **,
-                         struct pam_response **, void *));
+                         struct pam_response **, VOID *));
 static char *def_prompt;
 
 int
-pam_init(pw, promptp, data)
+pam_init(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     static struct pam_conv pam_conv;
     pam_handle_t *pamh;
@@ -80,17 +80,17 @@ pam_init(pw, promptp, data)
            "unable to initialize PAM");
        return(AUTH_FATAL);
     }
-    *data = pamh;
+    auth->data = (VOID *) pamh;
     return(AUTH_SUCCESS);
 }
 
 int
-pam_verify(pw, prompt, data)
+pam_verify(pw, prompt, auth)
     struct passwd *pw;
     char *prompt;
-    void **data;
+    sudo_auth *auth;
 {
-    pam_handle_t *pamh = (pam_handle_t *)(*data);
+    pam_handle_t *pamh = (pam_handle_t *) auth->data;
 
     def_prompt = prompt;       /* for sudo_conv */
 
@@ -102,22 +102,19 @@ pam_verify(pw, prompt, data)
 }
 
 int
-pam_cleanup(pw, status, data)
+pam_cleanup(pw, auth)
     struct passwd *pw;
-    int status;
-    void **data;
+    sudo_auth *auth;
 {
-    pam_handle_t *pamh = (pam_handle_t *)(*data);
+    pam_handle_t *pamh = (pam_handle_t *) auth->data;
 
-    if (pam_end(pamh, (status == AUTH_SUCCESS)) == PAM_SUCCESS)
+    if (pam_end(pamh, (auth->status == AUTH_SUCCESS)) == PAM_SUCCESS)
        return(AUTH_SUCCESS);
     else
        return(AUTH_FAILURE);
 }
 
 /*
- * sudo_conv()
- *
  * ``Conversation function'' for PAM.
  */
 static int
@@ -125,7 +122,7 @@ sudo_conv(num_msg, msg, response, appdata_ptr)
     int num_msg;
     PAM_CONST struct pam_message **msg;
     struct pam_response **response;
-    void *appdata_ptr;
+    VOID *appdata_ptr;
 {
     struct pam_response *pr;
     struct pam_message *pm;
index 1a7b9ed50e3df34a2fbde8716189edbc1f3b083f..aee795f20fa2db28d1788c2c0fa41d9992bee2c6 100644 (file)
@@ -59,10 +59,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-passwd_verify(pw, pass, data)
+passwd_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
 
 #ifdef HAVE_GETAUTHUID
index a10ee5986893a46a5f328192ff7deb6f8e32e102..210ad6d315f4a554cb4380c15985364d7160c20f 100644 (file)
@@ -71,10 +71,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-rfc1938_setup(pw, promptp, data)
+rfc1938_setup(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     char challenge[256];
     static char *orig_prompt = NULL, *new_prompt = NULL;
@@ -82,8 +82,8 @@ rfc1938_setup(pw, promptp, data)
     static struct RFC1938 rfc1938;
 
     /* Stash a pointer to the rfc1938 struct if we have not initialized */
-    if (!*data)
-       *data = &rfc1938;
+    if (!auth->data)
+       auth->data = &rfc1938;
 
     /* Save the original prompt */
     if (orig_prompt == NULL) {
@@ -101,16 +101,20 @@ rfc1938_setup(pw, promptp, data)
        (void) fclose(rfc1938.keyfile);
 #endif
 
-    /* Get the rfc1938 part of the prompt */
+    /*
+     * Look up the user and get the rfc1938 challenge.
+     * If the user is not in the OTP db, only post a fatal error if
+     * we are running alone (since they may just use a normal passwd).
+     */
     if (rfc1938challenge(&rfc1938, pw->pw_name, challenge) != 0) {
-#ifdef OTP_ONLY
-       (void) fprintf(stderr,
-                      "%s: You do not exist in the OTP database.\n",
-                      Argv[0]);
-       return(AUTH_FATAL);
-#else
-       return(AUTH_FAILURE);
-#endif /* OTP_ONLY */
+       if (IS_ONEANDONLY(auth)) {
+           (void) fprintf(stderr,
+                          "%s: You do not exist in the %s database.\n",
+                          Argv[0], auth->name);
+           return(AUTH_FATAL);
+       } else {
+           return(AUTH_FAILURE);
+       }
     }
 
     /* Get space for new prompt with embedded challenge */
@@ -130,13 +134,13 @@ rfc1938_setup(pw, promptp, data)
 }
 
 int
-rfc1938_verify(pw, pass, data)
+rfc1938_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
 
-    if (rfc1938verify((struct RFC1938 *) (*data), pass) == 0)
+    if (rfc1938verify((struct RFC1938 *) auth->data, pass) == 0)
        return(AUTH_SUCCESS);
     else
        return(AUTH_FAILURE);
index dbd4151f87e5428e3c40a734db7a0addfca8ffed..793f571596c85785677d388ee7f820b99d06b9d2 100644 (file)
@@ -65,10 +65,10 @@ static const char rcsid[] = "$Sudo$";
 #endif /* lint */
 
 int
-secureware_init(pw, promptp, data)
+secureware_init(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
 #ifdef __alpha
     extern int crypt_type;
@@ -80,10 +80,10 @@ secureware_init(pw, promptp, data)
 }
 
 int
-secureware_verify(pw, pass, data)
+secureware_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
 #ifdef __alpha
     extern int crypt_type;
index 81a7fe261639015e47eb130edec78b7eec2fd7a8..2d34662121c681be4993fff7c84d6e681e1f2534 100644 (file)
@@ -68,10 +68,10 @@ static const char rcsid[] = "$Sudo$";
 union config_record configure;
 
 int
-securid_init(pw, promptp, data)
+securid_init(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
 
     creadcfg();                                        /* Only read config file once */
@@ -79,15 +79,15 @@ securid_init(pw, promptp, data)
 }
 
 int
-securid_setup(pw, promptp, data)
+securid_setup(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     static SD_CLIENT sd_dat;                   /* SecurID data block */
 
     /* Re-initialize SecurID every time. */
-    *data = &sd_dat;
+    auth->data = (VOID *) &sd_dat;
     if (sd_init(sd) == 0)
        return(AUTH_SUCCESS);
     else {
@@ -97,12 +97,12 @@ securid_setup(pw, promptp, data)
 }
 
 int
-securid_verify(pw, pass, data)
+securid_verify(pw, pass, auth)
     struct passwd *pw;
     char *pass;
-    void **data;
+    sudo_auth *auth;
 {
-    struct SD_CLIENT *sd = (struct SD_CLIENT *)(*data);
+    struct SD_CLIENT *sd = (struct SD_CLIENT *) auth->data;
 
     if (sd_auth(sd) == ACM_OK)
        return(AUTH_SUCCESS);
index 98fe38902893f307fa5022edbd04644bf83ed65e..8420c3fa7e8f824bba0c4d5c8888cc80a1850ca0 100644 (file)
@@ -99,10 +99,10 @@ sudo_collect(timeout, rendition, title, nprompts, prompts)
 }
 
 int
-sia_setup(pw, promptp, data)
+sia_setup(pw, promptp, auth)
     struct passwd *pw;
     char **promptp;
-    void **data;
+    sudo_auth *auth;
 {
     SIAENTITY *siah = NULL;
 
@@ -114,17 +114,17 @@ sia_setup(pw, promptp, data)
        return(AUTH_FATAL);
     }
 
-    *data = siah;
+    auth->data = (VOID *) siah;
     return(AUTH_SUCCESS);
 }
 
 int
-sia_verify(pw, prompt, data)
+sia_verify(pw, prompt, auth)
     struct passwd *pw;
     char *prompt;
-    void **data;
+    sudo_auth *auth;
 {
-    SIAENTITY *siah = (SIAENTITY *)(*data);
+    SIAENTITY *siah = (SIAENTITY *) auth->data;
 
     def_prompt = prompt;               /* for sudo_collect */
 
@@ -136,12 +136,11 @@ sia_verify(pw, prompt, data)
 }
 
 int
-sia_cleanup(pw, status, data)
+sia_cleanup(pw, auth)
     struct passwd *pw;
-    int status;
-    void **data;
+    sudo_auth *auth;
 {
-    SIAENTITY *siah = (SIAENTITY *)(*data);
+    SIAENTITY *siah = (SIAENTITY *) auth->data;
 
     (void) sia_ses_release(&siah);
 }
index a34511c7551408dc74cc38214eb3be3173749fba..b93ef19a340307fecd1e3e8971afeab5dd760ab0 100644 (file)
@@ -65,22 +65,25 @@ sudo_auth auth_switch[] = {
     AUTH_STANDALONE
 #else
 #  ifndef WITHOUT_PASSWD
-    AUTH_ENTRY(0, "passwd", NULL, NULL, passwd_verify, NULL)
+    AUTH_ENTRY(FLAG_ROOT, "passwd", NULL, NULL, passwd_verify, NULL)
 #  endif
 #  if defined(HAVE_SECUREWARE) && !defined(WITHOUT_PASSWD)
-    AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, NULL)
+    AUTH_ENTRY(FLAG_ROOT, "secureware", secureware_init, NULL, secureware_verify, NULL)
 #  endif
 #  ifdef HAVE_AFS
-    AUTH_ENTRY(1, "afs", NULL, NULL, afs_verify, NULL)
+    AUTH_ENTRY(FLAG_ROOT, "afs", NULL, NULL, afs_verify, NULL)
 #  endif
 #  ifdef HAVE_KERB4
-    AUTH_ENTRY(1, "kerb4", kerb4_init, NULL, kerb4_verify, NULL)
+    AUTH_ENTRY(FLAG_ROOT, "kerb4", kerb4_init, NULL, kerb4_verify, NULL)
 #  endif
 #  ifdef HAVE_KERB5
-    AUTH_ENTRY(1, "kerb5", kerb5_init, NULL, kerb5_verify, NULL)
+    AUTH_ENTRY(FLAG_ROOT, "kerb5", kerb5_init, NULL, kerb5_verify, NULL)
 #  endif
-#  if defined(HAVE_SKEY)  || defined(HAVE_OPIE)
-    AUTH_ENTRY(1, "rfc1938", NULL, rfc1938_setup, rfc1938_verify, NULL)
+#  ifdef HAVE_SKEY
+    AUTH_ENTRY(FLAG_ROOT, "S/Key", NULL, rfc1938_setup, rfc1938_verify, NULL)
+#  endif
+#  ifdef HAVE_OPIE
+    AUTH_ENTRY(FLAG_ROOT, "OPIE", NULL, rfc1938_setup, rfc1938_verify, NULL)
 #  endif
 #endif /* AUTH_STANDALONE */
     AUTH_ENTRY(0, NULL, NULL, NULL, NULL, NULL)
@@ -91,24 +94,29 @@ int nil_pw;         /* I hate resorting to globals like this... */
 void
 verify_user()
 {
-    int counter = TRIES_FOR_PASSWORD + 1;
-    int status, success = AUTH_FAILURE;
+    short counter = TRIES_FOR_PASSWORD + 1;
+    short success = AUTH_FAILURE;
+    short status;
     char *p;
     sudo_auth *auth;
 
+    /* Set FLAG_ONEANDONLY if there is only one auth method.  */
+    if (auth_switch[0].name && !auth_switch[1].name)
+       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 && auth->configured) {
-           if (auth->need_root)
+       if (auth->init && IS_CONFIGURED(auth)) {
+           if (NEEDS_ROOT(auth))
                set_perms(PERM_ROOT, 0);
 
-           status = (auth->init)(sudo_user.pw, &user_prompt, &auth->data);
+           status = (auth->init)(sudo_user.pw, &user_prompt, auth);
            if (status == AUTH_FAILURE)
-               auth->configured = 0;
+               auth->flags &= ~FLAG_CONFIGURED;
            else if (status == AUTH_FATAL)      /* XXX log */
                exit(1);                /* assume error msg already printed */
 
-           if (auth->need_root)
+           if (NEEDS_ROOT(auth))
                set_perms(PERM_USER, 0);
        }
     }
@@ -116,24 +124,24 @@ verify_user()
     while (--counter) {
        /* Do any per-method setup and unconfigure the method if needed */
        for (auth = auth_switch; auth->name; auth++) {
-           if (auth->setup && auth->configured) {
-               if (auth->need_root)
+           if (auth->setup && IS_CONFIGURED(auth)) {
+               if (NEEDS_ROOT(auth))
                    set_perms(PERM_ROOT, 0);
 
-               status = (auth->setup)(sudo_user.pw, &user_prompt, &auth->data);
+               status = (auth->setup)(sudo_user.pw, &user_prompt, auth);
                if (status == AUTH_FAILURE)
-                   auth->configured = 0;
+                   auth->flags &= ~FLAG_CONFIGURED;
                else if (status == AUTH_FATAL)  /* XXX log */
                    exit(1);            /* assume error msg already printed */
 
-               if (auth->need_root)
+               if (NEEDS_ROOT(auth))
                    set_perms(PERM_USER, 0);
            }
        }
 
        /* Get the password unless the auth function will do it for us */
        nil_pw = 0;
-#if defined(AUTH_STANDALONE) && !defined(AUTH_STANDALONE_GETPASS)
+#if defined(AUTH_STANDALONE)
        p = user_prompt;
 #else
        p = (char *) tgetpass(user_prompt, PASSWORD_TIMEOUT * 60, 1);
@@ -143,16 +151,16 @@ verify_user()
 
        /* Call authentication functions. */
        for (auth = auth_switch; auth->name; auth++) {
-           if (!auth->configured)
+           if (!IS_CONFIGURED(auth))
                continue;
 
-           if (auth->need_root)
+           if (NEEDS_ROOT(auth))
                set_perms(PERM_ROOT, 0);
 
-           success = auth->status = (auth->verify)(sudo_user.pw, p,
-               &auth->data);
+           success = auth->status = (auth->verify)(sudo_user.pw, p, auth);
+           (void) memset(p, 0, strlen(p));
 
-           if (auth->need_root)
+           if (NEEDS_ROOT(auth))
                set_perms(PERM_USER, 0);
 
            if (auth->status != AUTH_FAILURE)
@@ -173,15 +181,15 @@ verify_user()
 cleanup:
     /* Call cleanup routines. */
     for (auth = auth_switch; auth->name; auth++) {
-       if (auth->cleanup && auth->configured) {
-           if (auth->need_root)
+       if (auth->cleanup && IS_CONFIGURED(auth)) {
+           if (NEEDS_ROOT(auth))
                set_perms(PERM_ROOT, 0);
 
-           status = (auth->cleanup)(sudo_user.pw, auth->status, &auth->data);
+           status = (auth->cleanup)(sudo_user.pw, auth);
            if (status == AUTH_FATAL)   /* XXX log */
                exit(1);                /* assume error msg already printed */
 
-           if (auth->need_root)
+           if (NEEDS_ROOT(auth))
                set_perms(PERM_USER, 0);
        }
     }
index 5bbdccfaa973055973fdc0c10a93ad33a78a4e50..821822cf464ea5ef5fed752058fff95c2d892975 100644 (file)
 #ifndef SUDO_AUTH_H
 #define SUDO_AUTH_H
 
+/* Auth function return values.  */
 #define AUTH_SUCCESS   0
 #define AUTH_FAILURE   1
 #define AUTH_FATAL     2
 
 typedef struct sudo_auth {
-    int need_root;             /* must run as root? */
-    int configured;            /* auth type configured on this host? */
-    int status;                        /* status from verify routine */
-    char *name;
-    void *data;                        /* method-specific data pointer */
-    int (*init) __P((struct passwd *pw, char **prompt, void **data));
-    int (*setup) __P((struct passwd *pw, char **prompt, void **data));
-    int (*verify) __P((struct passwd *pw, char *p, void **data));
-    int (*cleanup) __P((struct passwd *pw, int status, void **data));
+    short flags;               /* various flags, see below */
+    short status;              /* status from verify routine */
+    char *name;                        /* name of the method as a string */
+    VOID *data;                        /* method-specific data pointer */
+    int (*init) __P((struct passwd *pw, char **prompt, struct sudo_auth *auth));
+    int (*setup) __P((struct passwd *pw, char **prompt, struct sudo_auth *auth));
+    int (*verify) __P((struct passwd *pw, char *p, struct sudo_auth *auth));
+    int (*cleanup) __P((struct passwd *pw, struct sudo_auth *auth));
 } sudo_auth;
 
+/* Values for sudo_auth.flags.  */
+/* XXX - these names are too long for my liking */
+#define FLAG_ROOT      0x01    /* functions must run as root */
+#define FLAG_CONFIGURED        0x02    /* method configured ok */
+#define FLAG_ONEANDONLY        0x04    /* one and only auth method */
+
+/* Shortcuts for using the flags above. */
+#define NEEDS_ROOT(x)          ((x)->flags & FLAG_ROOT)
+#define IS_CONFIGURED(x)       ((x)->flags & FLAG_CONFIGURED)
+#define IS_ONEANDONLY(x)       ((x)->flags & FLAG_ONEANDONLY)
+
 /* Prototypes for standalone methods */
-int fwtk_init __P((struct passwd *pw, char **prompt, void **data));
-int fwtk_verify __P((struct passwd *pw, char *prompt, void **data));
-int fwtk_cleanup __P((struct passwd *pw, int status, void **data));
-int pam_init __P((struct passwd *pw, char **prompt, void **data));
-int pam_verify __P((struct passwd *pw, char *prompt, void **data));
-int pam_cleanup __P((struct passwd *pw, int status, void **data));
-int sia_setup __P((struct passwd *pw, char **prompt, void **data));
-int sia_verify __P((struct passwd *pw, char *prompt, void **data));
-int sia_cleanup __P((struct passwd *pw, int status, void **data));
-int aixauth_verify __P((struct passwd *pw, char *pass, void **data));
-int dce_verify __P((struct passwd *pw, char *pass, void **data));
+int fwtk_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int fwtk_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int fwtk_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int pam_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int pam_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int pam_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int sia_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int sia_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
+int sia_cleanup __P((struct passwd *pw, sudo_auth *auth));
+int aixauth_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int dce_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
 
 /* Prototypes for normal methods */
-int passwd_verify __P((struct passwd *pw, char *pass, void **data));
-int secureware_init __P((struct passwd *pw, char **prompt, void **data));
-int secureware_verify __P((struct passwd *pw, char *pass, void **data));
-int rfc1938_setup __P((struct passwd *pw, char **prompt, void **data));
-int rfc1938_verify __P((struct passwd *pw, char *pass, void **data));
-int afs_verify __P((struct passwd *pw, char *pass, void **data));
-int kerb4_init __P((struct passwd *pw, char **prompt, void **data));
-int kerb4_verify __P((struct passwd *pw, char *pass, void **data));
-int kerb5_init __P((struct passwd *pw, char **prompt, void **data));
-int kerb5_verify __P((struct passwd *pw, char *pass, void **data));
-int securid_init __P((struct passwd *pw, char **prompt, void **data));
-int securid_setup __P((struct passwd *pw, char **prompt, void **data));
-int securid_verify __P((struct passwd *pw, char *pass, void **data));
+int passwd_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int secureware_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int secureware_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int rfc1938_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int rfc1938_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int afs_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int kerb4_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int kerb4_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int kerb5_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int kerb5_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
+int securid_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int securid_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
+int securid_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
 
 /* Fields: need_root, name, init, setup, verify, cleanup */
-#define AUTH_ENTRY(r, n, i, s, v, c) { r, 1, AUTH_FAILURE, n, NULL, i, s, v, c },
+#define AUTH_ENTRY(r, n, i, s, v, c) \
+       { (r|FLAG_CONFIGURED), AUTH_FAILURE, n, NULL, i, s, v, c },
 
 /* Some methods cannots (or should not) interoperate with any others */
 #if defined(HAVE_PAM)
 #  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "pam", pam_init, NULL, pam_verify, pam_cleanup)
+       AUTH_ENTRY(FLAG_ROOT, "pam", \
+           pam_init, NULL, pam_verify, pam_cleanup)
 #elif defined(HAVE_SECURID)
 #  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "SecurId", securid_init, securid_setup, securid_verify, NULL)
+       AUTH_ENTRY(FLAG_ROOT, "SecurId", \
+           securid_init, securid_setup, securid_verify, NULL)
 #elif defined(HAVE_SIA)
 #  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "sia", NULL, sia_setup, sia_verify, sia_cleanup)
+       AUTH_ENTRY(FLAG_ROOT, "sia", \
+           NULL, sia_setup, sia_verify, sia_cleanup)
 #elif defined(HAVE_DCE)
 #  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "dce", NULL, NULL, dce_verify, NULL)
+       AUTH_ENTRY(FLAG_ROOT, "dce", \
+           NULL, NULL, dce_verify, NULL)
 #elif defined(HAVE_AUTHENTICATE)
 #  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "aixauth", NULL, NULL, aixauth_verify, NULL)
+       AUTH_ENTRY(FLAG_ROOT, "aixauth", \
+           NULL, NULL, aixauth_verify, NULL)
 #elif defined(HAVE_FWTK)
 #  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "fwtk", fwtk_init, NULL, fwtk_verify, fwtk_cleanup)
-#elif defined(OTP_ONLY) && (defined(HAVE_SKEY) || defined(HAVE_OPIE))
-#  define AUTH_STANDALONE \
-       AUTH_ENTRY(1, "rfc1938", NULL, rfc1938_setup, rfc1938_verify, NULL)
-#  define AUTH_STANDALONE_GETPASS
+       AUTH_ENTRY(FLAG_ROOT, "fwtk", fwtk_init, \
+           NULL, fwtk_verify, fwtk_cleanup)
 #endif
 
 #endif /* SUDO_AUTH_H */