コード例 #1
0
static void
passwd_file_verify_plain(struct auth_request *request, const char *password,
			 verify_plain_callback_t *callback)
{
	struct passdb_module *_module = request->passdb->passdb;
	struct passwd_file_passdb_module *module =
		(struct passwd_file_passdb_module *)_module;
	struct passwd_user *pu;
	const char *scheme, *crypted_pass;
        int ret;

	pu = db_passwd_file_lookup(module->pwf, request,
				   module->username_format);
	if (pu == NULL) {
		callback(PASSDB_RESULT_USER_UNKNOWN, request);
		return;
	}

	passwd_file_save_results(request, pu, &crypted_pass, &scheme);

	ret = auth_request_password_verify(request, password, crypted_pass,
					   scheme, AUTH_SUBSYS_DB);

	callback(ret > 0 ? PASSDB_RESULT_OK : PASSDB_RESULT_PASSWORD_MISMATCH,
		 request);
}
コード例 #2
0
ファイル: passdb-static.c プロジェクト: bdraco/core
static void
static_verify_plain(struct auth_request *request, const char *password,
		    verify_plain_callback_t *callback)
{
	enum passdb_result result;
	const char *static_password;
	const char *static_scheme;

	int ret;

	result = static_save_fields(request, &static_password, &static_scheme);
	if (result != PASSDB_RESULT_OK) {
		callback(result, request);
		return;
	}

	ret = auth_request_password_verify(request, password, static_password,
					   static_scheme, AUTH_SUBSYS_DB);
	if (ret <= 0) {
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	}

	callback(PASSDB_RESULT_OK, request);
}
コード例 #3
0
ファイル: passdb-passwd.c プロジェクト: jfsmig/dovecot-core
static void
passwd_verify_plain(struct auth_request *request, const char *password,
		    verify_plain_callback_t *callback)
{
	struct passwd pw;
	enum passdb_result res;
	int ret;

	res = passwd_lookup(request, &pw);
	if (res != PASSDB_RESULT_OK) {
		callback(res, request);
		return;
	}
	/* check if the password is valid */
	ret = auth_request_password_verify(request, password, pw.pw_passwd,
					   PASSWD_PASS_SCHEME, AUTH_SUBSYS_DB);

	/* clear the passwords from memory */
	safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd));

	if (ret <= 0) {
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	}

	/* make sure we're using the username exactly as it's in the database */
        auth_request_set_field(request, "user", pw.pw_name, NULL);

	callback(PASSDB_RESULT_OK, request);
}
コード例 #4
0
ファイル: passdb-cache.c プロジェクト: jraimundo/core
bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
			       const char *password,
			       enum passdb_result *result_r, bool use_expired)
{
	const char *value, *cached_pw, *scheme, *const *list;
	struct auth_cache_node *node;
	int ret;
	bool neg_expired;

	if (passdb_cache == NULL || key == NULL)
		return FALSE;

	if (!passdb_cache_lookup(request, key, use_expired,
				 &node, &value, &neg_expired))
		return FALSE;

	if (*value == '\0') {
		/* negative cache entry */
		auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
		*result_r = PASSDB_RESULT_USER_UNKNOWN;
		return TRUE;
	}

	list = t_strsplit_tab(value);

	cached_pw = list[0];
	if (*cached_pw == '\0') {
		/* NULL password */
		auth_request_log_info(request, AUTH_SUBSYS_DB,
				      "Cached NULL password access");
		ret = 1;
	} else {
		scheme = password_get_scheme(&cached_pw);
		i_assert(scheme != NULL);

		ret = auth_request_password_verify(request, password, cached_pw,
						   scheme, AUTH_SUBSYS_DB);

		if (ret == 0 && (node->last_success || neg_expired)) {
			/* a) the last authentication was successful. assume
			   that the password was changed and cache is expired.
			   b) negative TTL reached, use it for password
			   mismatches too. */
			node->last_success = FALSE;
			return FALSE;
		}
	}
	node->last_success = ret > 0;

	/* save the extra_fields only after we know we're using the
	   cached data */
	auth_request_set_fields(request, list + 1, NULL);

