Ejemplo n.º 1
0
/*
 * 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);
}
Ejemplo n.º 2
0
Archivo: sudo_auth.c Proyecto: CVi/sudo
int
verify_user(struct passwd *pw, char *prompt)
{
    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;
    }

    /* Make sure we haven't mixed standalone and shared auth methods. */
    standalone = IS_STANDALONE(&auth_switch[0]);
    if (standalone && auth_switch[1].name != NULL) {
	audit_failure(NewArgv, "invalid authentication methods");
    	log_error(0, _("Invalid authentication methods compiled into sudo!  "
	    "You may mix standalone and non-standalone authentication."));
	return -1;
    }

    /* Set FLAG_ONEANDONLY if there is only one auth method. */
    if (auth_switch[1].name == NULL)
	SET(auth_switch[0].flags, FLAG_ONEANDONLY);

    /* Initialize auth methods and unconfigure the method if necessary. */
    for (auth = auth_switch; auth->name; auth++) {
	if (auth->init && !IS_DISABLED(auth)) {
	    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 */
		audit_failure(NewArgv, "authentication failure");
		return -1;		/* assume error msg already printed */
	    }

	    if (NEEDS_USER(auth))
		restore_perms();
	}
    }

    while (--counter) {
	/* Do any per-method setup and unconfigure the method if needed */
	for (auth = auth_switch; auth->name; auth++) {
	    if (auth->setup && !IS_DISABLED(auth)) {
		if (NEEDS_USER(auth))
		    set_perms(PERM_USER);

		status = (auth->setup)(pw, &prompt, auth);
		if (status == AUTH_FAILURE)
		    SET(auth->flags, FLAG_DISABLED);
		else if (status == AUTH_FATAL) {/* XXX log */
		    audit_failure(NewArgv, "authentication failure");
		    return -1;		/* assume error msg already printed */
		}

		if (NEEDS_USER(auth))
		    restore_perms();
	    }
	}

	/* Get the password unless the auth function will do it for us */
	if (standalone) {
	    p = prompt;
	} else {
	    p = auth_getpass(prompt, def_passwd_timeout * 60,
		SUDO_CONV_PROMPT_ECHO_OFF);
	    if (p == NULL)
		break;
	}

	/* Call authentication functions. */
	for (auth = auth_switch; auth->name; auth++) {
	    if (IS_DISABLED(auth))
		continue;

	    if (NEEDS_USER(auth))
		set_perms(PERM_USER);

	    success = auth->status = (auth->verify)(pw, p, auth);

	    if (NEEDS_USER(auth))
		restore_perms();

	    if (auth->status != AUTH_FAILURE)
		goto cleanup;
	}
	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();
	}
    }

    switch (success) {
	case AUTH_SUCCESS:
	    (void) sigaction(SIGTSTP, &osa, NULL);
	    rval = TRUE;
	    break;
	case AUTH_INTR:
	case AUTH_FAILURE:
	    if (counter != def_passwd_tries) {
		if (def_mail_badpass || def_mail_always)
		    flags = 0;
		else
		    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;
	case AUTH_FATAL:
	default:
	    audit_failure(NewArgv, "authentication failure");
	    rval = -1;
	    break;
    }

    return rval;
}