From 0f5b2b717a2dc3877484e18ca4854940afd46f73 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Fri, 5 Nov 2010 11:05:38 -0400
Subject: [PATCH] Sanitize search filters in LDAP provider

---
 src/providers/ldap/ldap_id.c             |   18 +++++++++++++++-
 src/providers/ldap/ldap_id_netgroup.c    |    9 +++++++-
 src/providers/ldap/sdap_access.c         |   10 ++++++++-
 src/providers/ldap/sdap_async_accounts.c |   31 +++++++++++++++++++++++++++--
 4 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 91b6c8addc79b6e5a8762aa5799acd2e11071906..07e3ae17954cacef2a81edc226e3b87786d70576 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -64,6 +64,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
     struct tevent_req *req;
     struct users_get_state *state;
     const char *attr_name;
+    char *clean_name;
     int ret;
 
     req = tevent_req_create(memctx, &state, struct users_get_state);
@@ -97,14 +98,20 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
         goto fail;
     }
 
+    ret = sss_filter_sanitize(state, name, &clean_name);
+    if (ret != EOK) {
+        goto fail;
+    }
+
     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
-                                    attr_name, name,
+                                    attr_name, clean_name,
                                     ctx->opts->user_map[SDAP_OC_USER].name);
     if (!state->filter) {
         DEBUG(2, ("Failed to build filter\n"));
         ret = ENOMEM;
         goto fail;
     }
+    talloc_zfree(clean_name);
 
     /* TODO: handle attrs_type */
     ret = build_attrs_from_map(state, ctx->opts->user_map,
@@ -290,6 +297,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
     struct tevent_req *req;
     struct groups_get_state *state;
     const char *attr_name;
+    char *clean_name;
     int ret;
 
     req = tevent_req_create(memctx, &state, struct groups_get_state);
@@ -323,14 +331,20 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
         goto fail;
     }
 
+    ret = sss_filter_sanitize(state, name, &clean_name);
+    if (ret != EOK) {
+        goto fail;
+    }
+
     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
-                                    attr_name, name,
+                                    attr_name, clean_name,
                                     ctx->opts->group_map[SDAP_OC_GROUP].name);
     if (!state->filter) {
         DEBUG(2, ("Failed to build filter\n"));
         ret = ENOMEM;
         goto fail;
     }
