Add an approval function to the sudo auth API which is run after

the user's password has been verified.  The approval function is
run even if no password is required.  This is currently only used
for PAM (use pam_acct_mgmt) and BSD auth (auth_approval).
This commit is contained in:
Todd C. Miller
2018-01-16 10:27:58 -07:00
parent f7896025ea
commit 594c2d4efd
7 changed files with 163 additions and 73 deletions

View File

@@ -14,10 +14,11 @@ typedef struct sudo_auth {
int (*init)(struct passwd *pw, sudo_auth *auth); int (*init)(struct passwd *pw, sudo_auth *auth);
int (*setup)(struct passwd *pw, char **prompt, sudo_auth *auth); int (*setup)(struct passwd *pw, char **prompt, sudo_auth *auth);
int (*verify)(struct passwd *pw, char *p, sudo_auth *auth); int (*verify)(struct passwd *pw, char *p, sudo_auth *auth, struct sudo_conv_callback *callback);
int (*approval)(struct passwd *pw, sudo_auth *auth);
int (*cleanup)(struct passwd *pw, sudo_auth *auth); int (*cleanup)(struct passwd *pw, sudo_auth *auth);
int (*begin_session)(struct passwd *pw, sudo_auth *auth); int (*begin_session)(struct passwd *pw, char **user_env[], struct sudo_auth *auth);
int (*end_session)(sudo_auth *auth); int (*end_session)(struct passwd *pw, struct sudo_auth *auth);
} sudo_auth; } sudo_auth;
The variables in the struct are as follows: The variables in the struct are as follows:
@@ -71,13 +72,22 @@ The functions in the struct are as follows:
pointer to the prompt string may be used to add method-specific pointer to the prompt string may be used to add method-specific
info to the prompt. info to the prompt.
int verify(struct passwd *pw, char *p, sudo_auth *auth) int verify(struct passwd *pw, char *p, sudo_auth *auth, struct sudo_conv_callback *callback)
Function to do user verification for this auth method. For Function to do user verification for this auth method. For
standalone auth methods ``p'' is the prompt string. For standalone auth methods ``p'' is the prompt string. For
normal auth methods, ``p'' is the password the user entered. normal auth methods, ``p'' is the password the user entered.
The callback should be passed to auth_getpass() to allow sudoers
to unlock the ticket file when sudo is suspended.
Note that standalone auth methods are responsible for Note that standalone auth methods are responsible for
rerading the password themselves. rerading the password themselves.
int approval(struct passwd *pw, struct sudo_auth *auth)
Function to perform account management and approval *after*
the user has authenticated successfully. This function may
check for expired accounts, perform time of day restrictions, etc.
For PAM, this calls pam_acct_mgmt(). For BSD auth, it calls
auth_approval().
int cleanup(struct passwd *pw, sudo_auth *auth) int cleanup(struct passwd *pw, sudo_auth *auth)
Function to do per-auth method cleanup. This is only run Function to do per-auth method cleanup. This is only run
at the end of the authentication process, after the user at the end of the authentication process, after the user
@@ -85,6 +95,14 @@ The functions in the struct are as follows:
The ``auth->status'' variable contains the result of the The ``auth->status'' variable contains the result of the
last authentication attempt which may be interesting. last authentication attempt which may be interesting.
int begin_session(struct passwd *pw, char **user_env[], struct sudo_auth *auth)
Function to begin a user session. This is used for session handling
in PAM and SIA.
int end_session(struct passwd *pw, struct sudo_auth *auth)
Function to end a user session. This is used for session handling
in PAM and SIA.
A note about standalone methods. Some authentication methods can't A note about standalone methods. Some authentication methods can't
coexist with any 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 methods (pam, sia) or because they have a special way of interacting

View File

@@ -168,6 +168,22 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_con
debug_return_int(AUTH_FAILURE); debug_return_int(AUTH_FAILURE);
} }
int
bsdauth_approval(struct passwd *pw, sudo_auth *auth)
{
struct bsdauth_state *state = auth->data;
debug_decl(bsdauth_approval, SUDOERS_DEBUG_AUTH)
if (auth_approval(state->as, state->lc, pw->pw_name, "auth-sudo") == 0) {
if (auth_getstate(state->as) & AUTH_EXPIRED)
log_warningx(0, "%s", N_("your account has expired"));
else
log_warningx(0, "%s", N_("approval failed"));
debug_return_int(AUTH_FAILURE);
}
debug_return_int(AUTH_SUCCESS);
}
int int
bsdauth_cleanup(struct passwd *pw, sudo_auth *auth) bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2005, 2007-2015 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 1999-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -186,6 +186,28 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co
} }
switch (*pam_status) { switch (*pam_status) {
case PAM_SUCCESS: case PAM_SUCCESS:
debug_return_int(AUTH_SUCCESS);
case PAM_AUTH_ERR:
case PAM_AUTHINFO_UNAVAIL:
case PAM_MAXTRIES:
case PAM_PERM_DENIED:
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
"pam_authenticate: %d", *pam_status);
debug_return_int(AUTH_FAILURE);
default:
if ((s = pam_strerror(pamh, *pam_status)) != NULL)
log_warningx(0, N_("PAM authentication error: %s"), s);
debug_return_int(AUTH_FATAL);
}
}
int
sudo_pam_approval(struct passwd *pw, sudo_auth *auth)
{
const char *s;
int *pam_status = (int *) auth->data;
debug_decl(sudo_pam_approval, SUDOERS_DEBUG_AUTH)
*pam_status = pam_acct_mgmt(pamh, PAM_SILENT); *pam_status = pam_acct_mgmt(pamh, PAM_SILENT);
switch (*pam_status) { switch (*pam_status) {
case PAM_SUCCESS: case PAM_SUCCESS:
@@ -201,10 +223,10 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co
PAM_CHANGE_EXPIRED_AUTHTOK); PAM_CHANGE_EXPIRED_AUTHTOK);
if (*pam_status == PAM_SUCCESS) if (*pam_status == PAM_SUCCESS)
debug_return_int(AUTH_SUCCESS); debug_return_int(AUTH_SUCCESS);
if ((s = pam_strerror(pamh, *pam_status)) != NULL) { if ((s = pam_strerror(pamh, *pam_status)) == NULL)
s = "unknown error";
log_warningx(0, log_warningx(0,
N_("unable to change expired password: %s"), s); N_("unable to change expired password: %s"), s);
}
debug_return_int(AUTH_FAILURE); debug_return_int(AUTH_FAILURE);
case PAM_AUTHTOK_EXPIRED: case PAM_AUTHTOK_EXPIRED:
log_warningx(0, log_warningx(0,
@@ -215,18 +237,17 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co
N_("Account expired or PAM config lacks an \"account\" " N_("Account expired or PAM config lacks an \"account\" "
"section for sudo, contact your system administrator")); "section for sudo, contact your system administrator"));
debug_return_int(AUTH_FATAL); debug_return_int(AUTH_FATAL);
}
/* FALLTHROUGH */
case PAM_AUTH_ERR:
case PAM_AUTHINFO_UNAVAIL: case PAM_AUTHINFO_UNAVAIL:
case PAM_MAXTRIES: case PAM_MAXTRIES:
case PAM_PERM_DENIED: case PAM_PERM_DENIED:
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, s = pam_strerror(pamh, *pam_status);
"pam_acct_mgmt: %d", *pam_status); log_warningx(0, N_("PAM account management error: %s"),
s ? s : "unknown error");
debug_return_int(AUTH_FAILURE); debug_return_int(AUTH_FAILURE);
default: default:
if ((s = pam_strerror(pamh, *pam_status)) != NULL) s = pam_strerror(pamh, *pam_status);
log_warningx(0, N_("PAM authentication error: %s"), s); log_warningx(0, N_("PAM account management error: %s"),
s ? s : "unknown error");
debug_return_int(AUTH_FATAL); debug_return_int(AUTH_FATAL);
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2005, 2008-2016 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 1999-2005, 2008-2018 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -41,47 +41,47 @@
static sudo_auth auth_switch[] = { static sudo_auth auth_switch[] = {
/* Standalone entries first */ /* Standalone entries first */
#ifdef HAVE_AIXAUTH #ifdef HAVE_AIXAUTH
AUTH_ENTRY("aixauth", FLAG_STANDALONE, sudo_aix_init, NULL, sudo_aix_verify, sudo_aix_cleanup, NULL, NULL) AUTH_ENTRY("aixauth", FLAG_STANDALONE, sudo_aix_init, NULL, sudo_aix_verify, NULL, sudo_aix_cleanup, NULL, NULL)
#endif #endif
#ifdef HAVE_PAM #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) AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_approval, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session)
#endif #endif
#ifdef HAVE_SECURID #ifdef HAVE_SECURID
AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL) AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL, NULL)
#endif #endif
#ifdef HAVE_SIA_SES_INIT #ifdef HAVE_SIA_SES_INIT
AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, sudo_sia_cleanup, sudo_sia_begin_session, NULL) AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, NULL, sudo_sia_cleanup, sudo_sia_begin_session, NULL)
#endif #endif
#ifdef HAVE_FWTK #ifdef HAVE_FWTK
AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, sudo_fwtk_cleanup, NULL, NULL) AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, NULL, sudo_fwtk_cleanup, NULL, NULL)
#endif #endif
#ifdef HAVE_BSD_AUTH_H #ifdef HAVE_BSD_AUTH_H
AUTH_ENTRY("bsdauth", FLAG_STANDALONE, bsdauth_init, NULL, bsdauth_verify, bsdauth_cleanup, NULL, NULL) AUTH_ENTRY("bsdauth", FLAG_STANDALONE, bsdauth_init, NULL, bsdauth_verify, bsdauth_approval, bsdauth_cleanup, NULL, NULL)
#endif #endif
/* Non-standalone entries */ /* Non-standalone entries */
#ifndef WITHOUT_PASSWD #ifndef WITHOUT_PASSWD
AUTH_ENTRY("passwd", 0, sudo_passwd_init, NULL, sudo_passwd_verify, sudo_passwd_cleanup, NULL, NULL) AUTH_ENTRY("passwd", 0, sudo_passwd_init, NULL, sudo_passwd_verify, NULL, sudo_passwd_cleanup, NULL, NULL)
#endif #endif
#if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD) #if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD)
AUTH_ENTRY("secureware", 0, sudo_secureware_init, NULL, sudo_secureware_verify, sudo_secureware_cleanup, NULL, NULL) AUTH_ENTRY("secureware", 0, sudo_secureware_init, NULL, sudo_secureware_verify, NULL, sudo_secureware_cleanup, NULL, NULL)
#endif #endif
#ifdef HAVE_AFS #ifdef HAVE_AFS
AUTH_ENTRY("afs", 0, NULL, NULL, sudo_afs_verify, NULL, NULL, NULL) AUTH_ENTRY("afs", 0, NULL, NULL, sudo_afs_verify, NULL, NULL, NULL, NULL)
#endif #endif
#ifdef HAVE_DCE #ifdef HAVE_DCE
AUTH_ENTRY("dce", 0, NULL, NULL, sudo_dce_verify, NULL, NULL, NULL) AUTH_ENTRY("dce", 0, NULL, NULL, sudo_dce_verify, NULL, NULL, NULL, NULL)
#endif #endif
#ifdef HAVE_KERB5 #ifdef HAVE_KERB5
AUTH_ENTRY("kerb5", 0, sudo_krb5_init, sudo_krb5_setup, sudo_krb5_verify, sudo_krb5_cleanup, NULL, NULL) AUTH_ENTRY("kerb5", 0, sudo_krb5_init, sudo_krb5_setup, sudo_krb5_verify, NULL, sudo_krb5_cleanup, NULL, NULL)
#endif #endif
#ifdef HAVE_SKEY #ifdef HAVE_SKEY
AUTH_ENTRY("S/Key", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL) AUTH_ENTRY("S/Key", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL, NULL)
#endif #endif
#ifdef HAVE_OPIE #ifdef HAVE_OPIE
AUTH_ENTRY("OPIE", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL) AUTH_ENTRY("OPIE", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL, NULL)
#endif #endif
AUTH_ENTRY(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL) AUTH_ENTRY(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
}; };
static bool standalone; static bool standalone;
@@ -158,6 +158,30 @@ sudo_auth_init(struct passwd *pw)
debug_return_int(status == AUTH_FATAL ? -1 : 0); debug_return_int(status == AUTH_FATAL ? -1 : 0);
} }
/*
* Cleanup all authentication approval methods.
* Returns true on success, false on failure and -1 on error.
*/
int
sudo_auth_approval(struct passwd *pw, int validated)
{
sudo_auth *auth;
debug_decl(sudo_auth_approval, SUDOERS_DEBUG_AUTH)
/* Call approval routines. */
for (auth = auth_switch; auth->name; auth++) {
if (auth->approval && !IS_DISABLED(auth)) {
int status = (auth->approval)(pw, auth);
if (status != AUTH_SUCCESS) {
/* Assume error msg already printed. */
log_auth_failure(validated, 0);
debug_return_int(status == AUTH_FAILURE ? false : -1);
}
}
}
debug_return_int(true);
}
/* /*
* Cleanup all authentication methods. * Cleanup all authentication methods.
* Returns 0 on success and -1 on error. * Returns 0 on success and -1 on error.
@@ -166,18 +190,19 @@ int
sudo_auth_cleanup(struct passwd *pw) sudo_auth_cleanup(struct passwd *pw)
{ {
sudo_auth *auth; sudo_auth *auth;
int status = AUTH_SUCCESS;
debug_decl(sudo_auth_cleanup, SUDOERS_DEBUG_AUTH) debug_decl(sudo_auth_cleanup, SUDOERS_DEBUG_AUTH)
/* Call cleanup routines. */ /* Call cleanup routines. */
for (auth = auth_switch; auth->name; auth++) { for (auth = auth_switch; auth->name; auth++) {
if (auth->cleanup && !IS_DISABLED(auth)) { if (auth->cleanup && !IS_DISABLED(auth)) {
status = (auth->cleanup)(pw, auth); int status = (auth->cleanup)(pw, auth);
if (status == AUTH_FATAL) if (status == AUTH_FATAL) {
break; /* assume error msg already printed */ /* Assume error msg already printed. */
debug_return_int(-1);
} }
} }
debug_return_int(status == AUTH_FATAL ? -1 : 0); }
debug_return_int(0);
} }
static void static void
@@ -322,7 +347,7 @@ done:
break; break;
case AUTH_FATAL: case AUTH_FATAL:
default: default:
log_auth_failure(validated | FLAG_AUTH_ERROR, 0); log_auth_failure(validated, 0);
ret = -1; ret = -1;
break; break;
} }
@@ -338,17 +363,18 @@ int
sudo_auth_begin_session(struct passwd *pw, char **user_env[]) sudo_auth_begin_session(struct passwd *pw, char **user_env[])
{ {
sudo_auth *auth; sudo_auth *auth;
int status = AUTH_SUCCESS;
debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH) debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH)
for (auth = auth_switch; auth->name; auth++) { for (auth = auth_switch; auth->name; auth++) {
if (auth->begin_session && !IS_DISABLED(auth)) { if (auth->begin_session && !IS_DISABLED(auth)) {
status = (auth->begin_session)(pw, user_env, auth); int status = (auth->begin_session)(pw, user_env, auth);
if (status != AUTH_SUCCESS) if (status != AUTH_SUCCESS) {
break; /* assume error msg already printed */ /* Assume error msg already printed. */
debug_return_int(-1);
} }
} }
debug_return_int(status == AUTH_SUCCESS ? 1 : -1); }
debug_return_int(1);
} }
bool bool
@@ -375,17 +401,19 @@ int
sudo_auth_end_session(struct passwd *pw) sudo_auth_end_session(struct passwd *pw)
{ {
sudo_auth *auth; sudo_auth *auth;
int status = AUTH_SUCCESS; int status;
debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH) debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH)
for (auth = auth_switch; auth->name; auth++) { for (auth = auth_switch; auth->name; auth++) {
if (auth->end_session && !IS_DISABLED(auth)) { if (auth->end_session && !IS_DISABLED(auth)) {
status = (auth->end_session)(pw, auth); status = (auth->end_session)(pw, auth);
if (status == AUTH_FATAL) if (status == AUTH_FATAL) {
break; /* assume error msg already printed */ /* Assume error msg already printed. */
debug_return_int(-1);
} }
} }
debug_return_int(status == AUTH_FATAL ? -1 : 1); }
debug_return_int(1);
} }
/* /*

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2005, 2007-2015 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 1999-2005, 2007-2016, 2018 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -31,6 +31,7 @@ typedef struct sudo_auth {
int (*init)(struct passwd *pw, 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 (*setup)(struct passwd *pw, char **prompt, struct sudo_auth *auth);
int (*verify)(struct passwd *pw, char *p, struct sudo_auth *auth, struct sudo_conv_callback *callback); int (*verify)(struct passwd *pw, char *p, struct sudo_auth *auth, struct sudo_conv_callback *callback);
int (*approval)(struct passwd *pw, struct sudo_auth *auth);
int (*cleanup)(struct passwd *pw, struct sudo_auth *auth); int (*cleanup)(struct passwd *pw, struct sudo_auth *auth);
int (*begin_session)(struct passwd *pw, char **user_env[], struct sudo_auth *auth); int (*begin_session)(struct passwd *pw, char **user_env[], struct sudo_auth *auth);
int (*end_session)(struct passwd *pw, struct sudo_auth *auth); int (*end_session)(struct passwd *pw, struct sudo_auth *auth);
@@ -56,6 +57,7 @@ extern sudo_conv_t sudo_conv;
/* Prototypes for standalone methods */ /* Prototypes for standalone methods */
int bsdauth_init(struct passwd *pw, sudo_auth *auth); int bsdauth_init(struct passwd *pw, sudo_auth *auth);
int bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback); int bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
int bsdauth_approval(struct passwd *pw, sudo_auth *auth);
int bsdauth_cleanup(struct passwd *pw, 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_init(struct passwd *pw, sudo_auth *auth);
int sudo_aix_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback); int sudo_aix_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
@@ -66,6 +68,7 @@ int sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth);
int sudo_pam_init(struct passwd *pw, sudo_auth *auth); int sudo_pam_init(struct passwd *pw, sudo_auth *auth);
int sudo_pam_init_quiet(struct passwd *pw, sudo_auth *auth); int sudo_pam_init_quiet(struct passwd *pw, sudo_auth *auth);
int sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback); int sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
int sudo_pam_approval(struct passwd *pw, sudo_auth *auth);
int sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth); int sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth);
int sudo_pam_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth); int sudo_pam_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth);
int sudo_pam_end_session(struct passwd *pw, sudo_auth *auth); int sudo_pam_end_session(struct passwd *pw, sudo_auth *auth);
@@ -93,8 +96,8 @@ int sudo_secureware_init(struct passwd *pw, sudo_auth *auth);
int sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback); int sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
int sudo_secureware_cleanup(struct passwd *pw, sudo_auth *auth); int sudo_secureware_cleanup(struct passwd *pw, sudo_auth *auth);
/* Fields: name, flags, init, setup, verify, cleanup, begin_sess, end_sess */ /* Fields: name, flags, init, setup, verify, approval, cleanup, begin_sess, end_sess */
#define AUTH_ENTRY(n, f, i, s, v, c, b, e) \ #define AUTH_ENTRY(n, f, i, s, v, a, c, b, e) \
{ (f), AUTH_FAILURE, (n), NULL, (i), (s), (v), (c) , (b), (e) }, { (f), AUTH_FAILURE, (n), NULL, (i), (s), (v), (a), (c) , (b), (e) },
#endif /* SUDO_AUTH_H */ #endif /* SUDO_AUTH_H */

