void dump_auth_methods(void) { sudo_auth *auth; sudo_printf(SUDO_CONV_INFO_MSG, _("Authentication methods:")); for (auth = auth_switch; auth->name; auth++) sudo_printf(SUDO_CONV_INFO_MSG, " '%s'", auth->name); sudo_printf(SUDO_CONV_INFO_MSG, "\n"); }
/* * Log and mail the denial message, optionally informing the user. */ void log_denial(int status, int inform_user) { char *message; char *logline; /* Set error message. */ if (ISSET(status, FLAG_NO_USER)) message = _("user NOT in sudoers"); else if (ISSET(status, FLAG_NO_HOST)) message = _("user NOT authorized on host"); else message = _("command not allowed"); logline = new_logline(message, 0); if (should_mail(status)) send_mail("%s", logline); /* send mail based on status */ /* Inform the user if they failed to authenticate. */ if (inform_user) { if (ISSET(status, FLAG_NO_USER)) { sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not in the sudoers " "file. This incident will be reported.\n"), user_name); } else if (ISSET(status, FLAG_NO_HOST)) { sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not allowed to run sudo " "on %s. This incident will be reported.\n"), user_name, user_shost); } else if (ISSET(status, FLAG_NO_CHECK)) { sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s may not run " "sudo on %s.\n"), user_name, user_shost); } else { sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s is not allowed " "to execute '%s%s%s' as %s%s%s on %s.\n"), user_name, user_cmnd, user_args ? " " : "", user_args ? user_args : "", list_pw ? list_pw->pw_name : runas_pw ? runas_pw->pw_name : user_name, runas_gr ? ":" : "", runas_gr ? runas_gr->gr_name : "", user_host); } } /* * Log via syslog and/or a file. */ if (def_syslog) do_syslog(def_syslog_badpri, logline); if (def_logfile) do_logfile(logline); efree(logline); }
static void pass_warn(void) { const char *warning = def_badpass_message; #ifdef INSULT if (def_insults) warning = INSULT; #endif sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", warning); }
/* Returns 0 for DCE "ok" status, 1 otherwise */ static int check_dce_status(error_status_t input_status, char *comment) { int error_stat; unsigned char error_string[dce_c_error_string_len]; debug_decl(check_dce_status, SUDOERS_DEBUG_AUTH) if (input_status == rpc_s_ok) debug_return_int(0); dce_error_inq_text(input_status, error_string, &error_stat); sudo_printf(SUDO_CONV_ERROR_MSG, "%s %s\n", comment, error_string); debug_return_int(1); }
/* * Log, audit and mail the denial message, optionally informing the user. */ bool log_denial(int status, bool inform_user) { const char *message; char *logline; int oldlocale; bool uid_changed, ret = true; debug_decl(log_denial, SUDOERS_DEBUG_LOGGING) /* Handle auditing first (audit_failure() handles the locale itself). */ if (ISSET(status, FLAG_NO_USER | FLAG_NO_HOST)) audit_failure(NewArgc, NewArgv, N_("No user or host")); else audit_failure(NewArgc, NewArgv, N_("validation failure")); /* Log and mail messages should be in the sudoers locale. */ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); /* Set error message. */ if (ISSET(status, FLAG_NO_USER)) message = _("user NOT in sudoers"); else if (ISSET(status, FLAG_NO_HOST)) message = _("user NOT authorized on host"); else message = _("command not allowed"); logline = new_logline(message, 0); if (logline == NULL) debug_return_bool(false); /* Become root if we are not already. */ uid_changed = set_perms(PERM_ROOT); if (should_mail(status)) send_mail("%s", logline); /* send mail based on status */ /* * Log via syslog and/or a file. */ if (def_syslog) do_syslog(def_syslog_badpri, logline); if (def_logfile && !do_logfile(logline)) ret = false; if (uid_changed) { if (!restore_perms()) ret = false; /* XXX - return -1 instead? */ } free(logline); /* Restore locale. */ sudoers_setlocale(oldlocale, NULL); /* Inform the user if they failed to authenticate (in their locale). */ if (inform_user) { sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale); if (ISSET(status, FLAG_NO_USER)) { sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not in the sudoers " "file. This incident will be reported.\n"), user_name); } else if (ISSET(status, FLAG_NO_HOST)) { sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not allowed to run sudo " "on %s. This incident will be reported.\n"), user_name, user_srunhost); } else if (ISSET(status, FLAG_NO_CHECK)) { sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s may not run " "sudo on %s.\n"), user_name, user_srunhost); } else { sudo_printf(SUDO_CONV_ERROR_MSG, _("Sorry, user %s is not allowed " "to execute '%s%s%s' as %s%s%s on %s.\n"), user_name, user_cmnd, user_args ? " " : "", user_args ? user_args : "", list_pw ? list_pw->pw_name : runas_pw ? runas_pw->pw_name : user_name, runas_gr ? ":" : "", runas_gr ? runas_gr->gr_name : "", user_host); } sudoers_setlocale(oldlocale, NULL); } debug_return_bool(ret); }
int sudo_dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth, struct sudo_conv_callback *callback) { struct passwd temp_pw; sec_passwd_rec_t password_rec; sec_login_handle_t login_context; boolean32 reset_passwd; sec_login_auth_src_t auth_src; error_status_t status; debug_decl(sudo_dce_verify, SUDOERS_DEBUG_AUTH) /* * Create the local context of the DCE principal necessary * to perform authenticated network operations. The network * identity set up by this operation cannot be used until it * is validated via sec_login_validate_identity(). */ if (sec_login_setup_identity((unsigned_char_p_t) pw->pw_name, sec_login_no_flags, &login_context, &status)) { if (check_dce_status(status, "sec_login_setup_identity(1):")) debug_return_int(AUTH_FAILURE); password_rec.key.key_type = sec_passwd_plain; password_rec.key.tagged_union.plain = (idl_char *) plain_pw; password_rec.pepper = NULL; password_rec.version_number = sec_passwd_c_version_none; /* Validate the login context with the password */ if (sec_login_validate_identity(login_context, &password_rec, &reset_passwd, &auth_src, &status)) { if (check_dce_status(status, "sec_login_validate_identity(1):")) debug_return_int(AUTH_FAILURE); /* * Certify that the DCE Security Server used to set * up and validate a login context is legitimate. Makes * sure that we didn't get spoofed by another DCE server. */ if (!sec_login_certify_identity(login_context, &status)) { sudo_printf(SUDO_CONV_ERROR_MSG, "Whoa! Bogus authentication server!\n"); (void) check_dce_status(status,"sec_login_certify_identity(1):"); debug_return_int(AUTH_FAILURE); } if (check_dce_status(status, "sec_login_certify_identity(2):")) debug_return_int(AUTH_FAILURE); /* * Sets the network credentials to those specified * by the now validated login context. */ sec_login_set_context(login_context, &status); if (check_dce_status(status, "sec_login_set_context:")) debug_return_int(AUTH_FAILURE); /* * Oops, your credentials were no good. Possibly * caused by clock times out of adjustment between * DCE client and DCE security server... */ if (auth_src != sec_login_auth_src_network) { sudo_printf(SUDO_CONV_ERROR_MSG, "You have no network credentials.\n"); debug_return_int(AUTH_FAILURE); } /* Check if the password has aged and is thus no good */ if (reset_passwd) { sudo_printf(SUDO_CONV_ERROR_MSG, "Your DCE password needs resetting.\n"); debug_return_int(AUTH_FAILURE); } /* * We should be a valid user by this point. Pull the * user's password structure from the DCE security * server just to make sure. If we get it with no * problems, then we really are legitimate... */ sec_login_get_pwent(login_context, (sec_login_passwd_t) &temp_pw, &status); if (check_dce_status(status, "sec_login_get_pwent:")) debug_return_int(AUTH_FAILURE); /* * If we get to here, then the pwent above properly fetched * the password structure from the DCE registry, so the user * must be valid. We don't really care what the user's * registry password is, just that the user could be * validated. In fact, if we tried to compare the local * password to the DCE entry at this point, the operation * would fail if the hidden password feature is turned on, * because the password field would contain an asterisk. * Also go ahead and destroy the user's DCE login context * before we leave here (and don't bother checking the * status), in order to clean up credentials files in * /opt/dcelocal/var/security/creds. By doing this, we are * assuming that the user will not need DCE authentication * later in the program, only local authentication. If this * is not true, then the login_context will have to be * returned to the calling program, and the context purged * somewhere later in the program. */ sec_login_purge_context(&login_context, &status); debug_return_int(AUTH_SUCCESS); } else { if(check_dce_status(status, "sec_login_validate_identity(2):")) debug_return_int(AUTH_FAILURE); sec_login_purge_context(&login_context, &status); if(check_dce_status(status, "sec_login_purge_context:")) debug_return_int(AUTH_FAILURE); } } (void) check_dce_status(status, "sec_login_setup_identity(2):"); debug_return_int(AUTH_FAILURE); }
/* * securid_verify - Authenticates user and handles ACE responses * * Arguments in: * pw - struct passwd for username * pass - UNUSED * auth - sudo authentication structure for SecurID handle * * Results out: * return code - Success on successful authentication, failure on * incorrect authentication, fatal on errors */ int sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback) { SDI_HANDLE *sd = (SDI_HANDLE *) auth->data; int ret; debug_decl(sudo_securid_verify, SUDOERS_DEBUG_AUTH) pass = auth_getpass("Enter your PASSCODE: ", SUDO_CONV_PROMPT_ECHO_OFF, callback); /* Have ACE verify password */ switch (SD_Check(*sd, pass, pw->pw_name)) { case ACM_OK: ret = AUTH_SUCESS; break; case ACE_UNDEFINED_PASSCODE: sudo_warnx(U_("invalid passcode length for SecurID")); ret = AUTH_FATAL; break; case ACE_UNDEFINED_USERNAME: sudo_warnx(U_("invalid username length for SecurID")); ret = AUTH_FATAL; break; case ACE_ERR_INVALID_HANDLE: sudo_warnx(U_("invalid Authentication Handle for SecurID")); ret = AUTH_FATAL; break; case ACM_ACCESS_DENIED: ret = AUTH_FAILURE; break; case ACM_NEXT_CODE_REQUIRED: /* Sometimes (when current token close to expire?) ACE challenges for the next token displayed (entered without the PIN) */ if (pass != NULL) { memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass)); free(pass); } pass = auth_getpass("\ !!! ATTENTION !!!\n\ Wait for the token code to change, \n\ then enter the new token code.\n", \ SUDO_CONV_PROMPT_ECHO_OFF, callback); if (SD_Next(*sd, pass) == ACM_OK) { ret = AUTH_SUCCESS; break; } ret = AUTH_FAILURE; break; case ACM_NEW_PIN_REQUIRED: /* * This user's SecurID has not been activated yet, * or the pin has been reset */ /* XXX - Is setting up a new PIN within sudo's scope? */ SD_Pin(*sd, ""); sudo_printf(SUDO_CONV_ERROR_MSG, "Your SecurID access has not yet been set up.\n"); sudo_printf(SUDO_CONV_ERROR_MSG, "Please set up a PIN before you try to authenticate.\n"); ret = AUTH_FATAL; break; default: sudo_warnx(U_("unknown SecurID error")); ret = AUTH_FATAL; break; } /* Free resources */ SD_Close(*sd); if (pass != NULL) { memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass)); free(pass); } /* Return stored state to calling process */ debug_return_int(ret); }