+    talloc_zfree(clean_name);
 
     /* TODO: handle attrs_type */
     ret = build_attrs_from_map(state, ctx->opts->group_map,
diff --git a/src/providers/ldap/ldap_id_netgroup.c b/src/providers/ldap/ldap_id_netgroup.c
index c82ccc4399dd9840ac1c6d820da7206249553f73..6a668a1d6a007d5d45e77d52048cc71334546834 100644
--- a/src/providers/ldap/ldap_id_netgroup.c
+++ b/src/providers/ldap/ldap_id_netgroup.c
@@ -59,6 +59,7 @@ struct tevent_req *netgroup_get_send(TALLOC_CTX *memctx,
 {
     struct tevent_req *req;
     struct netgroup_get_state *state;
+    char *clean_name;
     int ret;
 
     req = tevent_req_create(memctx, &state, struct netgroup_get_state);
@@ -79,15 +80,21 @@ struct tevent_req *netgroup_get_send(TALLOC_CTX *memctx,
     state->domain = state->ctx->be->domain;
     state->name = name;
 
+    ret = sss_filter_sanitize(state, name, &clean_name);
+    if (ret != EOK) {
+        goto fail;
+    }
+
     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
                             ctx->opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name,
-                            name,
+                            clean_name,
                             ctx->opts->netgroup_map[SDAP_OC_NETGROUP].name);
     if (!state->filter) {
         DEBUG(2, ("Failed to build filter\n"));
         ret = ENOMEM;
         goto fail;
     }
+    talloc_zfree(clean_name);
 
     ret = build_attrs_from_map(state, ctx->opts->netgroup_map,
                                SDAP_OPTS_NETGROUP, &state->attrs);
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index 4a30b74be723921bea2e9afddc74767fd9f30d5d..23c076f1fc920d6db4cc53892374dcfad9ada3cb 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -114,6 +114,7 @@ static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx,
     struct tevent_req *req;
     struct ldb_result *res;
     const char *basedn;
+    char *clean_username;
 
     req = tevent_req_create(mem_ctx, &state, struct sdap_access_req_ctx);
     if (req == NULL) {
@@ -204,17 +205,24 @@ static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx,
     talloc_zfree(res);
 
     /* Construct the filter */
+
+    ret = sss_filter_sanitize(state, state->username, &clean_username);
+    if (ret != EOK) {
+        goto failed;
+    }
+
     state->filter = talloc_asprintf(
         state,
         "(&(%s=%s)(objectclass=%s)%s)",
         state->sdap_ctx->opts->user_map[SDAP_AT_USER_NAME].name,
-        state->username,
+        clean_username,
         state->sdap_ctx->opts->user_map[SDAP_OC_USER].name,
         state->access_ctx->filter);
     if (state->filter == NULL) {
         DEBUG(0, ("Could not construct access filter\n"));
         goto failed;
     }
+    talloc_zfree(clean_username);
 
     DEBUG(6, ("Checking filter against LDAP\n"));
 
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 6f4532eea31ff4a027c221983bf91ef06ea66f58..4a1ff4ff310408e47fd3f769677ca77d705ff5ac 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -1857,6 +1857,7 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
     struct sdap_initgr_rfc2307_state *state;
     const char *filter;
     const char **attrs;
+    char *clean_name;
     errno_t ret;
 
     req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307_state);
@@ -1881,13 +1882,21 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
         return NULL;
     }
 
+    ret = sss_filter_sanitize(state, name, &clean_name);
+    if (ret != EOK) {
+        talloc_free(req);
+        return NULL;
+    }
+
     filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
                              opts->group_map[SDAP_AT_GROUP_MEMBER].name,
-                             name, opts->group_map[SDAP_OC_GROUP].name);
+                             clean_name,
+                             opts->group_map[SDAP_OC_GROUP].name);
     if (!filter) {
         talloc_zfree(req);
         return NULL;
     }
+    talloc_zfree(clean_name);
 
     subreq = sdap_get_generic_send(state, state->ev, state->opts,
                                    state->sh, base_dn, LDAP_SCOPE_SUBTREE,
@@ -3120,6 +3129,7 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
     struct sdap_initgr_rfc2307_state *state;
     const char *filter;
     const char **attrs;
+    char *clean_orig_dn;
 
     req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307_state);
     if (!req) return NULL;
@@ -3139,13 +3149,21 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
         return NULL;
     }
 
+    ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
+    if (ret != EOK) {
+        talloc_free(req);
+        return NULL;
+    }
+
     filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
                              opts->group_map[SDAP_AT_GROUP_MEMBER].name,
-                             orig_dn, opts->group_map[SDAP_OC_GROUP].name);
+                             clean_orig_dn,
+                             opts->group_map[SDAP_OC_GROUP].name);
     if (!filter) {
         talloc_zfree(req);
         return NULL;
     }
+    talloc_zfree(clean_orig_dn);
 
     DEBUG(6, ("Looking up parent groups for user [%s]\n", orig_dn));
     subreq = sdap_get_generic_send(state, state->ev, state->opts,
@@ -3451,6 +3469,7 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
     char *filter;
     const char *orig_dn;
     const char **attrs;
+    char *clean_orig_dn;
     struct sdap_rfc2307bis_nested_ctx *state =
             tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx);
 
@@ -3525,15 +3544,21 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
         goto error;
     }
 
+    ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
+    if (ret != EOK) {
+        goto error;
+    }
+
     filter = talloc_asprintf(
             tmp_ctx, "(&(%s=%s)(objectclass=%s))",
             state->opts->group_map[SDAP_AT_GROUP_MEMBER].name,
-            orig_dn,
+            clean_orig_dn,
             state->opts->group_map[SDAP_OC_GROUP].name);
     if (!filter) {
         ret = ENOMEM;
         goto error;
     }
+    talloc_zfree(clean_orig_dn);
 
     DEBUG(6, ("Looking up parent groups for group [%s]\n", orig_dn));
     subreq = sdap_get_generic_send(state, state->ev, state->opts,
-- 
1.7.3.2

