diff --git a/auth/API b/auth/API index bf6d4e5e9..88991b66c 100644 --- 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. diff --git a/auth/afs.c b/auth/afs.c index 82b1d1619..6f13e5368 100644 --- a/auth/afs.c +++ b/auth/afs.c @@ -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; diff --git a/auth/aix_auth.c b/auth/aix_auth.c index 914639fe5..1e53fa638 100644 --- a/auth/aix_auth.c +++ b/auth/aix_auth.c @@ -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; diff --git a/auth/dce.c b/auth/dce.c index 2f959fe4a..0c841095f 100644 --- a/auth/dce.c +++ b/auth/dce.c @@ -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; diff --git a/auth/fwtk.c b/auth/fwtk.c index be1a63574..9e80c63cc 100644 --- a/auth/fwtk.c +++ b/auth/fwtk.c @@ -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(); diff --git a/auth/kerb4.c b/auth/kerb4.c index b57434d84..2503ee51a 100644 --- a/auth/kerb4.c +++ b/auth/kerb4.c @@ -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; /* diff --git a/auth/kerb5.c b/auth/kerb5.c index c11a679d1..48a075f80 100644 --- a/auth/kerb5.c +++ b/auth/kerb5.c @@ -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; diff --git a/auth/pam.c b/auth/pam.c index 71bdf974b..4228b5b34 100644 --- a/auth/pam.c +++ b/auth/pam.c @@ -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; diff --git a/auth/passwd.c b/auth/passwd.c index 1a7b9ed50..aee795f20 100644 --- a/auth/passwd.c +++ b/auth/passwd.c @@ -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 diff --git a/auth/rfc1938.c b/auth/rfc1938.c index a10ee5986..210ad6d31 100644 --- a/auth/rfc1938.c +++ b/auth/rfc1938.c @@ -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); diff --git a/auth/secureware.c b/auth/secureware.c index dbd4151f8..793f57159 100644 --- a/auth/secureware.c +++ b/auth/secureware.c @@ -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; diff --git a/auth/securid.c b/auth/securid.c index 81a7fe261..2d3466212 100644 --- a/auth/securid.c +++ b/auth/securid.c @@ -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); diff --git a/auth/sia.c b/auth/sia.c index 98fe38902..8420c3fa7 100644 --- a/auth/sia.c +++ b/auth/sia.c @@ -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); } diff --git a/auth/sudo_auth.c b/auth/sudo_auth.c index a34511c75..b93ef19a3 100644 --- a/auth/sudo_auth.c +++ b/auth/sudo_auth.c @@ -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); } } diff --git a/auth/sudo_auth.h b/auth/sudo_auth.h index 5bbdccfaa..821822cf4 100644 --- a/auth/sudo_auth.h +++ b/auth/sudo_auth.h @@ -37,76 +37,90 @@ #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 */