From fc104f013254fc9fadaadb02c781cc6e091fc782 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Wed, 23 May 2012 04:21:35 -0400
Subject: [PATCH 1/2] Add support for filtering of attributes

This patch adds support for filtering attributes when constructing
attribute list from a map for LDAP query.
---
 src/providers/ipa/ipa_hosts.c              |    5 +++--
 src/providers/ipa/ipa_id.c                 |    3 ++-
 src/providers/ipa/ipa_netgroups.c          |    2 +-
 src/providers/ipa/ipa_selinux_maps.c       |    3 ++-
 src/providers/ipa/ipa_subdomains_id.c      |    6 ++++--
 src/providers/ldap/ldap_common.c           |    3 ++-
 src/providers/ldap/ldap_id.c               |   12 ++++++------
 src/providers/ldap/ldap_id_enum.c          |    8 ++++----
 src/providers/ldap/ldap_id_netgroup.c      |    4 ++--
 src/providers/ldap/ldap_id_services.c      |    3 ++-
 src/providers/ldap/sdap.c                  |   20 +++++++++++++++++++-
 src/providers/ldap/sdap.h                  |    1 +
 src/providers/ldap/sdap_async_autofs.c     |    6 ++++--
 src/providers/ldap/sdap_async_groups.c     |   10 +++++-----
 src/providers/ldap/sdap_async_initgroups.c |   20 ++++++++++----------
 src/providers/ldap/sdap_async_services.c   |    3 ++-
 src/providers/ldap/sdap_sudo.c             |    2 +-
 17 files changed, 70 insertions(+), 41 deletions(-)

diff --git a/src/providers/ipa/ipa_hosts.c b/src/providers/ipa/ipa_hosts.c
index 09a5acaf81694ff16541f18508d16236db20d383..792af410ea5521d5ae065f8e94c3f026540018dc 100644
--- a/src/providers/ipa/ipa_hosts.c
+++ b/src/providers/ipa/ipa_hosts.c
@@ -103,7 +103,7 @@ ipa_host_info_send(TALLOC_CTX *mem_ctx,
     state->hostgroup_map = hostgroup_map;
 
     ret = build_attrs_from_map(state, host_map, IPA_OPTS_HOST,
-                               &state->attrs, NULL);
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) {
         goto immediate;
     }
