dict-ldap-settings.c revision 2ce0021487fbd7ef3384f3456fa4a176309c4ebf
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2008-2017 Dovecot authors, see the included COPYING file */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include "lib.h"
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include "array.h"
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include "str.h"
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include "settings.h"
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include "dict-ldap-settings.h"
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#include <ctype.h>
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *dict_ldap_commonName = "cn";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *dict_ldap_empty_filter = "";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenenum section_type {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen SECTION_ROOT = 0,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen SECTION_MAP,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen SECTION_FIELDS
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen};
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstruct dict_ldap_map_attribute {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *name;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *variable;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen};
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstruct setting_parser_ctx {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen pool_t pool;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct dict_ldap_settings *set;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen enum section_type type;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct dict_ldap_map cur_map;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct dict_ldap_map_attribute) cur_attributes;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen};
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#undef DEF_STR
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#undef DEF_BOOL
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#undef DEF_UINT
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#define DEF_STR(name) DEF_STRUCT_STR(name, dict_ldap_map)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, dict_ldap_map)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen#define DEF_UINT(name) DEF_STRUCT_UINT(name ,dict_ldap_map)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const struct setting_def dict_ldap_map_setting_defs[] = {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(pattern),
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(filter),
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(filter_iter),
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(username_attribute),
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(value_attribute),
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(base_dn),
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen DEF_STR(scope),
cc4087c4d7b1b6188dc731e783cee361f1e9c185Timo Sirainen { 0, NULL, 0 }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen};
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *pattern_read_name(const char **pattern)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *p = *pattern, *name;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (*p == '{') {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* ${name} */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen name = ++p;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen p = strchr(p, '}');
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (p == NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* error, but allow anyway */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *pattern += strlen(*pattern);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *pattern = p + 1;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen } else {
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen /* $name - ends at the first non-alnum_ character */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen name = p;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (; *p != '\0'; p++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (!i_isalnum(*p) && *p != '_')
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen break;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen *pattern = p;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen name = t_strdup_until(name, p);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return name;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *dict_ldap_attributes_map(struct setting_parser_ctx *ctx)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct dict_ldap_map_attribute *attributes;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen string_t *pattern;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *p, *name;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen unsigned int i, count;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* go through the variables in the pattern, replace them with plain
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen '$' character and add its ldap attribute */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen pattern = t_str_new(strlen(ctx->cur_map.pattern) + 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen attributes = array_get_modifiable(&ctx->cur_attributes, &count);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen p_array_init(&ctx->cur_map.ldap_attributes, ctx->pool, count);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (p = ctx->cur_map.pattern; *p != '\0';) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (*p != '$') {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen str_append_c(pattern, *p);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen p++;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen continue;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen p++;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen str_append_c(pattern, '$');
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen name = pattern_read_name(&p);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (i = 0; i < count; i++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (attributes[i].variable != NULL &&
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen strcmp(attributes[i].variable, name) == 0)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen break;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (i == count) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return t_strconcat("Missing LDAP attribute for variable: ",
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen name, NULL);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* mark this attribute as used */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen attributes[i].variable = NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen array_append(&ctx->cur_map.ldap_attributes,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen &attributes[i].name, 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* make sure there aren't any unused attributes */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (i = 0; i < count; i++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (attributes[i].variable != NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return t_strconcat("Unused variable: ",
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen attributes[i].variable, NULL);
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx->set->max_attribute_count < count)
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen ctx->set->max_attribute_count = count;
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen ctx->cur_map.pattern = p_strdup(ctx->pool, str_c(pattern));
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainenstatic const char *dict_ldap_map_finish(struct setting_parser_ctx *ctx)
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen{
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen if (ctx->cur_map.pattern == NULL)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Missing setting: pattern";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx->cur_map.filter == NULL)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->cur_map.filter = dict_ldap_empty_filter;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (*ctx->cur_map.filter != '\0') {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *ptr = ctx->cur_map.filter;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (*ptr != '(')
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen return "Filter must start with (";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen while(*ptr != '\0') ptr++;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ptr--;
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen if (*ptr != ')')
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen return "Filter must end with )";
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx->cur_map.value_attribute == NULL)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Missing setting: value_attribute";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx->cur_map.username_attribute == NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* default to commonName */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->cur_map.username_attribute = dict_ldap_commonName;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx->cur_map.scope == NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->cur_map.scope_val = 2; /* subtree */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen } else {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (strcasecmp(ctx->cur_map.scope, "one") == 0) ctx->cur_map.scope_val = 1;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen else if (strcasecmp(ctx->cur_map.scope, "base") == 0) ctx->cur_map.scope_val = 0;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen else if (strcasecmp(ctx->cur_map.scope, "subtree") == 0) ctx->cur_map.scope_val = 2;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen else return "Scope must be one, base or subtree";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (!array_is_created(&ctx->cur_map.ldap_attributes)) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* no attributes besides value. allocate the array anyway. */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen p_array_init(&ctx->cur_map.ldap_attributes, ctx->pool, 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (strchr(ctx->cur_map.pattern, '$') != NULL)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Missing attributes for pattern variables";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen array_append(&ctx->set->maps, &ctx->cur_map, 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_zero(&ctx->cur_map);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenparse_setting(const char *key, const char *value,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct setting_parser_ctx *ctx)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen{
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen struct dict_ldap_map_attribute *attribute;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen switch (ctx->type) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen case SECTION_ROOT:
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (strcmp(key, "uri") == 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->set->uri = p_strdup(ctx->pool, value);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen if (strcmp(key, "bind_dn") == 0) {
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen ctx->set->bind_dn = p_strdup(ctx->pool, value);
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen return NULL;
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen }
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen if (strcmp(key, "password") == 0) {
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen ctx->set->password = p_strdup(ctx->pool, value);
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (strcmp(key, "timeout") == 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (str_to_uint(value, &ctx->set->timeout) != 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Invalid timeout value";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (strcmp(key, "max_idle_time") == 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (str_to_uint(value, &ctx->set->max_idle_time) != 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return "Invalid max_idle_time value";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return NULL;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (strcmp(key, "debug") == 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (str_to_uint(value, &ctx->set->debug) != 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return "invalid debug value";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return NULL;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (strcmp(key, "tls") == 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (strcasecmp(value, "yes") == 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->set->require_ssl = TRUE;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->set->start_tls = TRUE;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen } else if (strcasecmp(value, "no") == 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx->set->require_ssl = FALSE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx->set->start_tls = FALSE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen } else if (strcasecmp(value, "try") == 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx->set->require_ssl = FALSE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx->set->start_tls = TRUE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen } else {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return "tls must be yes, try or no";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return NULL;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen break;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen case SECTION_MAP:
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return parse_setting_from_defs(ctx->pool,
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen dict_ldap_map_setting_defs,
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen &ctx->cur_map, key, value);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen case SECTION_FIELDS:
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (*value != '$') {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return t_strconcat("Value is missing '$' for attribute: ",
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen key, NULL);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen attribute = array_append_space(&ctx->cur_attributes);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen attribute->name = p_strdup(ctx->pool, key);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen attribute->variable = p_strdup(ctx->pool, value + 1);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return NULL;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return t_strconcat("Unknown setting: ", key, NULL);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen}
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainenstatic bool
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainenparse_section(const char *type, const char *name ATTR_UNUSED,
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen struct setting_parser_ctx *ctx, const char **error_r)
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen{
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen switch (ctx->type) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen case SECTION_ROOT:
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (type == NULL)
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return FALSE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (strcmp(type, "map") == 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen array_clear(&ctx->cur_attributes);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx->type = SECTION_MAP;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return TRUE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen break;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen case SECTION_MAP:
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (type == NULL) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx->type = SECTION_ROOT;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen *error_r = dict_ldap_map_finish(ctx);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return FALSE;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen }
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (strcmp(type, "fields") == 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->type = SECTION_FIELDS;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return TRUE;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen break;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen case SECTION_FIELDS:
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (type == NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx->type = SECTION_MAP;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *error_r = dict_ldap_attributes_map(ctx);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return FALSE;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen break;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *error_r = t_strconcat("Unknown section: ", type, NULL);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return FALSE;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainenstruct dict_ldap_settings *
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainendict_ldap_settings_read(pool_t pool, const char *path, const char **error_r)
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen{
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen struct setting_parser_ctx ctx;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen i_zero(&ctx);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx.pool = pool;
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx.set = p_new(pool, struct dict_ldap_settings, 1);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen t_array_init(&ctx.cur_attributes, 16);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen p_array_init(&ctx.set->maps, pool, 8);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx.set->timeout = 30; /* default timeout */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx.set->require_ssl = FALSE; /* try to start SSL */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx.set->start_tls = TRUE;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (!settings_read(path, NULL, parse_setting, parse_section,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen &ctx, error_r))
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (ctx.set->uri == NULL) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *error_r = t_strdup_printf("Error in configuration file %s: "
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen "Missing ldap uri", path);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return NULL;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen }
35de8ec2dbdb8d772593289093e4244c88aef94cTimo Sirainen
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return ctx.set;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen}
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen