コード例 #1
0
ファイル: passverify.c プロジェクト: GNA-SERVICES-INC/MoNGate
int
helper_verify_password(const char *name, const char *p, int nullok)
{
	struct passwd *pwd = NULL;
	char *salt = NULL;
	int retval;

	retval = get_pwd_hash(name, &pwd, &salt);

	if (pwd == NULL || salt == NULL) {
		helper_log_err(LOG_WARNING, "check pass; user unknown");
		retval = PAM_USER_UNKNOWN;
	} else {
		retval = verify_pwd_hash(p, salt, nullok);
	}

	if (salt) {
		_pam_overwrite(salt);
		_pam_drop(salt);
	}

	p = NULL;		/* no longer needed here */

	return retval;
}
コード例 #2
0
static int _audit_log(int type, const char *uname, int rc)
{
    int audit_fd;

    audit_fd = audit_open();
    if (audit_fd < 0) {
        /* You get these error codes only when the kernel doesn't have
         * audit compiled in. */
        if (errno == EINVAL || errno == EPROTONOSUPPORT ||
                errno == EAFNOSUPPORT)
            return PAM_SUCCESS;

        helper_log_err(LOG_CRIT, "audit_open() failed: %m");
        return PAM_AUTH_ERR;
    }

    rc = audit_log_acct_message(audit_fd, type, NULL, "PAM:unix_chkpwd",
                                uname, -1, NULL, NULL, NULL, rc == PAM_SUCCESS);
    if (rc == -EPERM && geteuid() != 0) {
        rc = 0;
    }

    audit_close(audit_fd);

    return rc < 0 ? PAM_AUTH_ERR : PAM_SUCCESS;
}
コード例 #3
0
ファイル: unix_update.c プロジェクト: Distrotech/Linux-PAM
int main(int argc, char *argv[])
{
	char *option;

	/*
	 * Catch or ignore as many signal as possible.
	 */
	setup_signals();

	/*
	 * we establish that this program is running with non-tty stdin.
	 * this is to discourage casual use. It does *NOT* prevent an
	 * intruder from repeatadly running this program to determine the
	 * password of the current user (brute force attack, but one for
	 * which the attacker must already have gained access to the user's
	 * account).
	 */

	if (isatty(STDIN_FILENO) || argc != 5 ) {
		helper_log_err(LOG_NOTICE
		      ,"inappropriate use of Unix helper binary [UID=%d]"
			 ,getuid());
		fprintf(stderr
		 ,"This binary is not designed for running in this way\n"
		      "-- the system administrator has been informed\n");
		sleep(10);	/* this should discourage/annoy the user */
		return PAM_SYSTEM_ERR;
	}

	/* We must be root to read/update shadow.
	 */
	if (geteuid() != 0) {
	    return PAM_CRED_INSUFFICIENT;
	}

	option = argv[2];

	if (strcmp(option, "update") == 0) {
	    /* Attempting to change the password */
	    return set_password(argv[1], argv[3], argv[4]);
	}

	return PAM_SYSTEM_ERR;
}
コード例 #4
0
static int _check_expiry(const char *uname)
{
    struct spwd *spent;
    struct passwd *pwent;
    int retval;
    int daysleft;

    retval = get_account_info(uname, &pwent, &spent);
    if (retval != PAM_SUCCESS) {
        helper_log_err(LOG_ALERT, "could not obtain user info (%s)", uname);
        printf("-1\n");
        return retval;
    }

    if (spent == NULL) {
        printf("-1\n");
        return retval;
    }

    retval = check_shadow_expiry(spent, &daysleft);
    printf("%d\n", daysleft);
    return retval;
}
コード例 #5
0
ファイル: unix_update.c プロジェクト: Distrotech/Linux-PAM
static int
set_password(const char *forwho, const char *shadow, const char *remember)
{
    struct passwd *pwd = NULL;
    int retval;
    char pass[MAXPASS + 1];
    char towhat[MAXPASS + 1];
    int npass = 0;
    /* we don't care about number format errors because the helper
       should be called internally only */
    int doshadow = atoi(shadow);
    int nremember = atoi(remember);
    char *passwords[] = { pass, towhat };

    /* read the password from stdin (a pipe from the pam_unix module) */

    npass = read_passwords(STDIN_FILENO, 2, passwords);

    if (npass != 2) {	/* is it a valid password? */
      if (npass == 1) {
        helper_log_err(LOG_DEBUG, "no new password supplied");
	memset(pass, '\0', MAXPASS);
      } else {
        helper_log_err(LOG_DEBUG, "no valid passwords supplied");
      }
      return PAM_AUTHTOK_ERR;
    }

    if (lock_pwdf() != PAM_SUCCESS)
	return PAM_AUTHTOK_LOCK_BUSY;

    pwd = getpwnam(forwho);

    if (pwd == NULL) {
        retval = PAM_USER_UNKNOWN;
        goto done;
    }

    /* If real caller uid is not root we must verify that
       received old pass agrees with the current one.
       We always allow change from null pass. */
    if (getuid()) {
	retval = helper_verify_password(forwho, pass, 1);
	if (retval != PAM_SUCCESS) {
	    goto done;
	}
    }

    /* first, save old password */
    if (save_old_password(forwho, pass, nremember)) {
	retval = PAM_AUTHTOK_ERR;
	goto done;
    }

    if (doshadow || is_pwd_shadowed(pwd)) {
	retval = unix_update_shadow(forwho, towhat);
	if (retval == PAM_SUCCESS)
	    if (!is_pwd_shadowed(pwd))
		retval = unix_update_passwd(forwho, "x");
    } else {
	retval = unix_update_passwd(forwho, towhat);
    }

done:
    memset(pass, '\0', MAXPASS);
    memset(towhat, '\0', MAXPASS);

    unlock_pwdf();

    if (retval == PAM_SUCCESS) {
	return PAM_SUCCESS;
    } else {
	return PAM_AUTHTOK_ERR;
    }
}
コード例 #6
0
int main(int argc, char *argv[])
{
    char pass[MAXPASS + 1];
    char *option;
    int npass, nullok;
    int blankpass = 0;
    int retval = PAM_AUTH_ERR;
    char *user;
    char *passwords[] = { pass };

    /*
     * Catch or ignore as many signal as possible.
     */
    setup_signals();

    /*
     * we establish that this program is running with non-tty stdin.
     * this is to discourage casual use. It does *NOT* prevent an
     * intruder from repeatadly running this program to determine the
     * password of the current user (brute force attack, but one for
     * which the attacker must already have gained access to the user's
     * account).
     */

    if (isatty(STDIN_FILENO) || argc != 3 ) {
        helper_log_err(LOG_NOTICE
                       ,"inappropriate use of Unix helper binary [UID=%d]"
                       ,getuid());
#ifdef HAVE_LIBAUDIT
        _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR);
#endif
        fprintf(stderr
                ,"This binary is not designed for running in this way\n"
                "-- the system administrator has been informed\n");
        sleep(10);	/* this should discourage/annoy the user */
        return PAM_SYSTEM_ERR;
    }

    /*
     * Determine what the current user's name is.
     * We must thus skip the check if the real uid is 0.
     */
    if (getuid() == 0) {
        user=argv[1];
    }
    else {
        user = getuidname(getuid());
        /* if the caller specifies the username, verify that user
           matches it */
        if (strcmp(user, argv[1])) {
            user = argv[1];
            /* no match -> permanently change to the real user and proceed */
            if (setuid(getuid()) != 0)
                return PAM_AUTH_ERR;
        }
    }

    option=argv[2];

    if (strcmp(option, "chkexpiry") == 0)
        /* Check account information from the shadow file */
        return _check_expiry(argv[1]);
    /* read the nullok/nonull option */
    else if (strcmp(option, "nullok") == 0)
        nullok = 1;
    else if (strcmp(option, "nonull") == 0)
        nullok = 0;
    else {
#ifdef HAVE_LIBAUDIT
        _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR);
#endif
        return PAM_SYSTEM_ERR;
    }
    /* read the password from stdin (a pipe from the pam_unix module) */

    npass = read_passwords(STDIN_FILENO, 1, passwords);

    if (npass != 1) {	/* is it a valid password? */
        helper_log_err(LOG_DEBUG, "no password supplied");
        *pass = '******';
    }

    if (*pass == '\0') {
        blankpass = 1;
    }

    retval = helper_verify_password(user, pass, nullok);

    memset(pass, '\0', MAXPASS);	/* clear memory of the password */

    /* return pass or fail */

    if (retval != PAM_SUCCESS) {
        if (!nullok || !blankpass) {
            /* no need to log blank pass test */
#ifdef HAVE_LIBAUDIT
            if (getuid() != 0)
                _audit_log(AUDIT_USER_AUTH, user, PAM_AUTH_ERR);
#endif
            helper_log_err(LOG_NOTICE, "password check failed for user (%s)", user);
        }
        return PAM_AUTH_ERR;
    } else {
        if (getuid() != 0) {
#ifdef HAVE_LIBAUDIT
            return _audit_log(AUDIT_USER_AUTH, user, PAM_SUCCESS);
#else
            return PAM_SUCCESS;
#endif
        }
        return PAM_SUCCESS;
    }
}