Esempio n. 1
0
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);
}
Esempio n. 2
0
static enum passdb_result
auth_worker_reply_parse(struct auth_request *request, const char *reply)
{
	enum passdb_result ret;
	const char *const *args;

	args = t_strsplit_tabescaped(reply);

	if (strcmp(*args, "OK") == 0 && args[1] != NULL && args[2] != NULL) {
		/* OK \t user \t password [\t extra] */
		auth_request_set_field(request, "user", args[1], NULL);
		auth_worker_reply_parse_args(request, args + 2);
		return PASSDB_RESULT_OK;
	}

	if (strcmp(*args, "NEXT") == 0 && args[1] != NULL) {
		/* NEXT \t user [\t extra] */
		auth_request_set_field(request, "user", args[1], NULL);
		auth_worker_reply_parse_args(request, args + 1);
		return PASSDB_RESULT_NEXT;
	}

	if (strcmp(*args, "FAIL") == 0 && args[1] != NULL) {
		int result;
		/* FAIL \t result [\t user \t password [\t extra]] */
		if (str_to_int(args[1], &result) < 0) {
			/* shouldn't happen */
		} else {
			ret = (enum passdb_result)result;
			if (ret == PASSDB_RESULT_OK) {
				/* shouldn't happen */
			} else if (args[2] == NULL) {
				/* internal failure most likely */
				return ret;
			} else if (args[3] != NULL) {
				if (*args[2] != '\0') {
					auth_request_set_field(request, "user",
							       args[2], NULL);
				}
				auth_worker_reply_parse_args(request, args + 3);
				return ret;
			}
		}
	}

	auth_request_log_error(request, AUTH_SUBSYS_DB,
		"Received invalid reply from worker: %s", reply);
	return PASSDB_RESULT_INTERNAL_FAILURE;
}
Esempio n. 3
0
static enum passdb_result
passwd_lookup(struct auth_request *request, struct passwd *pw_r)
{
	auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup");

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

	if (!IS_VALID_PASSWD(pw_r->pw_passwd)) {
		auth_request_log_info(request, AUTH_SUBSYS_DB,
			"invalid password field '%s'", pw_r->pw_passwd);
		return PASSDB_RESULT_USER_DISABLED;
	}

	/* save the password so cache can use it */
	auth_request_set_field(request, "password", pw_r->pw_passwd,
			       PASSWD_PASS_SCHEME);
	return PASSDB_RESULT_OK;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
static void
ldap_query_save_result(struct ldap_connection *conn,
		       struct auth_request *auth_request,
		       struct ldap_request_search *ldap_request,
		       LDAPMessage *res)
{
	struct db_ldap_result_iterate_context *ldap_iter;
	const char *name, *const *values;

	ldap_iter = db_ldap_result_iterate_init(conn, ldap_request, res, FALSE);
	while (db_ldap_result_iterate_next(ldap_iter, &name, &values)) {
		if (values[0] == NULL) {
			auth_request_set_null_field(auth_request, name);
			continue;
		}
		if (values[1] != NULL) {
			auth_request_log_warning(auth_request, AUTH_SUBSYS_DB,
				"Multiple values found for '%s', "
				"using value '%s'", name, values[0]);
		}
		auth_request_set_field(auth_request, name, values[0],
				       conn->set.default_pass_scheme);
	}
	db_ldap_result_iterate_deinit(&ldap_iter);
}
void passdb_template_export(struct passdb_template *tmpl,
			    struct auth_request *auth_request)
{
        const struct var_expand_table *table;
	string_t *str;
	const char *const *args, *value;
	unsigned int i, count;

	str = t_str_new(256);
	table = auth_request_get_var_expand_table(auth_request, NULL);

	args = array_get(&tmpl->args, &count);
	i_assert((count % 2) == 0);
	for (i = 0; i < count; i += 2) {
		if (args[i+1] == NULL)
			value = "";
		else {
			str_truncate(str, 0);
			var_expand(str, args[i+1], table);
			value = str_c(str);
		}
		auth_request_set_field(auth_request, args[i], value,
				       STATIC_PASS_SCHEME);
	}
}
Esempio n. 7
0
static void
userdb_nss_lookup(struct auth_request *auth_request,
		  userdb_callback_t *callback)
{
	struct userdb_module *_module = auth_request->userdb->userdb;
	struct nss_userdb_module *module = (struct nss_userdb_module *)_module;
	struct passwd pw;
	enum nss_status status;
	enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE;
	int err;

	auth_request_log_debug(auth_request, "nss", "lookup");

	status = module->getpwnam_r(auth_request->user, &pw,
				    module->buf, module->bufsize, &err);
	switch (status) {
	case NSS_STATUS_TRYAGAIN:
		auth_request_log_error(auth_request, "nss",
				       "returned tryagain (err=%d)", err);
		break;
	case NSS_STATUS_UNAVAIL:
		auth_request_log_error(auth_request, "nss",
				       "unavailable (err=%d)", err);
		break;
	case NSS_STATUS_NOTFOUND:
		auth_request_log_info(auth_request, "nss", "unknown user");
		result = USERDB_RESULT_USER_UNKNOWN;
		break;
	case NSS_STATUS_SUCCESS:
		result = USERDB_RESULT_OK;
		break;
	default:
		auth_request_log_info(auth_request, "nss",
				      "returned %d (err=%d)", status, err);
		break;
	}

	if (result != USERDB_RESULT_OK) {
		callback(result, auth_request);
		return;
	}

	auth_request_set_field(auth_request, "user", pw.pw_name, NULL);

	auth_request_init_userdb_reply(auth_request);
	auth_request_set_userdb_field(auth_request, "system_groups_user",
				      pw.pw_name);
	auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
	auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
	auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);

	callback(USERDB_RESULT_OK, auth_request);
}
Esempio n. 8
0
static void passwd_file_save_results(struct auth_request *request,
                                     const struct passwd_user *pu,
                                     const char **crypted_pass_r,
                                     const char **scheme_r)
{
    const struct var_expand_table *table;
    const char *key, *value;
    string_t *str;
    char **p;

    *crypted_pass_r = pu->password != NULL ? pu->password : "";
    *scheme_r = password_get_scheme(crypted_pass_r);
    if (*scheme_r == NULL)
        *scheme_r = request->passdb->passdb->default_pass_scheme;

    /* save the password so cache can use it */
    auth_request_set_field(request, "password",
                           *crypted_pass_r, *scheme_r);

    if (pu->extra_fields != NULL) {
        str = t_str_new(512);
        table = auth_request_get_var_expand_table(request, NULL);

        for (p = pu->extra_fields; *p != NULL; p++) {
            value = strchr(*p, '=');
            if (value != NULL) {
                key = t_strdup_until(*p, value);
                str_truncate(str, 0);
                auth_request_var_expand_with_table(str, value + 1,
                                                   request, table, NULL);
                value = str_c(str);
            } else {
                key = *p;
                value = "";
            }
            auth_request_set_field(request, key, value, NULL);
        }
    }
}
Esempio n. 9
0
static void
ldap_query_save_result(struct ldap_connection *conn,
		       LDAPMessage *entry, struct auth_request *auth_request)
{
	struct db_ldap_result_iterate_context *ldap_iter;
	const char *name, *value;

	ldap_iter = db_ldap_result_iterate_init(conn, entry, auth_request,
						conn->pass_attr_map);
	while (db_ldap_result_iterate_next(ldap_iter, &name, &value)) {
		auth_request_set_field(auth_request, name, value,
				       conn->set.default_pass_scheme);
	}
}
Esempio n. 10
0
static void
passwd_lookup_credentials(struct auth_request *request,
			  lookup_credentials_callback_t *callback)
{
	struct passwd pw;
	enum passdb_result res;

	res = passwd_lookup(request, &pw);
	if (res != PASSDB_RESULT_OK) {
		callback(res, NULL, 0, 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);
	passdb_handle_credentials(PASSDB_RESULT_OK, pw.pw_passwd,
				  PASSWD_PASS_SCHEME, callback, request);
}
Esempio n. 11
0
static enum passdb_result
static_save_fields(struct auth_request *request, const char **password_r,
		   const char **scheme_r)
{
	struct static_passdb_module *module =
		(struct static_passdb_module *)request->passdb->passdb;
	const char *error;

	*password_r = NULL;
	*scheme_r = NULL;

	auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup");
	if (passdb_template_export(module->tmpl, request, &error) < 0) {
		auth_request_log_error(request, AUTH_SUBSYS_DB,
			"Failed to expand template: %s", error);
		return PASSDB_RESULT_INTERNAL_FAILURE;
	}

	if (module->static_password_tmpl != NULL) {
		if (t_auth_request_var_expand(module->static_password_tmpl,
				request, NULL, password_r, &error) <= 0) {
			auth_request_log_error(request, AUTH_SUBSYS_DB,
				"Failed to expand password=%s: %s",
				module->static_password_tmpl, error);
			return PASSDB_RESULT_INTERNAL_FAILURE;
		}
	} else if (auth_fields_exists(request->extra_fields, "nopassword")) {
		*password_r = "";
	} else {
		auth_request_log_info(request, AUTH_SUBSYS_DB,
			"No password returned (and no nopassword)");
		return PASSDB_RESULT_PASSWORD_MISMATCH;
	}

	*scheme_r = password_get_scheme(password_r);

	if (*scheme_r == NULL)
		*scheme_r = STATIC_PASS_SCHEME;

	auth_request_set_field(request, "password",
			       *password_r, *scheme_r);

	return PASSDB_RESULT_OK;
}
Esempio n. 12
0
static int
dict_query_save_results(struct auth_request *auth_request,
                        struct dict_connection *conn,
                        struct db_dict_value_iter *iter)
{
    const char *key, *value, *error;

    while (db_dict_value_iter_next(iter, &key, &value)) {
        if (value != NULL) {
            auth_request_set_field(auth_request, key, value,
                                   conn->set.default_pass_scheme);
        }
    }
    if (db_dict_value_iter_deinit(&iter, &error) < 0) {
        auth_request_log_error(auth_request, AUTH_SUBSYS_DB, "%s", error);
        return -1;
    }
    return 0;
}
Esempio n. 13
0
static void passwd_lookup(struct auth_request *auth_request,
			  userdb_callback_t *callback)
{
	struct userdb_module *_module = auth_request->userdb->userdb;
	struct passwd_userdb_module *module =
		(struct passwd_userdb_module *)_module;
	struct passwd pw;
	struct timeval start_tv;
	int ret;

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

	if (gettimeofday(&start_tv, NULL) < 0)
		start_tv.tv_sec = 0;
	ret = i_getpwnam(auth_request->user, &pw);
	if (start_tv.tv_sec != 0)
		passwd_check_warnings(auth_request, module, &start_tv);

	switch (ret) {
	case -1:
		auth_request_log_error(auth_request, "passwd",
				       "getpwnam() failed: %m");
		callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
		return;
	case 0:
		auth_request_log_info(auth_request, "passwd", "unknown user");
		callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
		return;
	}

	auth_request_set_field(auth_request, "user", pw.pw_name, NULL);

	auth_request_init_userdb_reply(auth_request);
	auth_request_set_userdb_field(auth_request, "system_groups_user",
				      pw.pw_name);
	auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
	auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
	auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);

	userdb_template_export(module->tmpl, auth_request);

	callback(USERDB_RESULT_OK, auth_request);
}
Esempio n. 14
0
static void
bsdauth_verify_plain(struct auth_request *request, const char *password,
		    verify_plain_callback_t *callback)
{
	struct passwd pw;
	const char *type;
	int result;

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

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

	/* check if the password is valid */
	type = t_strdup_printf("auth-%s", request->service);
	result = auth_userokay(request->user, NULL, t_strdup_noconst(type),
			       t_strdup_noconst(password));

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

	if (result == 0) {
		auth_request_log_password_mismatch(request, "bsdauth");
		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);
}
Esempio n. 15
0
static void
auth_checkpassword_callback(struct auth_request *request,
			    enum db_checkpassword_status status,
			    const char *const *extra_fields,
			    verify_plain_callback_t *callback)
{
	const char *scheme, *crypted_pass = NULL;
	unsigned int i;

	switch (status) {
	case DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE:
		callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
		return;
	case DB_CHECKPASSWORD_STATUS_FAILURE:
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	case DB_CHECKPASSWORD_STATUS_OK:
		break;
	}
	for (i = 0; extra_fields[i] != NULL; i++) {
		if (strncmp(extra_fields[i], "password="******"password",
					       crypted_pass, scheme);
		} else {
			auth_request_log_error(request, AUTH_SUBSYS_DB,
				"password field returned without {scheme} prefix");
		}
	}
	callback(PASSDB_RESULT_OK, request);
}
Esempio n. 16
0
static int
dict_query_save_results(struct auth_request *auth_request,
			struct dict_connection *conn, const char *result)
{
	struct db_dict_value_iter *iter;
	const char *key, *value, *error;

	iter = db_dict_value_iter_init(conn, result);
	while (db_dict_value_iter_next(iter, &key, &value)) {
		if (value != NULL) {
			auth_request_set_field(auth_request, key, value,
					       conn->set.default_pass_scheme);
		}
	}
	if (db_dict_value_iter_deinit(&iter, &error) < 0) {
		auth_request_log_error(auth_request, "dict",
			"Value '%s' not in valid %s format: %s",
			result, conn->set.value_format, error);
		return -1;
	}
	return 0;
}
Esempio n. 17
0
static void sql_query_save_results(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;
	unsigned int i, fields_count;
	const char *name, *value;

        fields_count = sql_result_get_fields_count(result);
	for (i = 0; i < fields_count; i++) {
		name = sql_result_get_field_name(result, i);
		value = sql_result_get_field_value(result, i);

		if (*name == '\0')
			;
		else if (value == NULL)
			auth_request_set_null_field(auth_request, name);
		else {
			auth_request_set_field(auth_request, name, value,
				module->conn->set.default_pass_scheme);
		}
	}
}