dict-ldap-settings.c revision 2ce0021487fbd7ef3384f3456fa4a176309c4ebf
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2008-2017 Dovecot authors, see the included COPYING file */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *dict_ldap_commonName = "cn";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *dict_ldap_empty_filter = "";
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct dict_ldap_map_attribute) cur_attributes;
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 Sirainenstatic const struct setting_def dict_ldap_map_setting_defs[] = {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *pattern_read_name(const char **pattern)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (*p == '{') {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* ${name} */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* error, but allow anyway */
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen /* $name - ends at the first non-alnum_ character */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (; *p != '\0'; p++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *dict_ldap_attributes_map(struct setting_parser_ctx *ctx)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen const char *p, *name;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen unsigned int i, count;
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 p_array_init(&ctx->cur_map.ldap_attributes, ctx->pool, count);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (*p != '$') {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (i = 0; i < count; i++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return t_strconcat("Missing LDAP attribute for variable: ",
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* mark this attribute as used */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* make sure there aren't any unused attributes */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for (i = 0; i < count; i++) {
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen ctx->cur_map.pattern = p_strdup(ctx->pool, str_c(pattern));
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainenstatic const char *dict_ldap_map_finish(struct setting_parser_ctx *ctx)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Missing setting: pattern";
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen return "Filter must start with (";
75113e5fa7532ef628f273caac2feec6008992c6Timo Sirainen return "Filter must end with )";
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Missing setting: value_attribute";
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 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 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 array_append(&ctx->set->maps, &ctx->cur_map, 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstatic const char *
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenparse_setting(const char *key, const char *value,
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen ctx->set->bind_dn = p_strdup(ctx->pool, value);
902acc26200957a1f04da3cc947211f0b9ffce05Timo Sirainen ctx->set->password = p_strdup(ctx->pool, value);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (str_to_uint(value, &ctx->set->timeout) != 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen return "Invalid timeout value";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (str_to_uint(value, &ctx->set->max_idle_time) != 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return "Invalid max_idle_time value";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen if (str_to_uint(value, &ctx->set->debug) != 0) {
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return "invalid debug value";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return "tls must be yes, try or no";
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return t_strconcat("Value is missing '$' for attribute: ",
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen attribute = array_append_space(&ctx->cur_attributes);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen attribute->variable = p_strdup(ctx->pool, value + 1);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen return t_strconcat("Unknown setting: ", key, NULL);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainenparse_section(const char *type, const char *name ATTR_UNUSED,
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen struct setting_parser_ctx *ctx, const char **error_r)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *error_r = t_strconcat("Unknown section: ", type, NULL);
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainendict_ldap_settings_read(pool_t pool, const char *path, const char **error_r)
73bc59c2a56ff351ae7c4d9f52de76b1b0173995Timo Sirainen ctx.set = p_new(pool, struct dict_ldap_settings, 1);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ctx.set->require_ssl = FALSE; /* try to start SSL */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if (!settings_read(path, NULL, parse_setting, parse_section,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen *error_r = t_strdup_printf("Error in configuration file %s: "