Add a force flag to sudo_auth_cleanup() to force immediate cleanup.
This is used for PAM authentication to make sure pam_end() is called via sudo_auth_cleanup() when the user authenticates successfully but sudoers denies the command. Debian bug #669687
This commit is contained in:
@@ -16,7 +16,7 @@ typedef struct sudo_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, struct sudo_conv_callback *callback);
|
int (*verify)(struct passwd *pw, char *p, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int (*approval)(struct passwd *pw, sudo_auth *auth);
|
int (*approval)(struct passwd *pw, sudo_auth *auth);
|
||||||
int (*cleanup)(struct passwd *pw, sudo_auth *auth);
|
int (*cleanup)(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
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);
|
||||||
} sudo_auth;
|
} sudo_auth;
|
||||||
@@ -88,12 +88,13 @@ The functions in the struct are as follows:
|
|||||||
For PAM, this calls pam_acct_mgmt(). For BSD auth, it calls
|
For PAM, this calls pam_acct_mgmt(). For BSD auth, it calls
|
||||||
auth_approval().
|
auth_approval().
|
||||||
|
|
||||||
int cleanup(struct passwd *pw, sudo_auth *auth)
|
int cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
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
|
||||||
has completely failed or succeeded to authenticate.
|
has completely failed or succeeded to authenticate.
|
||||||
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.
|
||||||
|
If the force flag is set, cleanup should happen immediately.
|
||||||
|
|
||||||
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)
|
||||||
Function to begin a user session. This is used for session handling
|
Function to begin a user session. This is used for session handling
|
||||||
|
@@ -300,7 +300,7 @@ sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_aix_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_aix_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
|
@@ -191,7 +191,7 @@ bsdauth_approval(struct passwd *pw, sudo_auth *auth, bool exempt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
|
bsdauth_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
struct bsdauth_state *state = auth->data;
|
struct bsdauth_state *state = auth->data;
|
||||||
debug_decl(bsdauth_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(bsdauth_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
@@ -145,7 +145,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_fwtk_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_fwtk_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
|
@@ -268,7 +268,7 @@ done:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
krb5_context sudo_context;
|
krb5_context sudo_context;
|
||||||
krb5_principal princ;
|
krb5_principal princ;
|
||||||
|
@@ -394,13 +394,13 @@ sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
int *pam_status = (int *) auth->data;
|
int *pam_status = (int *) auth->data;
|
||||||
debug_decl(sudo_pam_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_pam_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
|
||||||
/* If successful, we can't close the session until sudo_pam_end_session() */
|
/* If successful, we can't close the session until sudo_pam_end_session() */
|
||||||
if (*pam_status != PAM_SUCCESS || auth->end_session == NULL) {
|
if (force || *pam_status != PAM_SUCCESS || auth->end_session == NULL) {
|
||||||
*pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
|
*pam_status = pam_end(pamh, *pam_status | PAM_DATA_SILENT);
|
||||||
pamh = NULL;
|
pamh = NULL;
|
||||||
}
|
}
|
||||||
|
@@ -100,7 +100,7 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_passwd_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_passwd_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
char *pw_epasswd = auth->data;
|
char *pw_epasswd = auth->data;
|
||||||
debug_decl(sudo_passwd_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_passwd_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
@@ -101,7 +101,7 @@ sudo_secureware_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct su
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_secureware_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_secureware_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
char *pw_epasswd = auth->data;
|
char *pw_epasswd = auth->data;
|
||||||
debug_decl(sudo_secureware_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_secureware_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
@@ -106,7 +106,7 @@ sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth)
|
sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
|
||||||
{
|
{
|
||||||
SIAENTITY *siah = auth->data;
|
SIAENTITY *siah = auth->data;
|
||||||
debug_decl(sudo_sia_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_sia_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-License-Identifier: ISC
|
* SPDX-License-Identifier: ISC
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999-2005, 2008-2018 Todd C. Miller <Todd.Miller@sudo.ws>
|
* Copyright (c) 1999-2005, 2008-2020 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
|
||||||
@@ -199,7 +199,7 @@ sudo_auth_approval(struct passwd *pw, int validated, bool exempt)
|
|||||||
* Returns 0 on success and -1 on error.
|
* Returns 0 on success and -1 on error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sudo_auth_cleanup(struct passwd *pw)
|
sudo_auth_cleanup(struct passwd *pw, bool force)
|
||||||
{
|
{
|
||||||
sudo_auth *auth;
|
sudo_auth *auth;
|
||||||
debug_decl(sudo_auth_cleanup, SUDOERS_DEBUG_AUTH);
|
debug_decl(sudo_auth_cleanup, SUDOERS_DEBUG_AUTH);
|
||||||
@@ -207,7 +207,7 @@ sudo_auth_cleanup(struct passwd *pw)
|
|||||||
/* 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)) {
|
||||||
int status = (auth->cleanup)(pw, auth);
|
int status = (auth->cleanup)(pw, auth, force);
|
||||||
if (status == AUTH_FATAL) {
|
if (status == AUTH_FATAL) {
|
||||||
/* Assume error msg already printed. */
|
/* Assume error msg already printed. */
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
|
@@ -34,7 +34,7 @@ typedef struct sudo_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, bool exempt);
|
int (*approval)(struct passwd *pw, struct sudo_auth *auth, bool exempt);
|
||||||
int (*cleanup)(struct passwd *pw, struct sudo_auth *auth);
|
int (*cleanup)(struct passwd *pw, struct sudo_auth *auth, bool force);
|
||||||
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);
|
||||||
} sudo_auth;
|
} sudo_auth;
|
||||||
@@ -59,18 +59,18 @@ extern sudo_conv_t sudo_conv;
|
|||||||
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, bool exempt);
|
int bsdauth_approval(struct passwd *pw, sudo_auth *auth, bool exempt);
|
||||||
int bsdauth_cleanup(struct passwd *pw, sudo_auth *auth);
|
int bsdauth_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
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);
|
||||||
int sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth);
|
int sudo_aix_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
int sudo_fwtk_init(struct passwd *pw, sudo_auth *auth);
|
int sudo_fwtk_init(struct passwd *pw, sudo_auth *auth);
|
||||||
int sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
|
int sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth);
|
int sudo_fwtk_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
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, bool exempt);
|
int sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt);
|
||||||
int sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth);
|
int sudo_pam_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
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);
|
||||||
int sudo_securid_init(struct passwd *pw, sudo_auth *auth);
|
int sudo_securid_init(struct passwd *pw, sudo_auth *auth);
|
||||||
@@ -78,7 +78,7 @@ int sudo_securid_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
|||||||
int sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
int sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int sudo_sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
int sudo_sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
||||||
int sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
|
int sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth);
|
int sudo_sia_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
int sudo_sia_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth);
|
int sudo_sia_begin_session(struct passwd *pw, char **user_env[], sudo_auth *auth);
|
||||||
|
|
||||||
/* Prototypes for normal methods */
|
/* Prototypes for normal methods */
|
||||||
@@ -87,15 +87,15 @@ int sudo_dce_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_
|
|||||||
int sudo_krb5_init(struct passwd *pw, sudo_auth *auth);
|
int sudo_krb5_init(struct passwd *pw, sudo_auth *auth);
|
||||||
int sudo_krb5_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
int sudo_krb5_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
||||||
int sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
int sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth);
|
int sudo_krb5_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
int sudo_passwd_init(struct passwd *pw, sudo_auth *auth);
|
int sudo_passwd_init(struct passwd *pw, sudo_auth *auth);
|
||||||
int sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
int sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int sudo_passwd_cleanup(struct passwd *pw, sudo_auth *auth);
|
int sudo_passwd_cleanup(struct passwd *pw, sudo_auth *auth, bool force);
|
||||||
int sudo_rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
int sudo_rfc1938_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
|
||||||
int sudo_rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
int sudo_rfc1938_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback);
|
||||||
int sudo_secureware_init(struct passwd *pw, sudo_auth *auth);
|
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, bool force);
|
||||||
|
|
||||||
/* Fields: name, flags, init, setup, verify, approval, 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, a, c, b, e) \
|
#define AUTH_ENTRY(n, f, i, s, v, a, c, b, e) \
|
||||||
|
@@ -223,7 +223,7 @@ done:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
timestamp_close(closure.cookie);
|
timestamp_close(closure.cookie);
|
||||||
sudo_auth_cleanup(closure.auth_pw);
|
sudo_auth_cleanup(closure.auth_pw, !ISSET(validated, VALIDATE_SUCCESS));
|
||||||
if (closure.auth_pw != NULL)
|
if (closure.auth_pw != NULL)
|
||||||
sudo_pw_delref(closure.auth_pw);
|
sudo_pw_delref(closure.auth_pw);
|
||||||
|
|
||||||
|
@@ -272,7 +272,7 @@ 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, bool exempt);
|
int sudo_auth_approval(struct passwd *pw, int validated, bool exempt);
|
||||||
int sudo_auth_cleanup(struct passwd *pw);
|
int sudo_auth_cleanup(struct passwd *pw, bool force);
|
||||||
|
|
||||||
/* set_perms.c */
|
/* set_perms.c */
|
||||||
bool rewind_perms(void);
|
bool rewind_perms(void);
|
||||||
|
Reference in New Issue
Block a user