cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING memcached */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi#if defined(BUILTIN_LDAP) || defined(PLUGIN_BUILD)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumistatic const char *LDAP_ESCAPE_CHARS = "*,\\#+<>;\"()= ";
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumivoid ldap_dict_lookup_async(struct dict *dict, const char *key,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi dict_lookup_callback_t *callback, void *context);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumidict_ldap_map_match(const struct dict_ldap_map *map, const char *path,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ARRAY_TYPE(const_string) *values, size_t *pat_len_r,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi size_t *path_len_r, bool partial_ok, bool recurse)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* variable */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* pattern ended with this variable,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi it'll match the rest of the path */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* iterating - the last field never
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi matches fully. if there's a trailing
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi '/', drop it. */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* pattern matches until the next '/' in path */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* no '/' anymore, but it'll still match a
92cbfdaf682dca9cf60243f23c2e911181bfc7abKATOH Yasufumi /* partial matches must end with '/'. */
92cbfdaf682dca9cf60243f23c2e911181bfc7abKATOH Yasufumi /* if we're not recursing, there should be only one $variable
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi return pat[0] == '$' && strchr(pat, '/') == NULL;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumistatic const struct dict_ldap_map *
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumildap_dict_find_map(struct ldap_dict *dict, const char *path,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi t_array_init(values, dict->set->max_attribute_count);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi for (i = 0; i < count; i++) {
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (dict_ldap_map_match(&maps[i], path, values,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumiint dict_ldap_connect(struct ldap_dict *dict, const char **error_r)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi set.max_idle_time_secs = dict->set->max_idle_time;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi return ldap_client_init(&set, &dict->client, error_r);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ((((unsigned char)(c)) & 0x80) != 0 || strchr(LDAP_ESCAPE_CHARS, (c)) != NULL)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumistatic const char *ldap_escape(const char *str)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi str_printfa(ret, "\\%02X", (unsigned char)*p);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumildap_dict_build_query(struct ldap_dict *dict, const struct dict_ldap_map *map,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi template = t_strdup_printf("(&(%s=%s)%s)", map->username_attribute, "%{username}", map->filter);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi for(size_t i = 0; i < array_count(values) && i < array_count(&map->ldap_attributes); i++) {
41e8e807c8e85289bb717a365056b9437555e25aKATOH Yasufumi const char *const *valuep = array_idx(values, i);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const char *const *long_keyp = array_idx(&map->ldap_attributes, i);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if (var_expand(query_r, template, array_idx(&exp, 0), &error) <= 0) {
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi *error_r = t_strdup_printf("Failed to expand %s: %s", template, error);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumiint ldap_dict_init(struct dict *dict_driver, const char *uri,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi pool_t pool = pool_alloconly_create("ldap dict", 2048);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi struct ldap_dict *dict = p_new(pool, struct ldap_dict, 1);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi dict->username = p_strdup(pool, set->username);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi dict->set = dict_ldap_settings_read(pool, uri, error_r);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi struct ldap_dict *ctx = (struct ldap_dict *)dict;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi struct ldap_dict *ctx = (struct ldap_dict *)dict;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumistatic bool ldap_dict_switch_ioloop(struct dict *dict)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi struct ldap_dict *ctx = (struct ldap_dict *)dict;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumivoid ldap_dict_lookup_done(const struct dict_lookup_result *result, void *ctx)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumildap_dict_lookup_callback(struct ldap_result *result, struct dict_ldap_op *op)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi op->res.error = ldap_result_get_error(result);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi i_debug("ldap_dict_lookup_callback got dn %s", ldap_entry_dn(entry));
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi /* try extract value */
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const char *const *values = ldap_entry_get_attribute(entry, op->map->value_attribute);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi i_debug("ldap_dict_lookup_callback got attribute %s", op->map->value_attribute);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi new_values = p_new(op->pool, const char *, 2);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi new_values[0] = p_strdup(op->pool, values[0]);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi i_debug("ldap_dict_lookup_callback dit not get attribute %s", op->map->value_attribute);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumildap_dict_lookup(struct dict *dict, pool_t pool, const char *key,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi ldap_dict_lookup_async(dict, key, ldap_dict_lookup_done, &res);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumistruct dict_iterate_context *ldap_dict_iterate_init(struct dict *dict,
853d58fdf5af0960b7b6edc9dea0fadddb8535f1Elan Ruusamäe const char *const *paths,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi enum dict_iterate_flags flags)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumibool ldap_dict_iterate(struct dict_iterate_context *ctx,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi const char **key_r, const char **value_r)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi return FALSE;
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumiint ldap_dict_iterate_deinit(struct dict_iterate_context *ctx)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumistruct dict_transaction_context ldap_dict_transaction_init(struct dict *dict);
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumiint ldap_dict_transaction_commit(struct dict_transaction_context *ctx,
if (!ldap_dict_build_query(ctx, map, &values, strncmp(key, DICT_PATH_PRIVATE, strlen(DICT_PATH_PRIVATE))==0, query, &error)) {
#ifndef BUILTIN_LDAP
void dict_ldap_deinit(void);