View File

@@ -219,6 +219,10 @@ check_user(int validated, int mode)
ret = check_user_interactive(validated, mode, auth_pw); ret = check_user_interactive(validated, mode, auth_pw);
done: done:
if (ret == true) {
/* The approval function may disallow a user post-authentication. */
ret = sudo_auth_approval(auth_pw, validated);
}
sudo_auth_cleanup(auth_pw); sudo_auth_cleanup(auth_pw);
sudo_pw_delref(auth_pw); sudo_pw_delref(auth_pw);

View File

@@ -136,8 +136,7 @@ struct sudo_user {
#define FLAG_NO_CHECK 0x080 #define FLAG_NO_CHECK 0x080
#define FLAG_NON_INTERACTIVE 0x100 #define FLAG_NON_INTERACTIVE 0x100
#define FLAG_BAD_PASSWORD 0x200 #define FLAG_BAD_PASSWORD 0x200
#define FLAG_AUTH_ERROR 0x400 #define FLAG_NOPASSWD 0x400
#define FLAG_NOPASSWD 0x800
/* /*
* find_path()/set_cmnd() return values * find_path()/set_cmnd() return values
@@ -265,6 +264,7 @@ int verify_user(struct passwd *pw, char *prompt, int validated, struct sudo_conv
int sudo_auth_begin_session(struct passwd *pw, char **user_env[]); int sudo_auth_begin_session(struct passwd *pw, char **user_env[]);
int sudo_auth_end_session(struct passwd *pw); int sudo_auth_end_session(struct passwd *pw);
int sudo_auth_init(struct passwd *pw); int sudo_auth_init(struct passwd *pw);
int sudo_auth_approval(struct passwd *pw, int validated);
int sudo_auth_cleanup(struct passwd *pw); int sudo_auth_cleanup(struct passwd *pw);
/* set_perms.c */ /* set_perms.c */