@@ -214,7 +214,8 @@ ipa_host_info_done(struct tevent_req *subreq)
     if (state->hostgroup_map) {
         talloc_free(state->attrs);
         ret = build_attrs_from_map(state, state->hostgroup_map,
-                                   IPA_OPTS_HOSTGROUP, &state->attrs, NULL);
+                                   IPA_OPTS_HOSTGROUP, NULL,
+                                   &state->attrs, NULL);
         if (ret != EOK) {
             tevent_req_error(req, ret);
             return;
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index 1f43479986516b806b374f8173cc8c8fd9d6c049..5f5286321dad3f98e619d8abb4f5fab6f0775de4 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -212,7 +212,8 @@ struct tevent_req *ipa_netgroup_get_send(TALLOC_CTX *memctx,
     talloc_zfree(clean_name);
 
     ret = build_attrs_from_map(state, ctx->opts->netgroup_map,
-                               IPA_OPTS_NETGROUP, &state->attrs, NULL);
+                               IPA_OPTS_NETGROUP, NULL,
+                               &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     ret = ipa_netgroup_get_retry(req);
diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
index 881eeb8658a41f7b889a35878ab70ebc79342aa3..7d9a433e06a3c0866aad81955817b9037f4fa54c 100644
--- a/src/providers/ipa/ipa_netgroups.c
+++ b/src/providers/ipa/ipa_netgroups.c
@@ -528,7 +528,7 @@ static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
         return ENOMEM;
 
     ret = build_attrs_from_map(state, state->ipa_opts->host_map,
-                               IPA_OPTS_HOST, &attrs, NULL);
+                               IPA_OPTS_HOST, NULL, &attrs, NULL);
     if (ret != EOK) {
         talloc_free(filter);
         return ret;
diff --git a/src/providers/ipa/ipa_selinux_maps.c b/src/providers/ipa/ipa_selinux_maps.c
index 28923cee1a7db0a137118e25438b0b3755728464..b0a2c8f727be2af0a4eb878f4b5b56a7b0ef11bd 100644
--- a/src/providers/ipa/ipa_selinux_maps.c
+++ b/src/providers/ipa/ipa_selinux_maps.c
@@ -77,7 +77,8 @@ struct tevent_req *ipa_selinux_get_maps_send(TALLOC_CTX *mem_ctx,
     state->maps = NULL;
 
     ret = build_attrs_from_map(state, ipa_opts->selinuxuser_map,
-                               IPA_OPTS_SELINUX_USERMAP, &state->attrs, NULL);
+                               IPA_OPTS_SELINUX_USERMAP, NULL,
+                               &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     state->cur_filter = NULL;
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 39f076cdbd14f1f8c7eb9f84a3073d3b41bd3cdb..eed8170c916e898e758e074d8aeb9503b0784fac 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -89,11 +89,13 @@ struct tevent_req *ipa_get_subdomain_account_info_send(TALLOC_CTX *memctx,
     switch (state->entry_type) {
         case BE_REQ_USER:
             ret = build_attrs_from_map(state, ctx->opts->user_map,
-                                       SDAP_OPTS_USER, &state->attrs, NULL);
+                                       SDAP_OPTS_USER, NULL,
+                                       &state->attrs, NULL);
             break;
         case BE_REQ_GROUP:
             ret = build_attrs_from_map(state, ctx->opts->group_map,
-                                       SDAP_OPTS_GROUP, &state->attrs, NULL);
+                                       SDAP_OPTS_GROUP, NULL,
+                                       &state->attrs, NULL);
             break;
         default:
             ret = EINVAL;
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index dd782815278aeb600bc73bb8211471cd8e6e50cd..22cd7d9a2604d63d2024d0d0ffd578d1ff99726f 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -1303,7 +1303,8 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
-    ret = build_attrs_from_map(tmp_ctx, map, map_size, &expected_attrs, &attr_count);
+    ret = build_attrs_from_map(tmp_ctx, map, map_size, NULL,
+                               &expected_attrs, &attr_count);
     if (ret != EOK) {
         goto done;
     }
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index bdd640a94ed9951a47ee5c48cb612c8e69628730..889fbddc2b5bab94dc0c1ba4b6298076a5965e36 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -151,8 +151,8 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
     }
 
     /* TODO: handle attrs_type */
-    ret = build_attrs_from_map(state, ctx->opts->user_map,
-                               SDAP_OPTS_USER, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, ctx->opts->user_map, SDAP_OPTS_USER,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     ret = users_get_retry(req);
@@ -439,8 +439,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
     }
 
     /* TODO: handle attrs_type */
-    ret = build_attrs_from_map(state, ctx->opts->group_map,
-                               SDAP_OPTS_GROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     ret = groups_get_retry(req);
@@ -631,8 +631,8 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
 
     state->name = name;
 
-    ret = build_attrs_from_map(state, ctx->opts->group_map,
-                               SDAP_OPTS_GROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     ret = groups_by_user_retry(req);
diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c
index 107ab23fa1667792c9be4c8dfa3823e9b0b1175c..53fc99fbafee61b89035d0374bb91bc4ed9fd99f 100644
--- a/src/providers/ldap/ldap_id_enum.c
+++ b/src/providers/ldap/ldap_id_enum.c
@@ -557,8 +557,8 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
     }
 
     /* TODO: handle attrs_type */
-    ret = build_attrs_from_map(state, ctx->opts->user_map,
-                               SDAP_OPTS_USER, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, ctx->opts->user_map, SDAP_OPTS_USER,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     /* TODO: restrict the enumerations to using a single
@@ -716,8 +716,8 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
     }
 
     /* TODO: handle attrs_type */
-    ret = build_attrs_from_map(state, ctx->opts->group_map,
-                               SDAP_OPTS_GROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     /* TODO: restrict the enumerations to using a single
diff --git a/src/providers/ldap/ldap_id_netgroup.c b/src/providers/ldap/ldap_id_netgroup.c
index 7fe7543f81109fe952383bfb51353c41acaaa714..58a9a346232394ec372f221be22a493038c3d22e 100644
--- a/src/providers/ldap/ldap_id_netgroup.c
+++ b/src/providers/ldap/ldap_id_netgroup.c
@@ -98,8 +98,8 @@ struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx,
     }
     talloc_zfree(clean_name);
 
-    ret = build_attrs_from_map(state, ctx->opts->netgroup_map,
-                               SDAP_OPTS_NETGROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, ctx->opts->netgroup_map, SDAP_OPTS_NETGROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     ret = ldap_netgroup_get_retry(req);
diff --git a/src/providers/ldap/ldap_id_services.c b/src/providers/ldap/ldap_id_services.c
index 16d696af4a577f567addc506aefb4e65107f7112..b0291351492b08e729fe39b483c9b8b2588b6110 100644
--- a/src/providers/ldap/ldap_id_services.c
+++ b/src/providers/ldap/ldap_id_services.c
@@ -135,7 +135,8 @@ services_get_send(TALLOC_CTX *mem_ctx,
            state->filter));
 
     ret = build_attrs_from_map(state, id_ctx->opts->service_map,
-                               SDAP_OPTS_SERVICES, &state->attrs, NULL);
+                               SDAP_OPTS_SERVICES, NULL,
+                               &state->attrs, NULL);
     if (ret != EOK) goto error;
 
     ret = services_get_retry(req);
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 01ba418a6e50808552845f6e91db448c57adbb83..cb02f4a5b04f462eb9ba6ad835343fee07539c8b 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1019,10 +1019,28 @@ void sdap_steal_server_opts(struct sdap_id_ctx *id_ctx,
     id_ctx->srv_opts = talloc_move(id_ctx, srv_opts);
 }
 
+static bool attr_is_filtered(const char *attr, const char **filter)
+{
+    int i;
+
+    if (filter) {
+        i = 0;
+        while (filter[i]) {
+            if (filter[i] == attr ||
+                strcasecmp(filter[i], attr) == 0) {
+                return true;
+            }
+            i++;
+        }
+    }
+
+    return false;
+}
 
 int build_attrs_from_map(TALLOC_CTX *memctx,
                          struct sdap_attr_map *map,
                          size_t size,
+                         const char **filter,
                          const char ***_attrs,
                          size_t *attr_count)
 {
@@ -1045,7 +1063,7 @@ int build_attrs_from_map(TALLOC_CTX *memctx,
 
     /* add the others */
     for (i = j = 1; i < size; i++) {
-        if (map[i].name) {
+        if (map[i].name && !attr_is_filtered(map[i].name, filter)) {
             attrs[j] = map[i].name;
             j++;
         }
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 61f899f31618deeba8496a4874ef482be2ba78d3..90558221a83c82a8166f807c6f55b9155ff322c5 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -454,6 +454,7 @@ bool sdap_check_sup_list(struct sup_list *l, const char *val);
 int build_attrs_from_map(TALLOC_CTX *memctx,
                          struct sdap_attr_map *map,
                          size_t size,
+                         const char **filter,
                          const char ***_attrs,
                          size_t *attr_count);
 
diff --git a/src/providers/ldap/sdap_async_autofs.c b/src/providers/ldap/sdap_async_autofs.c
index d8a2d0eec75c3e42cd3dc39930d20a0a51e2c541..9c8337d33f4772d1be717999184896e7e6553ce1 100644
--- a/src/providers/ldap/sdap_async_autofs.c
+++ b/src/providers/ldap/sdap_async_autofs.c
@@ -242,7 +242,8 @@ automntmaps_process_members_send(TALLOC_CTX *mem_ctx,
     }
 
     ret = build_attrs_from_map(state, opts->autofs_entry_map,
-                               SDAP_OPTS_AUTOFS_ENTRY, &state->attrs, NULL);
+                               SDAP_OPTS_AUTOFS_ENTRY, NULL,
+                               &state->attrs, NULL);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to build attributes from map\n"));
         ret = ENOMEM;
@@ -674,7 +675,8 @@ sdap_autofs_setautomntent_send(TALLOC_CTX *memctx,
     talloc_free(clean_mapname);
 
     ret = build_attrs_from_map(state, state->opts->autofs_mobject_map,
-                               SDAP_OPTS_AUTOFS_MAP, &state->attrs, NULL);
+                               SDAP_OPTS_AUTOFS_MAP, NULL,
+                               &state->attrs, NULL);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to build attributes from map\n"));
         ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index c3cc2ac92b80a52632655be03f8386ab2e68d7b9..678925681bc4e2a81558c76f3eff59cd17838524 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -601,7 +601,7 @@ struct tevent_req *sdap_process_group_send(TALLOC_CTX *memctx,
     if (!req) return NULL;
 
     ret = build_attrs_from_map(grp_state, opts->user_map, SDAP_OPTS_USER,
-                               &attrs, NULL);
+                               NULL, &attrs, NULL);
     if (ret) {
         goto done;
     }
@@ -2384,8 +2384,8 @@ sdap_nested_group_process_deref_call(struct tevent_req *req)
 
     /* Pull down the whole group map, but only pull down username
      * and originalDN for users. */
-    ret = build_attrs_from_map(state, state->opts->group_map,
-                               SDAP_OPTS_GROUP, &sdap_attrs, &attr_count);
+    ret = build_attrs_from_map(state, state->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &sdap_attrs, &attr_count);
     if (ret != EOK) goto fail;
 
     sdap_attrs = talloc_realloc(NULL, sdap_attrs, const char *,
@@ -2587,8 +2587,8 @@ static errno_t sdap_nested_group_lookup_group(struct tevent_req *req)
         return EOK;
     }
 
-    ret = build_attrs_from_map(state, state->opts->group_map,
-                               SDAP_OPTS_GROUP, &sdap_attrs, NULL);
+    ret = build_attrs_from_map(state, state->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &sdap_attrs, NULL);
     if (ret != EOK) {
         return ret;
     }
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index b883ccf938348f9f5dda4ed43bf714973072c9f9..afb1b5b49fb477ea2d6e5e18910e2262a0ca1cb2 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -353,8 +353,8 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
         return NULL;
     }
 
-    ret = build_attrs_from_map(state, opts->group_map,
-                               SDAP_OPTS_GROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) {
         talloc_free(req);
         return NULL;
@@ -843,8 +843,8 @@ static errno_t sdap_initgr_nested_deref_search(struct tevent_req *req)
     maps[0].num_attrs = SDAP_OPTS_GROUP;
     maps[1].map = NULL;
 
-    ret = build_attrs_from_map(state, state->opts->group_map,
-                               SDAP_OPTS_GROUP, &sdap_attrs, NULL);
+    ret = build_attrs_from_map(state, state->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &sdap_attrs, NULL);
     if (ret != EOK) goto fail;
 
     timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
@@ -1495,8 +1495,8 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
         return NULL;
     }
 
-    ret = build_attrs_from_map(state, opts->group_map,
-                               SDAP_OPTS_GROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) goto done;
 
     ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
@@ -2168,8 +2168,8 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
         goto done;
     }
 
-    ret = build_attrs_from_map(state, state->opts->group_map,
-                               SDAP_OPTS_GROUP, &state->attrs, NULL);
+    ret = build_attrs_from_map(state, state->opts->group_map, SDAP_OPTS_GROUP,
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) {
         goto done;
     }
@@ -2504,8 +2504,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
         return NULL;
     }
 
-    ret = build_attrs_from_map(state, state->opts->user_map,
-                               SDAP_OPTS_USER, &state->user_attrs, NULL);
+    ret = build_attrs_from_map(state, state->opts->user_map, SDAP_OPTS_USER,
+                               NULL, &state->user_attrs, NULL);
     if (ret) {
         talloc_zfree(req);
         return NULL;
diff --git a/src/providers/ldap/sdap_async_services.c b/src/providers/ldap/sdap_async_services.c
index 895ea7e7b109489504367fb4b82121156da0c23f..a59db6c66a201f4665f5317835d7e94380eb3592 100644
--- a/src/providers/ldap/sdap_async_services.c
+++ b/src/providers/ldap/sdap_async_services.c
@@ -572,7 +572,8 @@ enum_services_send(TALLOC_CTX *memctx,
 
     /* TODO: handle attrs_type */
     ret = build_attrs_from_map(state, id_ctx->opts->service_map,
-                               SDAP_OPTS_SERVICES, &state->attrs, NULL);
+                               SDAP_OPTS_SERVICES, NULL,
+                               &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
     subreq = sdap_get_services_send(state, state->ev,
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 23fd062ccb44a29626a0f055578dd71348e71d93..75d30430c42691ed49e54f7fcbd8cf211f823e74 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -456,7 +456,7 @@ struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
 
     /* create attrs from map */
     ret = build_attrs_from_map(state, opts->sudorule_map, SDAP_OPTS_SUDO,
-                               &state->attrs, NULL);
+                               NULL, &state->attrs, NULL);
     if (ret != EOK) {
         goto fail;
     }
-- 
1.7.7.6

