The field expands to either the passdb or userdb extra field.
You can also use %{passdb:field:defaultvalue} where if field doesn't exist,
it's expanded to defaultvalue. Note that an empty value means that the field
still exists and it's not expanded to defaultvalue.
test_auth_cache_DEPENDENCIES = $(pkglibexec_PROGRAMS) $(test_libs)
test_auth_request_var_expand_SOURCES = test-auth-request-var-expand.c
-test_auth_request_var_expand_LDADD = auth-request-var-expand.o $(test_libs)
+test_auth_request_var_expand_LDADD = auth-request-var-expand.o auth-fields.o $(test_libs)
test_auth_request_var_expand_DEPENDENCIES = $(pkglibexec_PROGRAMS) $(test_libs)
test_db_dict_SOURCES = test-db-dict.c
/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
#include "auth-common.h"
+#include "str.h"
#include "strescape.h"
#include "auth-request.h"
+struct auth_request_var_expand_ctx {
+ struct auth_request *auth_request;
+ auth_request_escape_func_t *escape_func;
+};
+
const struct var_expand_table
auth_request_var_expand_static_tab[AUTH_REQUEST_VAR_TAB_COUNT+1] = {
{ 'u', NULL, "user" },
return auth_request_get_var_expand_table_full(auth_request, escape_func,
&count);
}
+
+static const char *field_get_default(const char *data)
+{
+ const char *p;
+
+ p = strchr(data, ':');
+ if (p == NULL)
+ return "";
+ else {
+ /* default value given */
+ return p+1;
+ }
+}
+
+static const char *
+auth_request_var_expand_func_passdb(const char *data, void *context)
+{
+ struct auth_request_var_expand_ctx *ctx = context;
+ const char *field_name = t_strcut(data, ':');
+ const char *value;
+
+ value = auth_fields_find(ctx->auth_request->extra_fields, field_name);
+ return ctx->escape_func(value != NULL ? value : field_get_default(data),
+ ctx->auth_request);
+}
+
+static const char *
+auth_request_var_expand_func_userdb(const char *data, void *context)
+{
+ struct auth_request_var_expand_ctx *ctx = context;
+ const char *field_name = t_strcut(data, ':');
+ const char *value;
+
+ value = ctx->auth_request->userdb_reply == NULL ? NULL :
+ auth_fields_find(ctx->auth_request->userdb_reply, field_name);
+ return ctx->escape_func(value != NULL ? value : field_get_default(data),
+ ctx->auth_request);
+}
+
+const struct var_expand_func_table auth_request_var_funcs_table[] = {
+ { "passdb", auth_request_var_expand_func_passdb },
+ { "userdb", auth_request_var_expand_func_userdb },
+ { NULL, NULL }
+};
+
+void auth_request_var_expand(string_t *dest, const char *str,
+ struct auth_request *auth_request,
+ auth_request_escape_func_t *escape_func)
+{
+ auth_request_var_expand_with_table(dest, str, auth_request,
+ auth_request_get_var_expand_table(auth_request, escape_func),
+ escape_func);
+}
+
+void auth_request_var_expand_with_table(string_t *dest, const char *str,
+ struct auth_request *auth_request,
+ const struct var_expand_table *table,
+ auth_request_escape_func_t *escape_func)
+{
+ struct auth_request_var_expand_ctx ctx;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.auth_request = auth_request;
+ ctx.escape_func = escape_func;
+ var_expand_with_funcs(dest, str, table,
+ auth_request_var_funcs_table, &ctx);
+}
+
+const char *
+t_auth_request_var_expand(const char *str,
+ struct auth_request *auth_request,
+ auth_request_escape_func_t *escape_func)
+{
+ string_t *dest = t_str_new(128);
+ auth_request_var_expand(dest, str, auth_request, escape_func);
+ return str_c(dest);
+}
auth_request_get_var_expand_table_full(const struct auth_request *auth_request,
auth_request_escape_func_t *escape_func,
unsigned int *count) ATTR_NULL(2);
+
+void auth_request_var_expand(string_t *dest, const char *str,
+ struct auth_request *auth_request,
+ auth_request_escape_func_t *escape_func);
+void auth_request_var_expand_with_table(string_t *dest, const char *str,
+ struct auth_request *auth_request,
+ const struct var_expand_table *table,
+ auth_request_escape_func_t *escape_func);
+const char *
+t_auth_request_var_expand(const char *str,
+ struct auth_request *auth_request,
+ auth_request_escape_func_t *escape_func);
+
const char *auth_request_str_escape(const char *string,
const struct auth_request *request);
/* username format given, put it through variable expansion.
we'll have to temporarily replace request->user to get
%u to be the wanted username */
- const struct var_expand_table *table;
char *old_username;
string_t *dest;
request->user = user;
dest = t_str_new(256);
- table = auth_request_get_var_expand_table(request, NULL);
- var_expand(dest, set->username_format, table);
+ auth_request_var_expand(dest, set->username_format, request, NULL);
user = p_strdup(request->pool, str_c(dest));
request->user = old_username;
struct stat st;
path = t_str_new(256);
- var_expand(path, path_template,
- auth_request_get_var_expand_table(request, NULL));
+ auth_request_var_expand(path, path_template, request, NULL);
if (stat(str_c(path), &st) < 0) {
auth_request_log_error(request, AUTH_SUBSYS_DB,
"stat(%s) failed: %m", str_c(path));
#include "safe-memset.h"
#include "strescape.h"
#include "child-wait.h"
-#include "var-expand.h"
#include "db-checkpassword.h"
#include <stdlib.h>
string_t *str;
str = t_str_new(256);
- var_expand(str, args,
- auth_request_get_var_expand_table(request, NULL));
+ auth_request_var_expand(str, args, request, NULL);
return t_strconcat(str_c(str), " ", checkpassword_reply_path, NULL);
}
#include "hash.h"
#include "str.h"
#include "eacces-error.h"
-#include "var-expand.h"
#include <stdlib.h>
#include <unistd.h>
{
struct passwd_file *pw;
struct passwd_user *pu;
- const struct var_expand_table *table;
string_t *username, *dest;
if (!db->vars)
pw = db->default_file;
else {
- table = auth_request_get_var_expand_table(request, path_fix);
dest = t_str_new(256);
- var_expand(dest, db->path, table);
+ auth_request_var_expand(dest, db->path, request, path_fix);
pw = hash_table_lookup(db->files, str_c(dest));
if (pw == NULL) {
}
username = t_str_new(256);
- table = auth_request_get_var_expand_table(request,
- auth_request_str_escape);
- var_expand(username, username_format, table);
+ auth_request_var_expand(username, username_format, request,
+ auth_request_str_escape);
auth_request_log_debug(request, AUTH_SUBSYS_DB,
"lookup: user=%s file=%s",
#include "auth-common.h"
#include "passdb.h"
#include "str.h"
-#include "var-expand.h"
#include "imap-resp-code.h"
#include "imapc-client.h"
(struct imap_passdb_module *)_module;
struct imap_auth_request *request;
struct imapc_client_settings set;
- const struct var_expand_table *table;
string_t *str;
set = module->set;
if (module->set_have_vars) {
str = t_str_new(128);
- table = auth_request_get_var_expand_table(auth_request, NULL);
- var_expand(str, set.username, table);
+ auth_request_var_expand(str, set.username, auth_request, NULL);
set.username = t_strdup(str_c(str));
str_truncate(str, 0);
- var_expand(str, set.host, table);
+ auth_request_var_expand(str, set.host, auth_request, NULL);
set.host = t_strdup(str_c(str));
}
auth_request_log_debug(auth_request, AUTH_SUBSYS_DB,
#include "ioloop.h"
#include "array.h"
#include "str.h"
-#include "var-expand.h"
#include "password-scheme.h"
#include "auth-cache.h"
#include "db-ldap.h"
(struct ldap_passdb_module *)_module;
struct ldap_connection *conn = module->conn;
struct ldap_request_search *srequest = &request->request.search;
- const struct var_expand_table *vars;
const char **attr_names = (const char **)conn->pass_attr_names;
string_t *str;
request->require_password = require_password;
srequest->request.type = LDAP_REQUEST_TYPE_SEARCH;
- vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
str = t_str_new(512);
- var_expand(str, conn->set.base, vars);
+ auth_request_var_expand(str, conn->set.base, auth_request, ldap_escape);
srequest->base = p_strdup(auth_request->pool, str_c(str));
str_truncate(str, 0);
- var_expand(str, conn->set.pass_filter, vars);
+ auth_request_var_expand(str, conn->set.pass_filter,
+ auth_request, ldap_escape);
srequest->filter = p_strdup(auth_request->pool, str_c(str));
srequest->attr_map = &conn->pass_attr_map;
srequest->attributes = conn->pass_attr_names;
(struct ldap_passdb_module *)_module;
struct ldap_connection *conn = module->conn;
struct ldap_request_search *srequest = &request->request.search;
- const struct var_expand_table *vars;
string_t *str;
srequest->request.type = LDAP_REQUEST_TYPE_SEARCH;
- vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
str = t_str_new(512);
- var_expand(str, conn->set.base, vars);
+ auth_request_var_expand(str, conn->set.base, auth_request, ldap_escape);
srequest->base = p_strdup(auth_request->pool, str_c(str));
str_truncate(str, 0);
- var_expand(str, conn->set.pass_filter, vars);
+ auth_request_var_expand(str, conn->set.pass_filter,
+ auth_request, ldap_escape);
srequest->filter = p_strdup(auth_request->pool, str_c(str));
/* we don't need the attributes to perform authentication, but they
(struct ldap_passdb_module *)_module;
struct ldap_connection *conn = module->conn;
struct ldap_request_bind *brequest = &request->request.bind;
- const struct var_expand_table *vars;
string_t *dn;
brequest->request.type = LDAP_REQUEST_TYPE_BIND;
- vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
dn = t_str_new(512);
- var_expand(dn, conn->set.auth_bind_userdn, vars);
+ auth_request_var_expand(dn, conn->set.auth_bind_userdn, auth_request, ldap_escape);
brequest->dn = p_strdup(auth_request->pool, str_c(dn));
ldap_auth_bind(conn, brequest);
#include "lib-signals.h"
#include "str.h"
-#include "var-expand.h"
#include "net.h"
#include "safe-memset.h"
#include "auth-cache.h"
struct passdb_module *_module = request->passdb->passdb;
struct pam_passdb_module *module = (struct pam_passdb_module *)_module;
enum passdb_result result;
- string_t *expanded_service;
const char *service;
if (module->requests_left > 0) {
worker_restart_request = TRUE;
}
- expanded_service = t_str_new(64);
- var_expand(expanded_service, module->service_name,
- auth_request_get_var_expand_table(request, NULL));
- service = str_c(expanded_service);
+ service = t_auth_request_var_expand(module->service_name, request, NULL);
auth_request_log_debug(request, AUTH_SUBSYS_DB,
"lookup service=%s", service);
#include "str.h"
#include "auth-cache.h"
-#include "var-expand.h"
#include "password-scheme.h"
#include "db-passwd-file.h"
if (value != NULL) {
key = t_strdup_until(*p, value);
str_truncate(str, 0);
- var_expand(str, value + 1, table);
+ auth_request_var_expand_with_table(str, value + 1,
+ request, table, NULL);
value = str_c(str);
} else {
key = *p;
#ifdef PASSDB_SQL
-#include "str.h"
-#include "strescape.h"
-#include "var-expand.h"
#include "safe-memset.h"
#include "password-scheme.h"
#include "auth-cache.h"
struct passdb_module *_module =
sql_request->auth_request->passdb->passdb;
struct sql_passdb_module *module = (struct sql_passdb_module *)_module;
- string_t *query;
+ const char *query;
- query = t_str_new(512);
- var_expand(query, module->conn->set.password_query,
- auth_request_get_var_expand_table(sql_request->auth_request,
- passdb_sql_escape));
+ query = t_auth_request_var_expand(module->conn->set.password_query,
+ sql_request->auth_request,
+ passdb_sql_escape);
auth_request_log_debug(sql_request->auth_request, AUTH_SUBSYS_DB,
- "query: %s", str_c(query));
+ "query: %s", query);
auth_request_ref(sql_request->auth_request);
- sql_query(module->conn->db, str_c(query),
+ sql_query(module->conn->db, query,
sql_query_callback, sql_request);
}
(struct sql_passdb_module *) request->passdb->passdb;
struct sql_transaction_context *transaction;
struct passdb_sql_request *sql_request;
- string_t *query;
+ const char *query;
request->mech_password = p_strdup(request->pool, new_credentials);
- query = t_str_new(512);
- var_expand(query, module->conn->set.update_query,
- auth_request_get_var_expand_table(request,
- passdb_sql_escape));
+ query = t_auth_request_var_expand(module->conn->set.update_query,
+ request, passdb_sql_escape);
sql_request = i_new(struct passdb_sql_request, 1);
sql_request->auth_request = request;
sql_request->callback.set_credentials = callback;
transaction = sql_transaction_begin(module->conn->db);
- sql_update(transaction, str_c(query));
+ sql_update(transaction, query);
sql_transaction_commit(&transaction,
sql_set_credentials_callback, sql_request);
return 0;
/* Copyright (c) 2010-2015 Dovecot authors, see the included COPYING file */
#include "auth-common.h"
-#include "array.h"
-#include "str.h"
-#include "var-expand.h"
#include "passdb.h"
#include "passdb-template.h"
{
struct static_passdb_module *module =
(struct static_passdb_module *)request->passdb->passdb;
- const struct var_expand_table *table;
- string_t *str = t_str_new(128);
auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup");
passdb_template_export(module->tmpl, request);
if (module->static_password_tmpl != NULL) {
- table = auth_request_get_var_expand_table(request, NULL);
- var_expand(str, module->static_password_tmpl, table);
- *password_r = str_c(str);
+ *password_r = t_auth_request_var_expand(
+ module->static_password_tmpl, request, NULL);
} else if (auth_fields_exists(request->extra_fields, "nopassword")) {
*password_r = "";
} else {
#include "auth-common.h"
#include "array.h"
#include "str.h"
-#include "var-expand.h"
#include "passdb.h"
#include "passdb-template.h"
value = "";
else {
str_truncate(str, 0);
- var_expand(str, args[i+1], table);
+ auth_request_var_expand_with_table(str, args[i+1],
+ auth_request, table, NULL);
value = str_c(str);
}
auth_request_set_field(auth_request, args[i], value,
test_end();
}
+static void test_auth_request_var_expand_funcs(void)
+{
+ pool_t pool;
+ const char *value;
+
+ test_begin("auth request var expand funcs");
+
+ pool = pool_alloconly_create("test var expand funcs", 1024);
+ test_request.extra_fields = auth_fields_init(pool);
+ test_request.userdb_reply = auth_fields_init(pool);
+
+ auth_fields_add(test_request.extra_fields, "pkey1", "-pval1", 0);
+ auth_fields_add(test_request.extra_fields, "pkey2", "", 0);
+
+ auth_fields_add(test_request.userdb_reply, "ukey1", "-uval1", 0);
+ auth_fields_add(test_request.userdb_reply, "ukey2", "", 0);
+
+ value = t_auth_request_var_expand(
+ "%{passdb:pkey1}\n%{passdb:pkey1:default1}\n"
+ "%{passdb:pkey2}\n%{passdb:pkey2:default2}\n"
+ "%{passdb:pkey3}\n%{passdb:pkey3:default3}\n"
+ "%{passdb:ukey1}\n%{passdb:ukey1:default4}\n",
+ &test_request, test_escape);
+ test_assert(strcmp(value, "+pval1\n+pval1\n\n\n\ndefault3\n\ndefault4\n") == 0);
+
+ value = t_auth_request_var_expand(
+ "%{userdb:ukey1}\n%{userdb:ukey1:default1}\n"
+ "%{userdb:ukey2}\n%{userdb:ukey2:default2}\n"
+ "%{userdb:ukey3}\n%{userdb:ukey3:default3}\n"
+ "%{userdb:pkey1}\n%{userdb:pkey1:default4}\n",
+ &test_request, test_escape);
+ test_assert(strcmp(value, "+uval1\n+uval1\n\n\n\ndefault3\n\ndefault4\n") == 0);
+
+ pool_unref(&pool);
+ test_end();
+}
+
int main(void)
{
static void (*test_functions[])(void) = {
test_auth_request_var_expand_flags,
test_auth_request_var_expand_long,
test_auth_request_var_expand_usernames,
+ test_auth_request_var_expand_funcs,
NULL
};
test_request = default_test_request;
#include "ioloop.h"
#include "array.h"
#include "str.h"
-#include "var-expand.h"
#include "auth-cache.h"
#include "db-dict.h"
struct dict_userdb_module *module =
(struct dict_userdb_module *)_module;
struct dict_userdb_iterate_context *ctx;
- const struct var_expand_table *vars;
string_t *path;
ctx = i_new(struct dict_userdb_iterate_context, 1);
path = t_str_new(128);
str_append(path, DICT_PATH_SHARED);
- vars = auth_request_get_var_expand_table(auth_request, NULL);
- var_expand(path, module->conn->set.iterate_prefix, vars);
+ auth_request_var_expand(path, module->conn->set.iterate_prefix,
+ auth_request, NULL);
ctx->key_prefix = p_strdup(auth_request->pool, str_c(path));
ctx->key_prefix_len = strlen(ctx->key_prefix);
#include "ioloop.h"
#include "array.h"
#include "str.h"
-#include "var-expand.h"
#include "auth-cache.h"
#include "db-ldap.h"
struct ldap_userdb_module *module =
(struct ldap_userdb_module *)_module;
struct ldap_connection *conn = module->conn;
- const struct var_expand_table *vars;
const char **attr_names = (const char **)conn->user_attr_names;
struct userdb_ldap_request *request;
string_t *str;
request = p_new(auth_request->pool, struct userdb_ldap_request, 1);
request->userdb_callback = callback;
- vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
-
str = t_str_new(512);
- var_expand(str, conn->set.base, vars);
+ auth_request_var_expand(str, conn->set.base, auth_request, ldap_escape);
request->request.base = p_strdup(auth_request->pool, str_c(str));
str_truncate(str, 0);
- var_expand(str, conn->set.user_filter, vars);
+ auth_request_var_expand(str, conn->set.user_filter, auth_request, ldap_escape);
request->request.filter = p_strdup(auth_request->pool, str_c(str));
request->request.attr_map = &conn->user_attr_map;
struct ldap_connection *conn = module->conn;
struct ldap_userdb_iterate_context *ctx;
struct userdb_iter_ldap_request *request;
- const struct var_expand_table *vars;
const char **attr_names = (const char **)conn->iterate_attr_names;
string_t *str;
auth_request_ref(auth_request);
request->request.request.auth_request = auth_request;
- vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
-
str = t_str_new(512);
- var_expand(str, conn->set.base, vars);
+ auth_request_var_expand(str, conn->set.base, auth_request, ldap_escape);
request->request.base = p_strdup(auth_request->pool, str_c(str));
str_truncate(str, 0);
- var_expand(str, conn->set.iterate_filter, vars);
+ auth_request_var_expand(str, conn->set.iterate_filter,
+ auth_request, ldap_escape);
request->request.filter = p_strdup(auth_request->pool, str_c(str));
request->request.attr_map = &conn->iterate_attr_map;
request->request.attributes = conn->iterate_attr_names;
#include "istream.h"
#include "str.h"
#include "auth-cache.h"
-#include "var-expand.h"
#include "db-passwd-file.h"
#include <unistd.h>
if (value != NULL) {
key = t_strdup_until(key, value);
str_truncate(str, 0);
- var_expand(str, value + 1, table);
+ auth_request_var_expand_with_table(str, value + 1,
+ auth_request, table, NULL);
value = str_c(str);
} else {
value = "";
#ifdef USERDB_SQL
-#include "str.h"
-#include "strescape.h"
-#include "var-expand.h"
#include "auth-cache.h"
#include "db-sql.h"
struct sql_userdb_module *module =
(struct sql_userdb_module *)_module;
struct userdb_sql_request *sql_request;
- string_t *query;
+ const char *query;
- query = t_str_new(512);
- var_expand(query, module->conn->set.user_query,
- auth_request_get_var_expand_table(auth_request,
- userdb_sql_escape));
+ query = t_auth_request_var_expand(module->conn->set.user_query,
+ auth_request, userdb_sql_escape);
auth_request_ref(auth_request);
sql_request = i_new(struct userdb_sql_request, 1);
sql_request->callback = callback;
sql_request->auth_request = auth_request;
- auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "%s", str_c(query));
+ auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "%s", query);
- sql_query(module->conn->db, str_c(query),
+ sql_query(module->conn->db, query,
sql_query_callback, sql_request);
}
struct sql_userdb_module *module =
(struct sql_userdb_module *)_module;
struct sql_userdb_iterate_context *ctx;
- string_t *query;
+ const char *query;
- query = t_str_new(512);
- var_expand(query, module->conn->set.iterate_query,
- auth_request_get_var_expand_table(auth_request,
- userdb_sql_escape));
+ query = t_auth_request_var_expand(module->conn->set.iterate_query,
+ auth_request, userdb_sql_escape);
ctx = i_new(struct sql_userdb_iterate_context, 1);
ctx->ctx.auth_request = auth_request;
ctx->ctx.context = context;
auth_request_ref(auth_request);
- sql_query(module->conn->db, str_c(query),
+ sql_query(module->conn->db, query,
sql_iter_query_callback, ctx);
- auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "%s", str_c(query));
+ auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "%s", query);
return &ctx->ctx;
}
#include "auth-common.h"
#include "array.h"
#include "str.h"
-#include "var-expand.h"
#include "userdb.h"
#include "userdb-template.h"
value = "";
else {
str_truncate(str, 0);
- var_expand(str, args[i+1], table);
+ auth_request_var_expand_with_table(str, args[i+1],
+ auth_request, table, NULL);
value = str_c(str);
}
auth_request_set_userdb_field(auth_request, args[i], value);