bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen#include "auth-common.h"
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen#include "str.h"
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen#include "strescape.h"
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen#include "auth-request.h"
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainenstruct auth_request_var_expand_ctx {
4154415071c71c669ae5aae5ca900747cdaf9b8bTimo Sirainen const struct auth_request *auth_request;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen auth_request_escape_func_t *escape_func;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen};
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenconst struct var_expand_table
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenauth_request_var_expand_static_tab[AUTH_REQUEST_VAR_TAB_COUNT+1] = {
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'u', NULL, "user" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'n', NULL, "username" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'd', NULL, "domain" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 's', NULL, "service" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'h', NULL, "home" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'l', NULL, "lip" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'r', NULL, "rip" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'p', NULL, "pid" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'w', NULL, "password" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '!', NULL, NULL },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'm', NULL, "mech" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'c', NULL, "secured" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'a', NULL, "lport" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'b', NULL, "rport" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { 'k', NULL, "cert" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "login_user" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "login_username" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "login_domain" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "session" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "real_lip" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "real_rip" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "real_lport" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "real_rport" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "domain_first" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "domain_last" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "master_user" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "session_pid" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "orig_user" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "orig_username" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, "orig_domain" },
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen { '\0', NULL, "auth_user" },
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen { '\0', NULL, "auth_username" },
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen { '\0', NULL, "auth_domain" },
fe791e96fdf796f7d8997ee0515b163dc5eddd72Aki Tuomi { '\0', NULL, "local_name" },
e88c6613d3bc78fa928b0e74f8e4ebd91151206eAki Tuomi { '\0', NULL, "client_id" },
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen /* be sure to update AUTH_REQUEST_VAR_TAB_COUNT */
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen { '\0', NULL, NULL }
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen};
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenstatic const char *
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenescape_none(const char *string,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen const struct auth_request *request ATTR_UNUSED)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen{
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen return string;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen}
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenconst char *
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenauth_request_str_escape(const char *string,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen const struct auth_request *request ATTR_UNUSED)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen{
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen return str_escape(string);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen}
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenstruct var_expand_table *
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenauth_request_get_var_expand_table_full(const struct auth_request *auth_request,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request_escape_func_t *escape_func,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen unsigned int *count)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen{
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen const unsigned int auth_count =
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen N_ELEMENTS(auth_request_var_expand_static_tab);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen struct var_expand_table *tab, *ret_tab;
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen const char *orig_user, *auth_user, *username;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (escape_func == NULL)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen escape_func = escape_none;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen /* keep the extra fields at the beginning. the last static_tab field
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen contains the ending NULL-fields. */
e7d0bea63a08b08c47c4b5c187d2cb7127859657Timo Sirainen tab = ret_tab = t_new(struct var_expand_table,
e7d0bea63a08b08c47c4b5c187d2cb7127859657Timo Sirainen MALLOC_ADD(*count, auth_count));
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab += *count;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen *count += auth_count;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen memcpy(tab, auth_request_var_expand_static_tab,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_count * sizeof(*tab));
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen username = auth_request->user != NULL ? auth_request->user : "";
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen tab[0].value = escape_func(username, auth_request);
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen tab[1].value = escape_func(t_strcut(username, '@'),
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request);
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen tab[2].value = i_strchr_to_next(username, '@');
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (tab[2].value != NULL)
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[2].value = escape_func(tab[2].value, auth_request);
de2cba085b9b231135be953d7f34f74fefb82725Timo Sirainen tab[3].value = escape_func(auth_request->service, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen /* tab[4] = we have no home dir */
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->local_ip.family != 0)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[5].value = net_ip2addr(&auth_request->local_ip);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->remote_ip.family != 0)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[6].value = net_ip2addr(&auth_request->remote_ip);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[7].value = dec2str(auth_request->client_pid);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->mech_password != NULL) {
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[8].value = escape_func(auth_request->mech_password,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen }
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->userdb_lookup) {
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[9].value = auth_request->userdb == NULL ? "" :
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen dec2str(auth_request->userdb->userdb->id);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen } else {
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[9].value = auth_request->passdb == NULL ? "" :
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen dec2str(auth_request->passdb->passdb->id);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen }
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[10].value = auth_request->mech_name == NULL ? "" :
de2cba085b9b231135be953d7f34f74fefb82725Timo Sirainen escape_func(auth_request->mech_name, auth_request);
1eedfce593fd29b5a5dee8d8ae3d82ab63d99cbfAki Tuomi switch(auth_request->secured) {
1eedfce593fd29b5a5dee8d8ae3d82ab63d99cbfAki Tuomi case AUTH_REQUEST_SECURED_NONE: tab[11].value = ""; break;
1eedfce593fd29b5a5dee8d8ae3d82ab63d99cbfAki Tuomi case AUTH_REQUEST_SECURED: tab[11].value = "secured"; break;
1eedfce593fd29b5a5dee8d8ae3d82ab63d99cbfAki Tuomi case AUTH_REQUEST_SECURED_TLS: tab[11].value = "TLS"; break;
1eedfce593fd29b5a5dee8d8ae3d82ab63d99cbfAki Tuomi default: tab[11].value = ""; break;
1eedfce593fd29b5a5dee8d8ae3d82ab63d99cbfAki Tuomi };
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[12].value = dec2str(auth_request->local_port);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[13].value = dec2str(auth_request->remote_port);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[14].value = auth_request->valid_client_cert ? "valid" : "";
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->requested_login_user != NULL) {
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen const char *login_user = auth_request->requested_login_user;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[15].value = escape_func(login_user, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[16].value = escape_func(t_strcut(login_user, '@'),
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request);
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[17].value = i_strchr_to_next(login_user, '@');
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (tab[17].value != NULL) {
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[17].value = escape_func(tab[17].value,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen }
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen }
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[18].value = auth_request->session_id == NULL ? NULL :
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen escape_func(auth_request->session_id, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->real_local_ip.family != 0)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[19].value = net_ip2addr(&auth_request->real_local_ip);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (auth_request->real_remote_ip.family != 0)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[20].value = net_ip2addr(&auth_request->real_remote_ip);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[21].value = dec2str(auth_request->real_local_port);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[22].value = dec2str(auth_request->real_remote_port);
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen tab[23].value = i_strchr_to_next(username, '@');
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (tab[23].value != NULL) {
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[23].value = escape_func(t_strcut(tab[23].value, '@'),
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen }
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen tab[24].value = strrchr(username, '@');
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (tab[24].value != NULL)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[24].value = escape_func(tab[24].value+1, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[25].value = auth_request->master_user == NULL ? NULL :
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen escape_func(auth_request->master_user, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[26].value = auth_request->session_pid == (pid_t)-1 ? NULL :
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen dec2str(auth_request->session_pid);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen orig_user = auth_request->original_username != NULL ?
99abb1302ae693ccdfe0d57351fd42c67a8612fcTimo Sirainen auth_request->original_username : username;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[27].value = escape_func(orig_user, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen tab[28].value = escape_func(t_strcut(orig_user, '@'), auth_request);
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[29].value = i_strchr_to_next(orig_user, '@');
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen if (tab[29].value != NULL)
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[29].value = escape_func(tab[29].value, auth_request);
ef1ff1af5a38ad2b0bc77b3236c4c2d79f2c530fAki Tuomi
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen if (auth_request->master_user != NULL)
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen auth_user = auth_request->master_user;
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen else
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen auth_user = orig_user;
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen tab[30].value = escape_func(auth_user, auth_request);
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen tab[31].value = escape_func(t_strcut(auth_user, '@'), auth_request);
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[32].value = i_strchr_to_next(auth_user, '@');
cc7699162ad3f1eaa95997b95b299610ca07158dTimo Sirainen if (tab[32].value != NULL)
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen tab[32].value = escape_func(tab[32].value, auth_request);
fe791e96fdf796f7d8997ee0515b163dc5eddd72Aki Tuomi if (auth_request->local_name != NULL)
fe791e96fdf796f7d8997ee0515b163dc5eddd72Aki Tuomi tab[33].value = escape_func(auth_request->local_name, auth_request);
e88c6613d3bc78fa928b0e74f8e4ebd91151206eAki Tuomi if (auth_request->client_id != NULL)
e88c6613d3bc78fa928b0e74f8e4ebd91151206eAki Tuomi tab[34].value = escape_func(auth_request->client_id, auth_request);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen return ret_tab;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen}
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenconst struct var_expand_table *
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainenauth_request_get_var_expand_table(const struct auth_request *auth_request,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen auth_request_escape_func_t *escape_func)
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen{
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen unsigned int count = 0;
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen return auth_request_get_var_expand_table_full(auth_request, escape_func,
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen &count);
4b7957c5e995f2c1820891d77a292a4886d52a43Timo Sirainen}
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainenstatic const char *field_get_default(const char *data)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen{
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen const char *p;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen p = strchr(data, ':');
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen if (p == NULL)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen return "";
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen else {
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen /* default value given */
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen return p+1;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen }
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen}
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenauth_request_var_expand_func_passdb(const char *data, void *context,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r ATTR_UNUSED)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen{
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen struct auth_request_var_expand_ctx *ctx = context;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen const char *field_name = t_strcut(data, ':');
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen const char *value;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen value = auth_fields_find(ctx->auth_request->extra_fields, field_name);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *value_r = ctx->escape_func(value != NULL ? value : field_get_default(data),
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen ctx->auth_request);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 1;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen}
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenauth_request_var_expand_func_userdb(const char *data, void *context,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r ATTR_UNUSED)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen{
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen struct auth_request_var_expand_ctx *ctx = context;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen const char *field_name = t_strcut(data, ':');
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen const char *value;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen value = ctx->auth_request->userdb_reply == NULL ? NULL :
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen auth_fields_find(ctx->auth_request->userdb_reply, field_name);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *value_r = ctx->escape_func(value != NULL ? value : field_get_default(data),
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen ctx->auth_request);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 1;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen}
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainenconst struct var_expand_func_table auth_request_var_funcs_table[] = {
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen { "passdb", auth_request_var_expand_func_passdb },
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen { "userdb", auth_request_var_expand_func_userdb },
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen { NULL, NULL }
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen};
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenint auth_request_var_expand(string_t *dest, const char *str,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const struct auth_request *auth_request,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen auth_request_escape_func_t *escape_func,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char **error_r)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen{
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return auth_request_var_expand_with_table(dest, str, auth_request,
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen auth_request_get_var_expand_table(auth_request, escape_func),
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen escape_func, error_r);
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen}
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenint auth_request_var_expand_with_table(string_t *dest, const char *str,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const struct auth_request *auth_request,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const struct var_expand_table *table,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen auth_request_escape_func_t *escape_func,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char **error_r)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen{
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen struct auth_request_var_expand_ctx ctx;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&ctx);
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen ctx.auth_request = auth_request;
c30bcc83aca4e0082c0d28abea72ec309984b06fTimo Sirainen ctx.escape_func = escape_func == NULL ? escape_none : escape_func;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return var_expand_with_funcs(dest, str, table,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen auth_request_var_funcs_table, &ctx, error_r);
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen}
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenint t_auth_request_var_expand(const char *str,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const struct auth_request *auth_request ATTR_UNUSED,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen auth_request_escape_func_t *escape_func ATTR_UNUSED,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char **value_r, const char **error_r)
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen{
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen string_t *dest = t_str_new(128);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen int ret = auth_request_var_expand(dest, str, auth_request,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen escape_func, error_r);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen *value_r = str_c(dest);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return ret;
38ceb710e2bc957a66a75c68957cb87746682a75Timo Sirainen}