version 1.1, 2012/02/21 16:23:02
|
version 1.1.1.3, 2012/10/09 09:29:52
|
Line 51
|
Line 51
|
static sudo_auth auth_switch[] = { |
static sudo_auth auth_switch[] = { |
/* Standalone entries first */ |
/* Standalone entries first */ |
#ifdef HAVE_PAM |
#ifdef HAVE_PAM |
AUTH_ENTRY("pam", FLAG_STANDALONE, pam_init, NULL, pam_verify, pam_cleanup, pam_begin_session, pam_end_session) | AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session) |
#endif |
#endif |
#ifdef HAVE_SECURID |
#ifdef HAVE_SECURID |
AUTH_ENTRY("SecurId", FLAG_STANDALONE, securid_init, securid_setup, securid_verify, NULL, NULL, NULL) | AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_SIA_SES_INIT |
#ifdef HAVE_SIA_SES_INIT |
AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sia_setup, sia_verify, sia_cleanup, NULL, NULL) | AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, sudo_sia_cleanup, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_AIXAUTH |
#ifdef HAVE_AIXAUTH |
AUTH_ENTRY("aixauth", FLAG_STANDALONE, NULL, NULL, aixauth_verify, aixauth_cleanup, NULL, NULL) | AUTH_ENTRY("aixauth", FLAG_STANDALONE, NULL, NULL, sudo_aix_verify, sudo_aix_cleanup, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_FWTK |
#ifdef HAVE_FWTK |
AUTH_ENTRY("fwtk", FLAG_STANDALONE, fwtk_init, NULL, fwtk_verify, fwtk_cleanup, NULL, NULL) | AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, 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_cleanup, NULL, NULL) |
Line 71 static sudo_auth auth_switch[] = {
|
Line 71 static sudo_auth auth_switch[] = {
|
|
|
/* Non-standalone entries */ |
/* Non-standalone entries */ |
#ifndef WITHOUT_PASSWD |
#ifndef WITHOUT_PASSWD |
AUTH_ENTRY("passwd", 0, passwd_init, NULL, passwd_verify, passwd_cleanup, NULL, NULL) | AUTH_ENTRY("passwd", 0, sudo_passwd_init, NULL, sudo_passwd_verify, 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, secureware_init, NULL, secureware_verify, secureware_cleanup, NULL, NULL) | AUTH_ENTRY("secureware", 0, sudo_secureware_init, NULL, sudo_secureware_verify, sudo_secureware_cleanup, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_AFS |
#ifdef HAVE_AFS |
AUTH_ENTRY("afs", 0, NULL, NULL, afs_verify, NULL, NULL, NULL) | AUTH_ENTRY("afs", 0, NULL, NULL, sudo_afs_verify, NULL, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_DCE |
#ifdef HAVE_DCE |
AUTH_ENTRY("dce", 0, NULL, NULL, dce_verify, NULL, NULL, NULL) | AUTH_ENTRY("dce", 0, NULL, NULL, sudo_dce_verify, NULL, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_KERB4 |
|
AUTH_ENTRY("kerb4", 0, kerb4_init, NULL, kerb4_verify, NULL, NULL, NULL) |
|
#endif |
|
#ifdef HAVE_KERB5 |
#ifdef HAVE_KERB5 |
AUTH_ENTRY("kerb5", 0, kerb5_init, kerb5_setup, kerb5_verify, kerb5_cleanup, NULL, NULL) | AUTH_ENTRY("kerb5", 0, sudo_krb5_init, sudo_krb5_setup, sudo_krb5_verify, sudo_krb5_cleanup, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_SKEY |
#ifdef HAVE_SKEY |
AUTH_ENTRY("S/Key", 0, NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL) | AUTH_ENTRY("S/Key", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL) |
#endif |
#endif |
#ifdef HAVE_OPIE |
#ifdef HAVE_OPIE |
AUTH_ENTRY("OPIE", 0, NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL) | AUTH_ENTRY("OPIE", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, 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) |
}; |
}; |
Line 103 extern char **NewArgv; /* XXX - for auditing */
|
Line 100 extern char **NewArgv; /* XXX - for auditing */
|
|
|
static void pass_warn(void); |
static void pass_warn(void); |
|
|
|
/* |
|
* Initialize sudoers authentication method(s). |
|
* Returns 0 on success and -1 on error. |
|
*/ |
int |
int |
sudo_auth_init(struct passwd *pw) |
sudo_auth_init(struct passwd *pw) |
{ |
{ |
sudo_auth *auth; |
sudo_auth *auth; |
int status = AUTH_SUCCESS; |
int status = AUTH_SUCCESS; |
|
debug_decl(sudo_auth_init, SUDO_DEBUG_AUTH) |
|
|
if (auth_switch[0].name == NULL) |
if (auth_switch[0].name == NULL) |
return TRUE; | debug_return_int(0); |
|
|
/* Make sure we haven't mixed standalone and shared auth methods. */ |
/* Make sure we haven't mixed standalone and shared auth methods. */ |
standalone = IS_STANDALONE(&auth_switch[0]); |
standalone = IS_STANDALONE(&auth_switch[0]); |
if (standalone && auth_switch[1].name != NULL) { |
if (standalone && auth_switch[1].name != NULL) { |
audit_failure(NewArgv, "invalid authentication methods"); |
audit_failure(NewArgv, "invalid authentication methods"); |
log_error(0, _("Invalid authentication methods compiled into sudo! " | log_fatal(0, _("Invalid authentication methods compiled into sudo! " |
"You may mix standalone and non-standalone authentication.")); |
"You may mix standalone and non-standalone authentication.")); |
return -1; | debug_return_int(-1); |
} |
} |
|
|
/* Set FLAG_ONEANDONLY if there is only one auth method. */ |
/* Set FLAG_ONEANDONLY if there is only one auth method. */ |
Line 136 sudo_auth_init(struct passwd *pw)
|
Line 138 sudo_auth_init(struct passwd *pw)
|
if (NEEDS_USER(auth)) |
if (NEEDS_USER(auth)) |
restore_perms(); |
restore_perms(); |
|
|
|
/* Disable if it failed to init unless there was a fatal error. */ |
if (status == AUTH_FAILURE) |
if (status == AUTH_FAILURE) |
SET(auth->flags, FLAG_DISABLED); |
SET(auth->flags, FLAG_DISABLED); |
else if (status == AUTH_FATAL) { | else if (status == AUTH_FATAL) |
/* XXX log */ | |
audit_failure(NewArgv, "authentication failure"); | |
break; /* assume error msg already printed */ |
break; /* assume error msg already printed */ |
} |
|
} |
} |
} |
} |
return status == AUTH_FATAL ? -1 : TRUE; | debug_return_int(status == AUTH_FATAL ? -1 : 0); |
} |
} |
|
|
|
/* |
|
* Cleanup all authentication methods. |
|
* Returns 0 on success and -1 on error. |
|
*/ |
int |
int |
sudo_auth_cleanup(struct passwd *pw) |
sudo_auth_cleanup(struct passwd *pw) |
{ |
{ |
sudo_auth *auth; |
sudo_auth *auth; |
int status = AUTH_SUCCESS; |
int status = AUTH_SUCCESS; |
|
debug_decl(sudo_auth_cleanup, SUDO_DEBUG_AUTH) |
|
|
/* Call cleanup routines. */ |
/* Call cleanup routines. */ |
for (auth = auth_switch; auth->name; auth++) { |
for (auth = auth_switch; auth->name; auth++) { |
Line 165 sudo_auth_cleanup(struct passwd *pw)
|
Line 170 sudo_auth_cleanup(struct passwd *pw)
|
if (NEEDS_USER(auth)) |
if (NEEDS_USER(auth)) |
restore_perms(); |
restore_perms(); |
|
|
if (status == AUTH_FATAL) { | if (status == AUTH_FATAL) |
/* XXX log */ | |
audit_failure(NewArgv, "authentication failure"); | |
break; /* assume error msg already printed */ |
break; /* assume error msg already printed */ |
} |
|
} |
} |
} |
} |
return status == AUTH_FATAL ? -1 : TRUE; | debug_return_int(status == AUTH_FATAL ? -1 : 0); |
} |
} |
|
|
|
/* |
|
* Verify the specified user. |
|
* Returns true if verified, false if not or -1 on error. |
|
*/ |
int |
int |
verify_user(struct passwd *pw, char *prompt) | verify_user(struct passwd *pw, char *prompt, int validated) |
{ |
{ |
int counter = def_passwd_tries + 1; |
int counter = def_passwd_tries + 1; |
int success = AUTH_FAILURE; |
int success = AUTH_FAILURE; |
int flags, status, rval; | int status, rval; |
char *p; |
char *p; |
sudo_auth *auth; |
sudo_auth *auth; |
sigaction_t sa, osa; |
sigaction_t sa, osa; |
|
debug_decl(verify_user, SUDO_DEBUG_AUTH) |
|
|
/* Enable suspend during password entry. */ |
/* Enable suspend during password entry. */ |
sigemptyset(&sa.sa_mask); |
sigemptyset(&sa.sa_mask); |
Line 199 verify_user(struct passwd *pw, char *prompt)
|
Line 206 verify_user(struct passwd *pw, char *prompt)
|
_("There are no authentication methods compiled into sudo! " |
_("There are no authentication methods compiled into sudo! " |
"If you want to turn off authentication, use the " |
"If you want to turn off authentication, use the " |
"--disable-authentication configure option.")); |
"--disable-authentication configure option.")); |
return -1; | debug_return_int(-1); |
} |
} |
|
|
while (--counter) { |
while (--counter) { |
Line 216 verify_user(struct passwd *pw, char *prompt)
|
Line 223 verify_user(struct passwd *pw, char *prompt)
|
|
|
if (status == AUTH_FAILURE) |
if (status == AUTH_FAILURE) |
SET(auth->flags, FLAG_DISABLED); |
SET(auth->flags, FLAG_DISABLED); |
else if (status == AUTH_FATAL) { | else if (status == AUTH_FATAL) |
/* XXX log */ | goto done; /* assume error msg already printed */ |
audit_failure(NewArgv, "authentication failure"); | |
return -1; /* assume error msg already printed */ | |
} | |
} |
} |
} |
} |
|
|
Line 259 done:
|
Line 263 done:
|
switch (success) { |
switch (success) { |
case AUTH_SUCCESS: |
case AUTH_SUCCESS: |
(void) sigaction(SIGTSTP, &osa, NULL); |
(void) sigaction(SIGTSTP, &osa, NULL); |
rval = TRUE; | rval = true; |
break; |
break; |
case AUTH_INTR: |
case AUTH_INTR: |
case AUTH_FAILURE: |
case AUTH_FAILURE: |
if (counter != def_passwd_tries) { | if (counter != def_passwd_tries) |
if (def_mail_badpass || def_mail_always) | validated |= FLAG_BAD_PASSWORD; |
flags = 0; | log_auth_failure(validated, def_passwd_tries - counter); |
else | rval = false; |
flags = NO_MAIL; | |
log_error(flags, ngettext("%d incorrect password attempt", | |
"%d incorrect password attempts", | |
def_passwd_tries - counter), def_passwd_tries - counter); | |
} | |
audit_failure(NewArgv, "authentication failure"); | |
rval = FALSE; | |
break; |
break; |
case AUTH_FATAL: |
case AUTH_FATAL: |
default: |
default: |
audit_failure(NewArgv, "authentication failure"); | log_auth_failure(validated | FLAG_AUTH_ERROR, 0); |
rval = -1; |
rval = -1; |
break; |
break; |
} |
} |
|
|
return rval; | debug_return_int(rval); |
} |
} |
|
|
|
/* |
|
* Call authentication method begin session hooks. |
|
* Returns 1 on success and -1 on error. |
|
*/ |
int |
int |
sudo_auth_begin_session(struct passwd *pw) | sudo_auth_begin_session(struct passwd *pw, char **user_env[]) |
{ |
{ |
sudo_auth *auth; |
sudo_auth *auth; |
int status; | int status = AUTH_SUCCESS; |
| debug_decl(auth_begin_session, SUDO_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, auth); | status = (auth->begin_session)(pw, user_env, auth); |
if (status == AUTH_FATAL) { | if (status == AUTH_FATAL) |
/* XXX log */ | break; /* assume error msg already printed */ |
audit_failure(NewArgv, "authentication failure"); | |
return -1; /* assume error msg already printed */ | |
} | |
} |
} |
} |
} |
return TRUE; | debug_return_int(status == AUTH_FATAL ? -1 : 1); |
} |
} |
|
|
|
/* |
|
* Call authentication method end session hooks. |
|
* Returns 1 on success and -1 on error. |
|
*/ |
int |
int |
sudo_auth_end_session(struct passwd *pw) |
sudo_auth_end_session(struct passwd *pw) |
{ |
{ |
sudo_auth *auth; |
sudo_auth *auth; |
int status; | int status = AUTH_SUCCESS; |
| debug_decl(auth_end_session, SUDO_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) |
/* XXX log */ | break; /* assume error msg already printed */ |
return -1; /* assume error msg already printed */ | |
} | |
} |
} |
} |
} |
return TRUE; | debug_return_int(status == AUTH_FATAL ? -1 : 1); |
} |
} |
|
|
static void |
static void |
pass_warn(void) |
pass_warn(void) |
{ |
{ |
const char *warning = def_badpass_message; |
const char *warning = def_badpass_message; |
|
debug_decl(pass_warn, SUDO_DEBUG_AUTH) |
|
|
#ifdef INSULT |
#ifdef INSULT |
if (def_insults) |
if (def_insults) |
warning = INSULT; |
warning = INSULT; |
#endif |
#endif |
sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", warning); |
sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", warning); |
|
|
|
debug_return; |
} |
} |
|
|
char * |
char * |
Line 339 auth_getpass(const char *prompt, int timeout, int type
|
Line 344 auth_getpass(const char *prompt, int timeout, int type
|
{ |
{ |
struct sudo_conv_message msg; |
struct sudo_conv_message msg; |
struct sudo_conv_reply repl; |
struct sudo_conv_reply repl; |
|
debug_decl(auth_getpass, SUDO_DEBUG_AUTH) |
|
|
/* Mask user input if pwfeedback set and echo is off. */ |
/* Mask user input if pwfeedback set and echo is off. */ |
if (type == SUDO_CONV_PROMPT_ECHO_OFF && def_pwfeedback) |
if (type == SUDO_CONV_PROMPT_ECHO_OFF && def_pwfeedback) |
Line 356 auth_getpass(const char *prompt, int timeout, int type
|
Line 362 auth_getpass(const char *prompt, int timeout, int type
|
memset(&repl, 0, sizeof(repl)); |
memset(&repl, 0, sizeof(repl)); |
sudo_conv(1, &msg, &repl); |
sudo_conv(1, &msg, &repl); |
/* XXX - check for ENOTTY? */ |
/* XXX - check for ENOTTY? */ |
return repl.reply; | debug_return_str_masked(repl.reply); |
} |
} |
|
|
void |
void |
dump_auth_methods(void) |
dump_auth_methods(void) |
{ |
{ |
sudo_auth *auth; |
sudo_auth *auth; |
|
debug_decl(dump_auth_methods, SUDO_DEBUG_AUTH) |
|
|
sudo_printf(SUDO_CONV_INFO_MSG, _("Authentication methods:")); |
sudo_printf(SUDO_CONV_INFO_MSG, _("Authentication methods:")); |
for (auth = auth_switch; auth->name; auth++) |
for (auth = auth_switch; auth->name; auth++) |
sudo_printf(SUDO_CONV_INFO_MSG, " '%s'", auth->name); |
sudo_printf(SUDO_CONV_INFO_MSG, " '%s'", auth->name); |
sudo_printf(SUDO_CONV_INFO_MSG, "\n"); |
sudo_printf(SUDO_CONV_INFO_MSG, "\n"); |
|
|
|
debug_return; |
} |
} |