>From 3864c725c5d34842ae12615e8b7c00b79a10cc0c Mon Sep 17 00:00:00 2001
From: Simo Sorce <ssorce@redhat.com>
Date: Wed, 4 Nov 2009 17:04:49 -0500
Subject: [PATCH 4/5] Unify parse routines, use maps in generic searches

This remove redundant code and also allows the generic search to be used to use
maps to convert attributes.
---
 server/providers/ldap/sdap.c       |  179 ++++++++++++------------------------
 server/providers/ldap/sdap.h       |   10 +-
 server/providers/ldap/sdap_async.c |   14 ++-
 server/providers/ldap/sdap_async.h |    4 +-
 4 files changed, 77 insertions(+), 130 deletions(-)

diff --git a/server/providers/ldap/sdap.c b/server/providers/ldap/sdap.c
index d9bb323..39c67cc 100644
--- a/server/providers/ldap/sdap.c
+++ b/server/providers/ldap/sdap.c
@@ -68,17 +68,20 @@ int sdap_get_map(TALLOC_CTX *memctx,
 
 /* =Parse-msg============================================================= */
 
-static int sdap_parse_entry(TALLOC_CTX *memctx,
-                            struct sdap_handle *sh, struct sdap_msg *sm,
-                            struct sdap_attr_map *map, int attrs_num,
-                            struct sysdb_attrs **_attrs, char **_dn)
+int sdap_parse_entry(TALLOC_CTX *memctx,
+                     struct sdap_handle *sh, struct sdap_msg *sm,
+                     struct sdap_attr_map *map, int attrs_num,
+                     struct sysdb_attrs **_attrs, char **_dn)
 {
     struct sysdb_attrs *attrs;
     BerElement *ber = NULL;
-    char **vals;
+    struct berval **vals;
+    struct ldb_val v;
     char *str;
     int lerrno;
     int a, i, ret;
+    const char *name;
+    bool store;
 
     lerrno = 0;
     ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
@@ -108,48 +111,64 @@ static int sdap_parse_entry(TALLOC_CTX *memctx,
     }
     ldap_memfree(str);
 
-    vals = ldap_get_values(sh->ldap, sm->msg, "objectClass");
-    if (!vals) {
-        DEBUG(1, ("Unknown entry type, no objectClasses found!\n"));
-        ret = EINVAL;
-        goto fail;
-    }
+    if (map) {
+        vals = ldap_get_values_len(sh->ldap, sm->msg, "objectClass");
+        if (!vals) {
+            DEBUG(1, ("Unknown entry type, no objectClasses found!\n"));
+            ret = EINVAL;
+            goto fail;
+        }
 
-    for (i = 0; vals[i]; i++) {
-        /* the objectclass is always the first name in the map */
-        if (strcasecmp(vals[i], map[0].name) == 0) {
-            /* ok it's a user */
-            break;
+        for (i = 0; vals[i]; i++) {
+            /* the objectclass is always the first name in the map */
+            if (strncasecmp(map[0].name,
+                            vals[i]->bv_val, vals[i]->bv_len) == 0) {
+                /* ok it's an entry of the right type */
+                break;
+            }
         }
+        if (!vals[i]) {
+            DEBUG(1, ("objectClass not matching: %s\n",
+                      map[0].name));
+            ldap_value_free_len(vals);
+            ret = EINVAL;
+            goto fail;
+        }
+        ldap_value_free_len(vals);
     }
-    if (!vals[i]) {
-        DEBUG(1, ("Not a user entry, objectClass not matching: %s\n",
-                  map[0].name));
-        ldap_value_free(vals);
-        ret = EINVAL;
-        goto fail;
-    }
-    ldap_value_free(vals);
 
     str = ldap_first_attribute(sh->ldap, sm->msg, &ber);
     if (!str) {
         ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
         DEBUG(1, ("Entry has no attributes [%d(%s)]!?\n",
                   lerrno, ldap_err2string(lerrno)));
-        ret = EINVAL;
-        goto fail;
+        if (map) {
+            ret = EINVAL;
+            goto fail;
+        }
     }
     while (str) {
-        for (a = 1; a < attrs_num; a++) {
-            /* check if this attr is valid with the chosen schema */
-            if (!map[a].name) continue;
-            /* check if it is an attr we are interested in */
-            if (strcasecmp(str, map[a].name) == 0) break;
-        }
-        if (a < attrs_num) {
+        if (map) {
+            for (a = 1; a < attrs_num; a++) {
+                /* check if this attr is valid with the chosen schema */
+                if (!map[a].name) continue;
+                /* check if it is an attr we are interested in */
+                if (strcasecmp(str, map[a].name) == 0) break;
+            }
             /* interesting attr */
+            if (a < attrs_num) {
+                store = true;
+                name = map[a].sys_name;
+            } else {
+                store = false;
+            }
+        } else {
+            name = str;
+            store = true;
+        }
 
-            vals = ldap_get_values(sh->ldap, sm->msg, str);
+        if (store) {
+            vals = ldap_get_values_len(sh->ldap, sm->msg, str);
             if (!vals) {
                 ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
                 DEBUG(1, ("LDAP Library error: %d(%s)",
@@ -163,96 +182,14 @@ static int sdap_parse_entry(TALLOC_CTX *memctx,
                 goto fail;
             }
             for (i = 0; vals[i]; i++) {
-                ret = sysdb_attrs_add_string(attrs, map[a].sys_name, vals[i]);
+                v.data = (uint8_t *)vals[i]->bv_val;
+                v.length = vals[i]->bv_len;
+
+                ret = sysdb_attrs_add_val(attrs, name, &v);
                 if (ret) goto fail;
             }
-            ldap_value_free(vals);
-        }
-
-        ldap_memfree(str);
-        str = ldap_next_attribute(sh->ldap, sm->msg, ber);
-    }
-    ber_free(ber, 0);
-
-    ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-    if (lerrno) {
-        DEBUG(1, ("LDAP Library error: %d(%s)",
-                  lerrno, ldap_err2string(lerrno)));
-        ret = EIO;
-        goto fail;
-    }
-
-    *_attrs = attrs;
-    return EOK;
-
-fail:
-    if (ber) ber_free(ber, 0);
-    talloc_free(attrs);
-    return ret;
-}
-
-int sdap_parse_generic_entry(TALLOC_CTX *memctx,
-                             struct sdap_handle *sh,
-                             struct sdap_msg *sm,
-                             struct sysdb_attrs **_attrs)
-{
-    struct sysdb_attrs *attrs;
-    BerElement *ber = NULL;
-    struct berval **vals;
-    struct ldb_val v;
-    char *str;
-    int lerrno;
-    int i;
-    int ret;
-
-    lerrno = 0;
-    ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-
-    attrs = sysdb_new_attrs(memctx);
-    if (!attrs) return ENOMEM;
-
-    str = ldap_get_dn(sh->ldap, sm->msg);
-    if (!str) {
-        ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-        DEBUG(1, ("ldap_get_dn failed: %d(%s)\n",
-                  lerrno, ldap_err2string(lerrno)));
-        ret = EIO;
-        goto fail;
-    }
-
-    DEBUG(9, ("OriginalDN: [%s].\n", str));
-    ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, str);
-    if (ret) goto fail;
-    ldap_memfree(str);
-
-    str = ldap_first_attribute(sh->ldap, sm->msg, &ber);
-    if (!str) {
-        ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-        DEBUG(9, ("Entry has no attributes [%d(%s)]!?\n",
-                  lerrno, ldap_err2string(lerrno)));
-    }
-    while (str) {
-        vals = ldap_get_values_len(sh->ldap, sm->msg, str);
-        if (!vals) {
-            ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
-            DEBUG(1, ("LDAP Library error: %d(%s)",
-                      lerrno, ldap_err2string(lerrno)));
-            ret = EIO;
-            goto fail;
-        }
-        if (!vals[0]) {
-            DEBUG(1, ("Missing value after ldap_get_values() ??\n"));
-            ret = EINVAL;
-            goto fail;
-        }
-        for (i = 0; vals[i]; i++) {
-            v.data = (uint8_t *) vals[i]->bv_val;
-            v.length = vals[i]->bv_len;
-
-            ret = sysdb_attrs_add_val(attrs, str, &v);
-            if (ret) goto fail;
+            ldap_value_free_len(vals);
         }
-        ldap_value_free_len(vals);
 
         ldap_memfree(str);
         str = ldap_next_attribute(sh->ldap, sm->msg, ber);
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index 7e5c4b7..fec9eef 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -205,6 +205,11 @@ int sdap_get_map(TALLOC_CTX *memctx,
                  int num_entries,
                  struct sdap_attr_map **_map);
 
+int sdap_parse_entry(TALLOC_CTX *memctx,
+                     struct sdap_handle *sh, struct sdap_msg *sm,
+                     struct sdap_attr_map *map, int attrs_num,
+                     struct sysdb_attrs **_attrs, char **_dn);
+
 int sdap_parse_user(TALLOC_CTX *memctx, struct sdap_options *opts,
                     struct sdap_handle *sh, struct sdap_msg *sm,
                     struct sysdb_attrs **_attrs, char **_dn);
@@ -213,11 +218,6 @@ int sdap_parse_group(TALLOC_CTX *memctx, struct sdap_options *opts,
                      struct sdap_handle *sh, struct sdap_msg *sm,
                      struct sysdb_attrs **_attrs, char **_dn);
 
-int sdap_parse_generic_entry(TALLOC_CTX *memctx,
-                                    struct sdap_handle *sh,
-                                    struct sdap_msg *sm,
-                                    struct sysdb_attrs **_attrs);
-
 int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh,
                     struct sdap_msg *sm, char **_dn);
 
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index e255d15..c7b81ea 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -3287,7 +3287,7 @@ struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx,
 
     subreq = sdap_get_generic_send(state, ev, opts, sh,
                                    "", LDAP_SCOPE_BASE,
-                                   "(objectclass=*)", NULL);
+                                   "(objectclass=*)", NULL, NULL, 0);
     if (!subreq) {
         talloc_zfree(req);
         return NULL;
@@ -3648,6 +3648,8 @@ struct sdap_get_generic_state {
     int scope;
     const char *filter;
     const char **attrs;
+    struct sdap_attr_map *map;
+    int map_num_attrs;
 
     struct sdap_op *op;
 
@@ -3670,7 +3672,9 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
                                          const char *search_base,
                                          int scope,
                                          const char *filter,
-                                         const char **attrs)
+                                         const char **attrs,
+                                         struct sdap_attr_map *map,
+                                         int map_num_attrs)
 {
     struct tevent_req *req = NULL;
     struct sdap_get_generic_state *state = NULL;
@@ -3688,6 +3692,8 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
     state->scope = scope;
     state->filter = filter;
     state->attrs = attrs;
+    state->map = map;
+    state->map_num_attrs = map_num_attrs;
     state->op = NULL;
     state->reply_max = 0;
     state->reply_count = 0;
@@ -3762,7 +3768,9 @@ static void sdap_get_generic_done(struct sdap_op *op,
         break;
 
     case LDAP_RES_SEARCH_ENTRY:
-        ret = sdap_parse_generic_entry(state, state->sh, reply, &attrs);
+        ret = sdap_parse_entry(state, state->sh, reply,
+                               state->map, state->map_num_attrs,
+                               &attrs, NULL);
         if (ret != EOK) {
             DEBUG(1, ("sdap_parse_generic_entry failed.\n"));
             tevent_req_error(req, ENOMEM);
diff --git a/server/providers/ldap/sdap_async.h b/server/providers/ldap/sdap_async.h
index 911933a..955dce4 100644
--- a/server/providers/ldap/sdap_async.h
+++ b/server/providers/ldap/sdap_async.h
@@ -106,7 +106,9 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
                                          const char *search_base,
                                          int scope,
                                          const char *filter,
-                                         const char **attrs);
+                                         const char **attrs,
+                                         struct sdap_attr_map *map,
+                                         int map_num_attrs);
 int sdap_get_generic_recv(struct tevent_req *req,
                          TALLOC_CTX *mem_ctx, size_t *reply_count,
                          struct sysdb_attrs ***reply_list);
-- 
1.6.2.5

