From bceb5df1583114b82a60ff537df8c05a6723703b Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 27 Sep 2011 13:18:46 -0400 Subject: [PATCH] Modify the authentication API such that the init and cleanup functions are always called, regardless of whether or not we are going to verify a password. This is needed for proper PAM session support. --- plugins/sudoers/auth/API | 7 +- plugins/sudoers/auth/bsdauth.c | 2 +- plugins/sudoers/auth/fwtk.c | 2 +- plugins/sudoers/auth/kerb4.c | 2 +- plugins/sudoers/auth/kerb5.c | 58 +++++++++------ plugins/sudoers/auth/pam.c | 32 ++++---- plugins/sudoers/auth/passwd.c | 2 +- plugins/sudoers/auth/secureware.c | 2 +- plugins/sudoers/auth/securid.c | 2 +- plugins/sudoers/auth/securid5.c | 3 +- plugins/sudoers/auth/sudo_auth.c | 118 ++++++++++++++++++------------ plugins/sudoers/auth/sudo_auth.h | 19 ++--- plugins/sudoers/check.c | 20 ++++- plugins/sudoers/sudoers.c | 4 +- plugins/sudoers/sudoers.h | 6 +- 15 files changed, 163 insertions(+), 116 deletions(-) diff --git a/plugins/sudoers/auth/API b/plugins/sudoers/auth/API index 24bd51086..62c21d063 100644 --- a/plugins/sudoers/auth/API +++ b/plugins/sudoers/auth/API @@ -12,7 +12,7 @@ typedef struct sudo_auth { char *name; /* name of the method in string form */ void *data; /* method-specific data pointer */ - int (*init)(struct passwd *pw, char **prompt, sudo_auth *auth); + int (*init)(struct passwd *pw, sudo_auth *auth); int (*setup)(struct passwd *pw, char **prompt, sudo_auth *auth); int (*verify)(struct passwd *pw, char *p, sudo_auth *auth); int (*cleanup)(struct passwd *pw, sudo_auth *auth); @@ -64,11 +64,10 @@ The member functions can return the following values: The functions in the struct are as follows: - int init(struct passwd *pw, char **prompt, sudo_auth *auth) + int init(struct passwd *pw, 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. + else. int setup(struct passwd *pw, char **prompt, sudo_auth *auth) Function to do method-specific setup. All the "setup" diff --git a/plugins/sudoers/auth/bsdauth.c b/plugins/sudoers/auth/bsdauth.c index ac32a1e6a..60616e2bb 100644 --- a/plugins/sudoers/auth/bsdauth.c +++ b/plugins/sudoers/auth/bsdauth.c @@ -54,7 +54,7 @@ extern char *login_style; /* from sudo.c */ int -bsdauth_init(struct passwd *pw, char **promptp, sudo_auth *auth) +bsdauth_init(struct passwd *pw, sudo_auth *auth) { static auth_session_t *as; extern login_cap_t *lc; /* from sudo.c */ diff --git a/plugins/sudoers/auth/fwtk.c b/plugins/sudoers/auth/fwtk.c index a6e45b253..ebab9154a 100644 --- a/plugins/sudoers/auth/fwtk.c +++ b/plugins/sudoers/auth/fwtk.c @@ -50,7 +50,7 @@ #include "sudo_auth.h" int -fwtk_init(struct passwd *pw, char **promptp, sudo_auth *auth) +fwtk_init(struct passwd *pw, sudo_auth *auth) { static Cfg *confp; /* Configuration entry struct */ char resp[128]; /* Response from the server */ diff --git a/plugins/sudoers/auth/kerb4.c b/plugins/sudoers/auth/kerb4.c index 176d6a797..c16739af4 100644 --- a/plugins/sudoers/auth/kerb4.c +++ b/plugins/sudoers/auth/kerb4.c @@ -48,7 +48,7 @@ #include "sudo_auth.h" int -kerb4_init(struct passwd *pw, char **promptp, sudo_auth *auth) +kerb4_init(struct passwd *pw, sudo_auth *auth) { static char realm[REALM_SZ]; diff --git a/plugins/sudoers/auth/kerb5.c b/plugins/sudoers/auth/kerb5.c index d12e11ff0..f94865dd4 100644 --- a/plugins/sudoers/auth/kerb5.c +++ b/plugins/sudoers/auth/kerb5.c @@ -88,14 +88,49 @@ krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opts) #endif int -kerb5_init(struct passwd *pw, char **promptp, sudo_auth *auth) +kerb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth) +{ + static char *krb5_prompt; + + if (krb5_prompt == NULL) { + krb5_context sudo_context; + krb5_principal princ; + char *pname; + krb5_error_code error; + + sudo_context = ((sudo_krb5_datap) auth->data)->sudo_context; + princ = ((sudo_krb5_datap) auth->data)->princ; + + /* + * Really, we need to tell the caller not to prompt for password. The + * API does not currently provide this unless the auth is standalone. + */ + if ((error = krb5_unparse_name(sudo_context, princ, &pname))) { + log_error(NO_EXIT|NO_MAIL, + _("%s: unable to unparse princ ('%s'): %s"), auth->name, + pw->pw_name, error_message(error)); + return AUTH_FAILURE; + } + + /* Only rewrite prompt if user didn't specify their own. */ + /*if (!strcmp(prompt, PASSPROMPT)) { */ + easprintf(&krb5_prompt, "Password for %s: ", pname); + /*}*/ + free(pname); + } + *promptp = krb5_prompt; + + return AUTH_SUCCESS; +} + +int +kerb5_init(struct passwd *pw, sudo_auth *auth) { krb5_context sudo_context; krb5_ccache ccache; krb5_principal princ; krb5_error_code error; char cache_name[64]; - char *pname; auth->data = (void *) &sudo_krb5_data; /* Stash all our data here */ @@ -117,25 +152,6 @@ kerb5_init(struct passwd *pw, char **promptp, sudo_auth *auth) } princ = sudo_krb5_data.princ; - /* - * Really, we need to tell the caller not to prompt for password. - * The API does not currently provide this unless the auth is standalone. - */ -#if 1 - if ((error = krb5_unparse_name(sudo_context, princ, &pname))) { - log_error(NO_EXIT|NO_MAIL, - _("%s: unable to unparse princ ('%s'): %s"), auth->name, - pw->pw_name, error_message(error)); - return AUTH_FAILURE; - } - - /* Only rewrite prompt if user didn't specify their own. */ - /*if (!strcmp(prompt, PASSPROMPT)) { */ - easprintf(promptp, "Password for %s: ", pname); - /*}*/ - free(pname); -#endif - (void) snprintf(cache_name, sizeof(cache_name), "MEMORY:sudocc_%ld", (long) getpid()); if ((error = krb5_cc_resolve(sudo_context, cache_name, diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c index f0b539452..70e916e0e 100644 --- a/plugins/sudoers/auth/pam.c +++ b/plugins/sudoers/auth/pam.c @@ -80,7 +80,7 @@ static int gotintr; static pam_handle_t *pamh; int -pam_init(struct passwd *pw, char **promptp, sudo_auth *auth) +pam_init(struct passwd *pw, sudo_auth *auth) { static struct pam_conv pam_conv; static int pam_status; @@ -184,10 +184,11 @@ pam_cleanup(struct passwd *pw, sudo_auth *auth) int *pam_status = (int *) auth->data; /* If successful, we can't close the session until pam_end_session() */ - if (auth->status == AUTH_SUCCESS) + if (*pam_status == AUTH_SUCCESS) return AUTH_SUCCESS; *pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT); + pamh = NULL; return *pam_status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE; } @@ -209,10 +210,6 @@ pam_begin_session(struct passwd *pw, sudo_auth *auth) goto done; } - /* If the user did not have to authenticate there is no pam handle yet. */ - if (pamh == NULL) - pam_init(pw, NULL, NULL); - /* * Update PAM_USER to reference the user we are running the command * as, as opposed to the user we authenticated as. @@ -246,22 +243,19 @@ pam_end_session(struct passwd *pw, sudo_auth *auth) { int status = PAM_SUCCESS; + if (pamh != NULL) { #ifndef NO_PAM_SESSION - /* If the user did not have to authenticate there is no pam handle yet. */ - if (pamh == NULL) - pam_init(pw, NULL, NULL); - - /* - * Update PAM_USER to reference the user we are running the command - * as to match the call to pam_open_session(). - */ - (void) pam_set_item(pamh, PAM_USER, pw->pw_name); - - (void) pam_close_session(pamh, PAM_SILENT); + /* + * Update PAM_USER to reference the user we are running the command + * as to match the call to pam_open_session(). + */ + (void) pam_set_item(pamh, PAM_USER, pw->pw_name); + (void) pam_close_session(pamh, PAM_SILENT); #endif - - if (pamh != NULL) status = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT); + pamh = NULL; + } + return status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE; } diff --git a/plugins/sudoers/auth/passwd.c b/plugins/sudoers/auth/passwd.c index ee0e4d300..1316acdae 100644 --- a/plugins/sudoers/auth/passwd.c +++ b/plugins/sudoers/auth/passwd.c @@ -49,7 +49,7 @@ #define HAS_AGEINFO(p, l) (l == 18 && p[DESLEN] == ',') int -passwd_init(struct passwd *pw, char **promptp, sudo_auth *auth) +passwd_init(struct passwd *pw, sudo_auth *auth) { #ifdef HAVE_SKEYACCESS if (skeyaccess(pw, user_tty, NULL, NULL) == 0) diff --git a/plugins/sudoers/auth/secureware.c b/plugins/sudoers/auth/secureware.c index 221889d5d..8a08da79f 100644 --- a/plugins/sudoers/auth/secureware.c +++ b/plugins/sudoers/auth/secureware.c @@ -53,7 +53,7 @@ #include "sudo_auth.h" int -secureware_init(struct passwd *pw, char **promptp, sudo_auth *auth) +secureware_init(struct passwd *pw, sudo_auth *auth) { #ifdef __alpha extern int crypt_type; diff --git a/plugins/sudoers/auth/securid.c b/plugins/sudoers/auth/securid.c index 0f5351103..2c3796c88 100644 --- a/plugins/sudoers/auth/securid.c +++ b/plugins/sudoers/auth/securid.c @@ -56,7 +56,7 @@ union config_record configure; int -securid_init(struct passwd *pw, char **promptp, sudo_auth *auth) +securid_init(struct passwd *pw, sudo_auth *auth) { static struct SD_CLIENT sd_dat; /* SecurID data block */ diff --git a/plugins/sudoers/auth/securid5.c b/plugins/sudoers/auth/securid5.c index 45513c9a9..cf022d2f8 100644 --- a/plugins/sudoers/auth/securid5.c +++ b/plugins/sudoers/auth/securid5.c @@ -59,7 +59,6 @@ * securid_init - Initialises communications with ACE server * Arguments in: * pw - UNUSED - * promptp - UNUSED * auth - sudo authentication structure * * Results out: @@ -68,7 +67,7 @@ * success. */ int -securid_init(struct passwd *pw, char **promptp, sudo_auth *auth) +securid_init(struct passwd *pw, sudo_auth *auth) { static SDI_HANDLE sd_dat; /* SecurID handle */ diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c index 66d8f46a4..6bd921696 100644 --- a/plugins/sudoers/auth/sudo_auth.c +++ b/plugins/sudoers/auth/sudo_auth.c @@ -86,7 +86,7 @@ static sudo_auth auth_switch[] = { AUTH_ENTRY("kerb4", 0, kerb4_init, NULL, kerb4_verify, NULL, NULL, NULL) #endif #ifdef HAVE_KERB5 - AUTH_ENTRY("kerb5", 0, kerb5_init, NULL, kerb5_verify, kerb5_cleanup, NULL, NULL) + AUTH_ENTRY("kerb5", 0, kerb5_init, kerb5_setup, kerb5_verify, kerb5_cleanup, NULL, NULL) #endif #ifdef HAVE_SKEY AUTH_ENTRY("S/Key", 0, NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL) @@ -97,35 +97,19 @@ static sudo_auth auth_switch[] = { AUTH_ENTRY(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) }; +static int standalone; + extern char **NewArgv; /* XXX - for auditing */ static void pass_warn(void); int -verify_user(struct passwd *pw, char *prompt) +sudo_auth_init(struct passwd *pw) { - int counter = def_passwd_tries + 1; - int success = AUTH_FAILURE; - int flags, status, standalone, rval; - char *p; sudo_auth *auth; - sigaction_t sa, osa; - /* Enable suspend during password entry. */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sa.sa_handler = SIG_DFL; - (void) sigaction(SIGTSTP, &sa, &osa); - - /* Make sure we have at least one auth method. */ - if (auth_switch[0].name == NULL) { - audit_failure(NewArgv, "no authentication methods"); - log_error(0, - _("There are no authentication methods compiled into sudo! " - "If you want to turn off authentication, use the " - "--disable-authentication configure option.")); - return -1; - } + if (auth_switch[0].name == NULL) + return AUTH_SUCCESS; /* Make sure we haven't mixed standalone and shared auth methods. */ standalone = IS_STANDALONE(&auth_switch[0]); @@ -146,10 +130,36 @@ verify_user(struct passwd *pw, char *prompt) if (NEEDS_USER(auth)) set_perms(PERM_USER); - status = (auth->init)(pw, &prompt, auth); - if (status == AUTH_FAILURE) - SET(auth->flags, FLAG_DISABLED); - else if (status == AUTH_FATAL) { /* XXX log */ + switch ((auth->init)(pw, auth)) { + case AUTH_FAILURE: + SET(auth->flags, FLAG_DISABLED); + break; + case AUTH_FATAL: + /* XXX log */ + audit_failure(NewArgv, "authentication failure"); + return -1; /* assume error msg already printed */ + } + + if (NEEDS_USER(auth)) + restore_perms(); + } + } + return AUTH_SUCCESS; +} + +int +sudo_auth_cleanup(struct passwd *pw) +{ + sudo_auth *auth; + + /* Call cleanup routines. */ + for (auth = auth_switch; auth->name; auth++) { + if (auth->cleanup && !IS_DISABLED(auth)) { + if (NEEDS_USER(auth)) + set_perms(PERM_USER); + + if ((auth->cleanup)(pw, auth) == AUTH_FATAL) { + /* XXX log */ audit_failure(NewArgv, "authentication failure"); return -1; /* assume error msg already printed */ } @@ -158,6 +168,35 @@ verify_user(struct passwd *pw, char *prompt) restore_perms(); } } + return AUTH_SUCCESS; +} + +int +verify_user(struct passwd *pw, char *prompt) +{ + int counter = def_passwd_tries + 1; + int success = AUTH_FAILURE; + int flags, status, rval; + char *p; + sudo_auth *auth; + sigaction_t sa, osa; + + /* Enable suspend during password entry. */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sa.sa_handler = SIG_DFL; + (void) sigaction(SIGTSTP, &sa, &osa); + + /* Make sure we have at least one auth method. */ + /* XXX - check FLAG_DISABLED too */ + if (auth_switch[0].name == NULL) { + audit_failure(NewArgv, "no authentication methods"); + log_error(0, + _("There are no authentication methods compiled into sudo! " + "If you want to turn off authentication, use the " + "--disable-authentication configure option.")); + return -1; + } while (--counter) { /* Do any per-method setup and unconfigure the method if needed */ @@ -203,31 +242,14 @@ verify_user(struct passwd *pw, char *prompt) restore_perms(); if (auth->status != AUTH_FAILURE) - goto cleanup; + goto done; } if (!standalone) zero_bytes(p, strlen(p)); pass_warn(); } -cleanup: - /* Call cleanup routines. */ - for (auth = auth_switch; auth->name; auth++) { - if (auth->cleanup && !IS_DISABLED(auth)) { - if (NEEDS_USER(auth)) - set_perms(PERM_USER); - - status = (auth->cleanup)(pw, auth); - if (status == AUTH_FATAL) { /* XXX log */ - audit_failure(NewArgv, "authentication failure"); - return -1; /* assume error msg already printed */ - } - - if (NEEDS_USER(auth)) - restore_perms(); - } - } - +done: switch (success) { case AUTH_SUCCESS: (void) sigaction(SIGTSTP, &osa, NULL); @@ -257,7 +279,8 @@ cleanup: return rval; } -int auth_begin_session(struct passwd *pw) +int +sudo_auth_begin_session(struct passwd *pw) { sudo_auth *auth; int status; @@ -274,7 +297,8 @@ int auth_begin_session(struct passwd *pw) return TRUE; } -int auth_end_session(struct passwd *pw) +int +sudo_auth_end_session(struct passwd *pw) { sudo_auth *auth; int status; diff --git a/plugins/sudoers/auth/sudo_auth.h b/plugins/sudoers/auth/sudo_auth.h index 83ea46398..995edb71a 100644 --- a/plugins/sudoers/auth/sudo_auth.h +++ b/plugins/sudoers/auth/sudo_auth.h @@ -28,7 +28,7 @@ typedef struct sudo_auth { int status; /* status from verify routine */ char *name; /* name of the method as a string */ void *data; /* method-specific data pointer */ - int (*init)(struct passwd *pw, char **prompt, struct sudo_auth *auth); + int (*init)(struct passwd *pw, struct sudo_auth *auth); int (*setup)(struct passwd *pw, char **prompt, struct sudo_auth *auth); int (*verify)(struct passwd *pw, char *p, struct sudo_auth *auth); int (*cleanup)(struct passwd *pw, struct sudo_auth *auth); @@ -55,10 +55,10 @@ char *auth_getpass(const char *prompt, int timeout, int type); extern sudo_conv_t sudo_conv; /* Prototypes for standalone methods */ -int fwtk_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int fwtk_init(struct passwd *pw, sudo_auth *auth); int fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth); int fwtk_cleanup(struct passwd *pw, sudo_auth *auth); -int pam_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int pam_init(struct passwd *pw, sudo_auth *auth); int pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth); int pam_cleanup(struct passwd *pw, sudo_auth *auth); int pam_begin_session(struct passwd *pw, sudo_auth *auth); @@ -68,27 +68,28 @@ int sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth); int sia_cleanup(struct passwd *pw, sudo_auth *auth); int aixauth_verify(struct passwd *pw, char *pass, sudo_auth *auth); int aixauth_cleanup(struct passwd *pw, sudo_auth *auth); -int bsdauth_init(struct passwd *pw, char **prompt, sudo_auth *auth); +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); /* Prototypes for normal methods */ -int passwd_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int passwd_init(struct passwd *pw, sudo_auth *auth); int passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth); int passwd_cleanup(struct passwd *pw, sudo_auth *auth); -int secureware_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int secureware_init(struct passwd *pw, sudo_auth *auth); int secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth); int secureware_cleanup(struct passwd *pw, sudo_auth *auth); int rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth); int rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth); int afs_verify(struct passwd *pw, char *pass, sudo_auth *auth); int dce_verify(struct passwd *pw, char *pass, sudo_auth *auth); -int kerb4_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int kerb4_init(struct passwd *pw, sudo_auth *auth); int kerb4_verify(struct passwd *pw, char *pass, sudo_auth *auth); -int kerb5_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int kerb5_init(struct passwd *pw, sudo_auth *auth); +int kerb5_setup(struct passwd *pw, char **prompt, sudo_auth *auth); int kerb5_verify(struct passwd *pw, char *pass, sudo_auth *auth); int kerb5_cleanup(struct passwd *pw, sudo_auth *auth); -int securid_init(struct passwd *pw, char **prompt, sudo_auth *auth); +int securid_init(struct passwd *pw, sudo_auth *auth); int securid_setup(struct passwd *pw, char **prompt, sudo_auth *auth); int securid_verify(struct passwd *pw, char *pass, sudo_auth *auth); diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c index 6a361054d..96d3c1e76 100644 --- a/plugins/sudoers/check.c +++ b/plugins/sudoers/check.c @@ -98,6 +98,7 @@ static struct passwd *get_authpw(void); int check_user(int validated, int mode) { + struct passwd *auth_pw; char *timestampdir = NULL; char *timestampfile = NULL; char *prompt; @@ -113,6 +114,11 @@ check_user(int validated, int mode) ctim_get(&sb, &tty_info.ctime); } + /* Init authentication system regardless of whether we need a password. */ + auth_pw = get_authpw(); + sudo_auth_init(auth_pw); + pw_delref(auth_pw); + /* Always prompt for a password when -k was specified with the command. */ if (ISSET(mode, MODE_IGNORE_TICKET)) { SET(validated, FLAG_CHECK_USER); @@ -124,11 +130,13 @@ check_user(int validated, int mode) if (user_uid == 0 || (user_uid == runas_pw->pw_uid && (!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name))) || user_is_exempt()) - return TRUE; + goto done; } - if (build_timestamp(×tampdir, ×tampfile) == -1) - return -1; + if (build_timestamp(×tampdir, ×tampfile) == -1) { + rval = -1; + goto done; + } status = timestamp_status(timestampdir, timestampfile, user_name, TS_MAKE_DIRS); @@ -139,7 +147,8 @@ check_user(int validated, int mode) /* Bail out if we are non-interactive and a password is required */ if (ISSET(mode, MODE_NONINTERACTIVE)) { warningx(_("sorry, a password is required to run %s"), getprogname()); - return -1; + rval = -1; + goto done; } /* XXX - should not lecture if askpass helper is being used. */ @@ -160,6 +169,9 @@ check_user(int validated, int mode) efree(timestampdir); efree(timestampfile); +done: + sudo_auth_cleanup(auth_pw); + return rval; } diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index d2595dd8d..c32d5b29f 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -254,7 +254,7 @@ sudoers_policy_close(int exit_status, int error_code) /* Close the session we opened in sudoers_policy_init_session(). */ if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT)) - (void)auth_end_session(runas_pw); + (void)sudo_auth_end_session(runas_pw); /* Free remaining references to password and group entries. */ pw_delref(sudo_user.pw); @@ -277,7 +277,7 @@ sudoers_policy_init_session(struct passwd *pwd) return -1; } - return auth_begin_session(pwd); + return sudo_auth_begin_session(pwd); } static int diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index c88e90b13..8b51e1d33 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -218,8 +218,10 @@ int user_is_exempt(void); /* sudo_auth.c */ int verify_user(struct passwd *, char *); -int auth_begin_session(struct passwd *); -int auth_end_session(); +int sudo_auth_begin_session(struct passwd *); +int sudo_auth_end_session(struct passwd *); +int sudo_auth_init(struct passwd *pw); +int sudo_auth_cleanup(struct passwd *pw); /* parse.c */ int sudo_file_open(struct sudo_nss *);