event = event_create(request->event);
event_add_str(event, "userdb", request->userdb->name);
event_add_str(event, "userdb_id", dec2str(request->userdb->userdb->id));
- event_add_str(event, "userdb_driver", request->userdb->userdb->iface->name);
+ const char *userdb_driver = request->userdb->userdb->iface->name;
+ event_add_str(event, "userdb_driver", userdb_driver);
+ event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME,
+ p_strconcat(event_get_pool(event), "userdb_",
+ userdb_driver, NULL));
event_set_log_prefix_callback(event, FALSE,
auth_request_get_log_prefix_db, request);
return 0;
}
+int auth_request_set_userdb_default_fields(struct auth_request *request)
+{
+ struct event *event = authdb_event(request);
+ const struct auth_userdb_pre_settings *pre_set;
+ const char *error;
+
+ if (settings_get(event, &auth_userdb_pre_setting_parser_info, 0,
+ &pre_set, &error) < 0) {
+ e_error(event, "%s", error);
+ return -1;
+ }
+ auth_request_set_userdb_strlist(request, &pre_set->default_fields);
+ settings_free(pre_set);
+ return 0;
+}
+
+static int auth_request_set_userdb_override_fields(struct auth_request *request)
+{
+ struct event *event = authdb_event(request);
+ const struct auth_userdb_post_settings *post_set;
+ const char *error;
+
+ if (settings_get(event, &auth_userdb_post_setting_parser_info, 0,
+ &post_set, &error) < 0) {
+ e_error(event, "%s", error);
+ return -1;
+ }
+ auth_request_set_userdb_strlist(request, &post_set->override_fields);
+ settings_free(post_set);
+ return 0;
+}
+
static int
auth_request_finish_passdb_lookup(enum passdb_result *result,
struct auth_request *request,
struct auth_userdb *userdb = request->userdb;
struct auth_userdb *next_userdb;
enum auth_db_rule result_rule;
- const char *error;
bool userdb_continue = FALSE;
if (!request->userdb_lookup_tempfailed &&
if (result == USERDB_RESULT_OK) {
/* this userdb lookup succeeded, preserve its extra fields */
- if (userdb_template_export(userdb->override_fields_tmpl,
- request, &error) < 0) {
- e_error(authdb_event(request),
- "Failed to expand override_fields: %s", error);
+ if (auth_request_set_userdb_override_fields(request) < 0)
result = USERDB_RESULT_INTERNAL_FAILURE;
- } else {
+ else
auth_fields_snapshot(request->fields.userdb_reply);
- }
} else {
/* this userdb lookup failed, remove any extra fields
it set */
userdb_callback_t *callback)
{
struct auth_userdb *userdb = request->userdb;
- const char *cache_key, *error;
+ const char *cache_key;
request->private_callback.userdb = callback;
request->user_returned_by_lookup = FALSE;
request->userdb_cache_result = AUTH_REQUEST_CACHE_NONE;
if (request->fields.userdb_reply == NULL)
auth_request_init_userdb_reply(request);
+
+ auth_request_userdb_lookup_begin(request);
+
/* we still want to set default_fields. these override any
existing fields set by previous userdbs (because if that is
unwanted, ":protected" can be used). */
- if (userdb_template_export(userdb->default_fields_tmpl,
- request, &error) < 0) {
- e_error(authdb_event(request),
- "Failed to expand default_fields: %s", error);
+ if (auth_request_set_userdb_default_fields(request) < 0) {
auth_request_userdb_callback(
USERDB_RESULT_INTERNAL_FAILURE, request);
return;
}
- auth_request_userdb_lookup_begin(request);
-
/* (for now) auth_cache is shared between passdb and userdb */
cache_key = passdb_cache == NULL ? NULL : userdb->cache_key;
if (cache_key != NULL) {
}
}
+void auth_request_set_userdb_strlist(struct auth_request *request,
+ const ARRAY_TYPE(const_string) *strlist)
+{
+ if (!array_is_created(strlist))
+ return;
+
+ unsigned int i, count;
+ const char *const *fields = array_get(strlist, &count);
+ i_assert(count % 2 == 0);
+ for (i = 0; i < count; i += 2) {
+ auth_request_set_userdb_field(request, fields[i],
+ fields[i + 1]);
+ }
+}
+
static bool auth_request_proxy_is_self(struct auth_request *request)
{
const char *port = NULL;
void auth_request_set_userdb_field_values(struct auth_request *request,
const char *name,
const char *const *values);
+void auth_request_set_userdb_strlist(struct auth_request *request,
+ const ARRAY_TYPE(const_string) *strlist);
/* returns -1 = failed, 0 = callback is called later, 1 = finished */
int auth_request_proxy_finish(struct auth_request *request,
auth_request_proxy_cb_t *callback);
void auth_request_userdb_lookup_end(struct auth_request *request,
enum userdb_result result);
+int auth_request_set_userdb_default_fields(struct auth_request *request);
+
/* Fetches the current authdb event, this is done because
some lookups can recurse into new lookups, requiring new event,
which will be returned here. */
DEF(STR, name),
DEF(STR, driver),
DEF(STR_NOVARS, args),
- DEF(STR_NOVARS, default_fields),
- DEF(STR_NOVARS, override_fields),
DEF(ENUM, skip),
DEF(ENUM, result_success),
.name = "",
.driver = "",
.args = "",
- .default_fields = "",
- .override_fields = "",
.skip = "never:found:notfound",
.result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail",
.pool_offset1 = 1 + offsetof(struct auth_userdb_settings, pool),
};
+static const struct setting_define auth_userdb_pre_setting_defines[] = {
+ { .type = SET_STRLIST, .key = "userdb_default_fields",
+ .offset = offsetof(struct auth_userdb_pre_settings, default_fields) },
+
+ SETTING_DEFINE_LIST_END
+};
+
+static const struct auth_userdb_pre_settings auth_userdb_pre_default_settings = {
+ .default_fields = ARRAY_INIT,
+};
+
+const struct setting_parser_info auth_userdb_pre_setting_parser_info = {
+ .name = "auth_userdb_pre",
+
+ .defines = auth_userdb_pre_setting_defines,
+ .defaults = &auth_userdb_pre_default_settings,
+
+ .struct_size = sizeof(struct auth_userdb_pre_settings),
+ .pool_offset1 = 1 + offsetof(struct auth_userdb_pre_settings, pool),
+};
+
+static const struct setting_define auth_userdb_post_setting_defines[] = {
+ { .type = SET_STRLIST, .key = "userdb_override_fields",
+ .offset = offsetof(struct auth_userdb_post_settings, override_fields) },
+
+ SETTING_DEFINE_LIST_END
+};
+
+static const struct auth_userdb_post_settings auth_userdb_post_default_settings = {
+ .override_fields = ARRAY_INIT,
+};
+
+const struct setting_parser_info auth_userdb_post_setting_parser_info = {
+ .name = "auth_userdb_post",
+
+ .defines = auth_userdb_post_setting_defines,
+ .defaults = &auth_userdb_post_default_settings,
+
+ .struct_size = sizeof(struct auth_userdb_post_settings),
+ .pool_offset1 = 1 + offsetof(struct auth_userdb_post_settings, pool),
+};
+
+
/* we're kind of kludging here to avoid "auth_" prefix in the struct fields */
#undef DEF
#undef DEF_NOPREFIX
bool master;
};
+struct auth_userdb_pre_settings {
+ pool_t pool;
+ ARRAY_TYPE(const_string) default_fields;
+};
+
+struct auth_userdb_post_settings {
+ pool_t pool;
+ ARRAY_TYPE(const_string) override_fields;
+};
+
struct auth_userdb_settings {
pool_t pool;
const char *name;
const char *driver;
const char *args;
- const char *default_fields;
- const char *override_fields;
const char *skip;
const char *result_success;
extern const struct setting_parser_info auth_setting_parser_info;
extern const struct setting_parser_info auth_passdb_pre_setting_parser_info;
extern const struct setting_parser_info auth_passdb_post_setting_parser_info;
+extern const struct setting_parser_info auth_userdb_pre_setting_parser_info;
+extern const struct setting_parser_info auth_userdb_post_setting_parser_info;
extern const struct auth_settings *global_auth_settings;
void auth_settings_read(struct master_service_settings_output *output_r);
/* lookup user */
struct auth_request *auth_request;
unsigned int userdb_id;
- const char *error;
/* <userdb id> [<args>] */
if (str_to_uint(args[0], &userdb_id) < 0) {
auth_request_userdb_lookup_begin(auth_request);
if (auth_request->fields.userdb_reply == NULL)
auth_request_init_userdb_reply(auth_request);
- if (userdb_template_export(auth_request->userdb->default_fields_tmpl,
- auth_request, &error) < 0) {
- e_error(authdb_event(auth_request),
- "Failed to expand default_fields: %s", error);
+ if (auth_request_set_userdb_default_fields(auth_request) < 0) {
lookup_user_callback(USERDB_RESULT_INTERNAL_FAILURE,
auth_request);
return TRUE;
.name = "",
.driver = "static",
.args = "",
- .default_fields = "",
- .override_fields = "",
.skip = "never",
.result_success = "return-ok",
auth_userdb = p_new(auth->pool, struct auth_userdb, 1);
auth_userdb->auth_set =
settings_get_or_fatal(event, &auth_setting_parser_info);
- event_unref(&event);
auth_userdb->name = set->name;
auth_userdb->set = set;
auth_userdb->result_internalfail =
auth_db_rule_parse(set->result_internalfail);
- auth_userdb->default_fields_tmpl =
- userdb_template_build(auth->pool, set->driver,
- set->default_fields);
- auth_userdb->override_fields_tmpl =
- userdb_template_build(auth->pool, set->driver,
- set->override_fields);
-
for (dest = &auth->userdbs; *dest != NULL; dest = &(*dest)->next) ;
*dest = auth_userdb;
auth_userdb->userdb = userdb_preinit(auth->pool, set);
/* make sure any %variables in default_fields exist in cache_key */
if (auth_userdb->userdb->default_cache_key != NULL) {
- auth_userdb->cache_key =
- p_strconcat(auth->pool, auth_userdb->userdb->default_cache_key,
- set->default_fields, NULL);
- }
- else {
+ struct auth_userdb_pre_settings *userdb_pre_set;
+ const char *error;
+ if (settings_get(event, &auth_userdb_pre_setting_parser_info,
+ SETTINGS_GET_FLAG_NO_EXPAND,
+ &userdb_pre_set, &error) < 0)
+ i_fatal("%s", error);
+ auth_userdb->cache_key = p_strconcat(
+ auth->pool,
+ auth_userdb->userdb->default_cache_key,
+ t_array_const_string_join(
+ &userdb_pre_set->default_fields, ""),
+ NULL);
+ settings_free(userdb_pre_set);
+ } else {
auth_userdb->cache_key = NULL;
}
+ event_unref(&event);
}
static void auth_userdb_deinit(struct auth_userdb *userdb)
/* The caching key for this userdb, or NULL if caching isn't wanted. */
const char *cache_key;
- struct userdb_template *default_fields_tmpl;
- struct userdb_template *override_fields_tmpl;
-
enum auth_userdb_skip skip;
enum auth_db_rule result_success;
enum auth_db_rule result_failure;