userdb-template.c revision 0f5dc4da3982053036be65190e44bf28a67b1ca2
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2003-2016 Dovecot authors, see the included COPYING file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "auth-common.h"
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen#include "array.h"
ff487c974815bdaa2d05a3b834f4c2c841f4cc34Timo Sirainen#include "str.h"
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen#include "userdb.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "userdb-template.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenstruct userdb_template {
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen ARRAY(const char *) args;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen};
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenstruct userdb_template *
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenuserdb_template_build(pool_t pool, const char *userdb_name, const char *args)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct userdb_template *tmpl;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen const char *const *tmp, *key, *value, *nonull_value;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen uid_t uid;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen gid_t gid;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen tmpl = p_new(pool, struct userdb_template, 1);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen tmp = t_strsplit_spaces(args, " ");
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen p_array_init(&tmpl->args, pool, str_array_length(tmp));
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen for (; *tmp != NULL; tmp++) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen value = strchr(*tmp, '=');
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (value == NULL)
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen key = *tmp;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen else
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen key = t_strdup_until(*tmp, value++);
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen nonull_value = value == NULL ? "" : value;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen if (strcasecmp(key, "uid") == 0) {
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen uid = userdb_parse_uid(NULL, nonull_value);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (uid == (uid_t)-1) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_fatal("%s userdb: Invalid uid: %s",
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen userdb_name, nonull_value);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen value = dec2str(uid);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen } else if (strcasecmp(key, "gid") == 0) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen gid = userdb_parse_gid(NULL, nonull_value);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen if (gid == (gid_t)-1) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_fatal("%s userdb: Invalid gid: %s",
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen userdb_name, nonull_value);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen value = dec2str(gid);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen } else if (*key == '\0') {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen i_fatal("%s userdb: Empty key (=%s)",
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen userdb_name, nonull_value);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen key = p_strdup(pool, key);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen value = p_strdup(pool, value);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen array_append(&tmpl->args, &key, 1);
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen array_append(&tmpl->args, &value, 1);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return tmpl;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen}
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainenint userdb_template_export(struct userdb_template *tmpl,
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen struct auth_request *auth_request,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const char **error_r)
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen{
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen const struct var_expand_table *table;
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen string_t *str;
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen const char *const *args, *value;
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen unsigned int i, count;
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen if (userdb_template_is_empty(tmpl))
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen return 0;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen str = t_str_new(256);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen table = auth_request_get_var_expand_table(auth_request, NULL);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
88f73e2ed3e99417255c90890fa46e11e6378c9dTimo Sirainen args = array_get(&tmpl->args, &count);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen i_assert((count % 2) == 0);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen for (i = 0; i < count; i += 2) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (args[i+1] == NULL)
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen value = "";
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen else {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen str_truncate(str, 0);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (auth_request_var_expand_with_table(str, args[i+1],
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen auth_request, table, NULL, error_r) <= 0)
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen return -1;
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen value = str_c(str);
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen }
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen auth_request_set_userdb_field(auth_request, args[i], value);
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen }
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen return 0;
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen}
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainenbool userdb_template_remove(struct userdb_template *tmpl,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const char *key, const char **value_r)
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen{
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen const char *const *args;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen unsigned int i, count;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen args = array_get(&tmpl->args, &count);
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen i_assert((count % 2) == 0);
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen for (i = 0; i < count; i += 2) {
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen if (strcmp(args[i], key) == 0) {
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen *value_r = args[i+1];
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen array_delete(&tmpl->args, i, 2);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen return TRUE;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen }
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return FALSE;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen}
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainenbool userdb_template_is_empty(struct userdb_template *tmpl)
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen{
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen return array_count(&tmpl->args) == 0;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen}
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen