diff options
Diffstat (limited to '')
-rw-r--r-- | src/auth/userdb-template.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/auth/userdb-template.c b/src/auth/userdb-template.c new file mode 100644 index 0000000..a1e3011 --- /dev/null +++ b/src/auth/userdb-template.c @@ -0,0 +1,124 @@ +/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */ + +#include "auth-common.h" +#include "array.h" +#include "str.h" +#include "userdb.h" +#include "userdb-template.h" + +struct userdb_template { + ARRAY(const char *) args; +}; + +struct userdb_template * +userdb_template_build(pool_t pool, const char *userdb_name, const char *args) +{ + struct userdb_template *tmpl; + const char *const *tmp, *key, *value, *nonull_value; + uid_t uid; + gid_t gid; + + tmpl = p_new(pool, struct userdb_template, 1); + + tmp = t_strsplit_spaces(args, " "); + p_array_init(&tmpl->args, pool, str_array_length(tmp)); + + for (; *tmp != NULL; tmp++) { + value = strchr(*tmp, '='); + if (value == NULL) + key = *tmp; + else + key = t_strdup_until(*tmp, value++); + + + if (*key == '\0') + i_fatal("Invalid userdb template %s - key must not be empty", + args); + + nonull_value = value == NULL ? "" : value; + if (strcasecmp(key, "uid") == 0) { + uid = userdb_parse_uid(NULL, nonull_value); + if (uid == (uid_t)-1) { + i_fatal("%s userdb: Invalid uid: %s", + userdb_name, nonull_value); + } + value = dec2str(uid); + } else if (strcasecmp(key, "gid") == 0) { + gid = userdb_parse_gid(NULL, nonull_value); + if (gid == (gid_t)-1) { + i_fatal("%s userdb: Invalid gid: %s", + userdb_name, nonull_value); + } + value = dec2str(gid); + } else if (*key == '\0') { + i_fatal("%s userdb: Empty key (=%s)", + userdb_name, nonull_value); + } + key = p_strdup(pool, key); + value = p_strdup(pool, value); + + array_push_back(&tmpl->args, &key); + array_push_back(&tmpl->args, &value); + } + return tmpl; +} + +int userdb_template_export(struct userdb_template *tmpl, + struct auth_request *auth_request, + const char **error_r) +{ + const struct var_expand_table *table; + string_t *str; + const char *const *args, *value; + unsigned int i, count; + + if (userdb_template_is_empty(tmpl)) + return 0; + + 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); + if (auth_request_var_expand_with_table(str, args[i+1], + auth_request, table, NULL, error_r) <= 0) + return -1; + value = str_c(str); + } + auth_request_set_userdb_field(auth_request, args[i], value); + } + return 0; +} + +bool userdb_template_remove(struct userdb_template *tmpl, + const char *key, const char **value_r) +{ + const char *const *args; + unsigned int i, count; + + args = array_get(&tmpl->args, &count); + i_assert((count % 2) == 0); + for (i = 0; i < count; i += 2) { + if (strcmp(args[i], key) == 0) { + *value_r = args[i+1]; + array_delete(&tmpl->args, i, 2); + return TRUE; + } + } + return FALSE; +} + +bool userdb_template_is_empty(struct userdb_template *tmpl) +{ + return array_count(&tmpl->args) == 0; +} + +const char *const *userdb_template_get_args(struct userdb_template *tmpl, unsigned int *count_r) +{ + return array_get(&tmpl->args, count_r); +} |