	*result_r = ret > 0 ? PASSDB_RESULT_OK :
		PASSDB_RESULT_PASSWORD_MISMATCH;
	return TRUE;
}
コード例 #5
0
ファイル: passdb-vpopmail.c プロジェクト: IvanKharpalev/core
static void
vpopmail_verify_plain(struct auth_request *request, const char *password,
		      verify_plain_callback_t *callback)
{
	enum passdb_result result;
	const char *scheme, *tmp_pass;
	char *crypted_pass;
	bool cleartext = FALSE;
	int ret;

	crypted_pass = vpopmail_password_lookup(request, &cleartext, &result);
	if (crypted_pass == NULL) {
		callback(result, request);
		return;
	}
	tmp_pass = crypted_pass;

	if (cleartext)
		scheme = "CLEARTEXT";
	else {
		scheme = password_get_scheme(&tmp_pass);
		if (scheme == NULL)
			scheme = request->passdb->passdb->default_pass_scheme;
	}

	ret = auth_request_password_verify(request, password, tmp_pass,
					   scheme, AUTH_SUBSYS_DB);
	safe_memset(crypted_pass, 0, strlen(crypted_pass));

	if (ret <= 0) {
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	}

#ifdef POP_AUTH_OPEN_RELAY
	if (strcasecmp(request->service, "POP3") == 0 ||
	    strcasecmp(request->service, "IMAP") == 0) {
		const char *host = net_ip2addr(&request->remote_ip);
		/* vpopmail 5.4 does not understand IPv6 */
		if (host[0] != '\0' && IPADDR_IS_V4(&request->remote_ip)) {
			/* use putenv() directly rather than env_put() which
			   would leak memory every time we got here. use a
			   static buffer for putenv() as SUSv2 requirements
			   would otherwise corrupt our environment later. */
			static char ip_env[256];

			i_snprintf(ip_env, sizeof(ip_env),
				   "TCPREMOTEIP=%s", host);
			putenv(ip_env);
			open_smtp_relay();
		}
	}
#endif

	callback(PASSDB_RESULT_OK, request);
}
コード例 #6
0
ファイル: passdb-ldap.c プロジェクト: Distrotech/dovecot
static void
ldap_lookup_finish(struct auth_request *auth_request,
		   struct passdb_ldap_request *ldap_request,
		   LDAPMessage *res)
{
	enum passdb_result passdb_result;
	const char *password = NULL, *scheme;
	int ret;

	if (res == NULL) {
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	} else if (ldap_request->entries == 0) {
		passdb_result = PASSDB_RESULT_USER_UNKNOWN;
		auth_request_log_info(auth_request, "ldap",
				      "unknown user");
	} else if (ldap_request->entries > 1) {
		auth_request_log_error(auth_request, "ldap",
			"pass_filter matched multiple objects, aborting");
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	} else if (auth_request->passdb_password == NULL &&
		   !auth_fields_exists(auth_request->extra_fields, "nopassword")) {
		auth_request_log_info(auth_request, "ldap",
			"No password returned (and no nopassword)");
		passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
	} else {
		/* passdb_password may change on the way,
		   so we'll need to strdup. */
		password = t_strdup(auth_request->passdb_password);
		passdb_result = PASSDB_RESULT_OK;
	}

	scheme = password_get_scheme(&password);
	/* auth_request_set_field() sets scheme */
	i_assert(password == NULL || scheme != NULL);

	if (auth_request->credentials_scheme != NULL) {
		passdb_handle_credentials(passdb_result, password, scheme,
			ldap_request->callback.lookup_credentials,
			auth_request);
	} else {
		if (password != NULL) {
			ret = auth_request_password_verify(auth_request,
					auth_request->mech_password,
					password, scheme, "ldap");
			passdb_result = ret > 0 ? PASSDB_RESULT_OK :
				PASSDB_RESULT_PASSWORD_MISMATCH;
		}

		ldap_request->callback.verify_plain(passdb_result,
						    auth_request);
	}
}
コード例 #7
0
ファイル: passdb-dict.c プロジェクト: damoxc/dovecot
static void passdb_dict_lookup_pass(struct passdb_dict_request *dict_request)
{
	struct auth_request *auth_request = dict_request->auth_request;
	struct passdb_module *_module = auth_request->passdb->passdb;
	struct dict_passdb_module *module =
		(struct dict_passdb_module *)_module;
	string_t *key;
	const char *password = NULL, *scheme = NULL;
	enum passdb_result passdb_result;
	int ret;

	key = t_str_new(512);
	str_append(key, DICT_PATH_SHARED);
	var_expand(key, module->conn->set.password_key,
		   auth_request_get_var_expand_table(auth_request, NULL));

	if (*module->conn->set.password_key == '\0') {
		auth_request_log_error(auth_request, "dict",
				       "password_key not specified");
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	} else {
		passdb_result = passdb_dict_lookup_key(auth_request, module,
						       str_c(key));
	}

	if (passdb_result == PASSDB_RESULT_OK) {
		/* passdb_password may change on the way,
		   so we'll need to strdup. */
		password = t_strdup(auth_request->passdb_password);
		scheme = password_get_scheme(&password);
		/* auth_request_set_field() sets scheme */
		i_assert(password == NULL || scheme != NULL);
	}

	if (auth_request->credentials_scheme != NULL) {
		passdb_handle_credentials(passdb_result, password, scheme,
			dict_request->callback.lookup_credentials,
			auth_request);
	} else {
		if (password != NULL) {
			ret = auth_request_password_verify(auth_request,
					auth_request->mech_password,
					password, scheme, "dict");
			passdb_result = ret > 0 ? PASSDB_RESULT_OK :
				PASSDB_RESULT_PASSWORD_MISMATCH;
		}

		dict_request->callback.verify_plain(passdb_result,
						    auth_request);
	}
}
コード例 #8
0
ファイル: passdb-passwd.c プロジェクト: damoxc/dovecot
static void
passwd_verify_plain(struct auth_request *request, const char *password,
		    verify_plain_callback_t *callback)
{
	struct passwd pw;
	int ret;

	auth_request_log_debug(request, "passwd", "lookup");

	switch (i_getpwnam(request->user, &pw)) {
	case -1:
		auth_request_log_error(request, "passwd",
				       "getpwnam() failed: %m");
		callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
		return;
	case 0:
		auth_request_log_unknown_user(request, "passwd");
		callback(PASSDB_RESULT_USER_UNKNOWN, request);
		return;
	}

	if (!IS_VALID_PASSWD(pw.pw_passwd)) {
		auth_request_log_info(request, "passwd",
			"invalid password field '%s'", pw.pw_passwd);
		callback(PASSDB_RESULT_USER_DISABLED, request);
		return;
	}

	/* save the password so cache can use it */
	auth_request_set_field(request, "password", pw.pw_passwd,
			       PASSWD_PASS_SCHEME);

	/* check if the password is valid */
	ret = auth_request_password_verify(request, password, pw.pw_passwd,
					   PASSWD_PASS_SCHEME, "passwd");

	/* clear the passwords from memory */
	safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd));

	if (ret <= 0) {
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	}

	/* make sure we're using the username exactly as it's in the database */
        auth_request_set_field(request, "user", pw.pw_name, NULL);

	callback(PASSDB_RESULT_OK, request);
}
コード例 #9
0
ファイル: passdb-dict.c プロジェクト: apoikos/pkg-dovecot
static void passdb_dict_lookup_pass(struct passdb_dict_request *dict_request)
{
    struct auth_request *auth_request = dict_request->auth_request;
    struct passdb_module *_module = auth_request->passdb->passdb;
    struct dict_passdb_module *module =
        (struct dict_passdb_module *)_module;
    const char *password = NULL, *scheme = NULL;
    enum passdb_result passdb_result;
    int ret;

    if (array_count(&module->conn->set.passdb_fields) == 0 &&
            array_count(&module->conn->set.parsed_passdb_objects) == 0) {
        auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
                               "No passdb_objects or passdb_fields specified");
        passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
    } else {
        passdb_result = passdb_dict_lookup_key(auth_request, module);
    }

    if (passdb_result == PASSDB_RESULT_OK) {
        /* passdb_password may change on the way,
           so we'll need to strdup. */
        password = t_strdup(auth_request->passdb_password);
        scheme = password_get_scheme(&password);
        /* auth_request_set_field() sets scheme */
        i_assert(password == NULL || scheme != NULL);
    }

    if (auth_request->credentials_scheme != NULL) {
        passdb_handle_credentials(passdb_result, password, scheme,
                                  dict_request->callback.lookup_credentials,
                                  auth_request);
    } else {
        if (password != NULL) {
            ret = auth_request_password_verify(auth_request,
                                               auth_request->mech_password,
                                               password, scheme, AUTH_SUBSYS_DB);
            passdb_result = ret > 0 ? PASSDB_RESULT_OK :
                            PASSDB_RESULT_PASSWORD_MISMATCH;
        }

        dict_request->callback.verify_plain(passdb_result,
                                            auth_request);
    }
}
コード例 #10
0
ファイル: passdb-sql.c プロジェクト: rowhit/core-1
static void sql_query_callback(struct sql_result *result,
			       struct passdb_sql_request *sql_request)
{
	struct auth_request *auth_request = sql_request->auth_request;
	struct passdb_module *_module = auth_request->passdb->passdb;
	struct sql_passdb_module *module = (struct sql_passdb_module *)_module;
	enum passdb_result passdb_result;
	const char *password, *scheme;
	int ret;

	passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	password = NULL;

	ret = sql_result_next_row(result);
	if (ret >= 0)
		db_sql_success(module->conn);
	if (ret < 0) {
		if (!module->conn->default_password_query) {
			auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
					       "Password query failed: %s",
					       sql_result_get_error(result));
		} else {
			auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
				"Password query failed: %s "
				"(using built-in default password_query: %s)",
				sql_result_get_error(result),
				module->conn->set.password_query);
		}
	} else if (ret == 0) {
		auth_request_log_unknown_user(auth_request, AUTH_SUBSYS_DB);
		passdb_result = PASSDB_RESULT_USER_UNKNOWN;
	} else {
		sql_query_save_results(result, sql_request);

		/* Note that we really want to check if the password field is
		   found. Just checking if password is set isn't enough,
		   because with proxies we might want to return NULL as
		   password. */
		if (sql_result_find_field(result, "password") < 0 &&
		    sql_result_find_field(result, "password_noscheme") < 0) {
			auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
				"Password query must return a field named "
				"'password'");
		} else if (sql_result_next_row(result) > 0) {
			auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
				"Password query returned multiple matches");
		} else if (auth_request->passdb_password == NULL &&
			   !auth_fields_exists(auth_request->extra_fields, "nopassword") &&
			   !auth_fields_exists(auth_request->extra_fields, "noauthenticate")) {
			auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
				"Empty password returned without nopassword");
			passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
		} else {
			/* passdb_password may change on the way,
			   so we'll need to strdup. */
			password = t_strdup(auth_request->passdb_password);
			passdb_result = PASSDB_RESULT_OK;
		}
	}

	scheme = password_get_scheme(&password);
	/* auth_request_set_field() sets scheme */
	i_assert(password == NULL || scheme != NULL);

	if (auth_request->credentials_scheme != NULL) {
		passdb_handle_credentials(passdb_result, password, scheme,
			sql_request->callback.lookup_credentials,
			auth_request);
		auth_request_unref(&auth_request);
		return;
	}

	/* verify plain */
	if (password == NULL) {
		sql_request->callback.verify_plain(passdb_result, auth_request);
		auth_request_unref(&auth_request);
		return;
	}

	ret = auth_request_password_verify(auth_request,
					   auth_request->mech_password,
					   password, scheme, AUTH_SUBSYS_DB);

	sql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
					   PASSDB_RESULT_PASSWORD_MISMATCH,
					   auth_request);
	auth_request_unref(&auth_request);
}