r9912: Fix another bug in ldb_map.
authorJelmer Vernooij <jelmer@samba.org>
Thu, 1 Sep 2005 18:55:51 +0000 (18:55 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:36:21 +0000 (13:36 -0500)
(This used to be commit 4c3b37d660e798764e35a31221f4939ab6f36948)

source4/lib/ldb/modules/ldb_map.c
source4/lib/ldb/modules/ldb_map.h
source4/lib/samba3/PLAN
testprogs/ejs/samba3sam

index f3ece2621ed4ad550fe76c5d10dd52a76d108061..3bbf893a276347faffbe02118e2c97b35c2866a9 100644 (file)
@@ -1001,37 +1001,39 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
        for (i = 0; i < msg->num_elements; i++) {
                const struct ldb_map_attribute *attr;
                struct ldb_message_element *elm = NULL;
-               enum ldb_map_attr_type map_type;
-               int j;
+               int j, k;
                int mapped = 0;
 
                if (ldb_attr_cmp(msg->elements[i].name, "objectClass") == 0)
                        continue;
 
-               attr = map_find_attr_local(privdat, msg->elements[i].name);
+               /* Loop over all attribute_maps with msg->elements[i].name as local_name */
+               for (k = 0; privdat->attribute_maps[k].local_name; k++) {
+                       if (ldb_attr_cmp(msg->elements[i].name, privdat->attribute_maps[k].local_name) != 0)
+                               continue;
 
-               if (!attr) {
-                       ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Undefined local attribute '%s', ignoring\n", msg->elements[i].name);
-                       map_type = MAP_IGNORE;
-               } else map_type = attr->type;
+                       attr = &privdat->attribute_maps[k];
 
-               /* Decide whether or not we need to map or fallback */
-               switch (map_type) {
-               case MAP_GENERATE:
-                       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Generating from %s", attr->local_name);
-                       attr->u.generate.generate_remote(module, attr->local_name, msg, mp, fb);
-                       continue;
-               case MAP_KEEP:
-                       mapped = map_msg_valid_attr(module, mp, attr->local_name);
-                       break;
-               case MAP_IGNORE: mapped = 0; break;
-               case MAP_CONVERT:
-               case MAP_RENAME: mapped = map_msg_valid_attr(module, mp, attr->u.rename.remote_name);
-                       break;
-               }
+                       /* Decide whether or not we need to map or fallback */
+                       switch (attr->type) {
+                       case MAP_GENERATE:
+                               ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Generating from %s", attr->local_name);
+                               attr->u.generate.generate_remote(module, attr->local_name, msg, mp, fb);
+                               mapped++;
+                               continue;
+                       case MAP_KEEP:
+                               if (!map_msg_valid_attr(module, mp, attr->local_name))
+                                       continue;
+                               break;
+                       case MAP_IGNORE: continue; 
+                       case MAP_CONVERT:
+                       case MAP_RENAME: 
+                                if (!map_msg_valid_attr(module, mp, attr->u.rename.remote_name))
+                                        continue;
+                                break;
+                       }
 
-               if (mapped) {
-                       switch (map_type) {
+                       switch (attr->type) {
                        case MAP_KEEP:
                                ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Keeping %s", attr->local_name);
                                elm = talloc(fb, struct ldb_message_element);
@@ -1062,8 +1064,6 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
                                        elm->values[j] = attr->u.convert.convert_local(module, mp, &msg->elements[i].values[j]);
                                }
 
-                               mapped = map_msg_valid_attr(module, mp, attr->u.convert.remote_name);
-
                                break;
 
                        case MAP_GENERATE:
@@ -1071,8 +1071,12 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
                                ldb_debug(module->ldb, LDB_DEBUG_FATAL, "This line should never be reached");
                                continue;
                        } 
+                       
                        ldb_msg_add(module->ldb, mp, elm, 0);
-               } else {
+                       mapped++;
+               } 
+               
+               if (mapped == 0) {
                        ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback storing %s", msg->elements[i].name);
                        elm = talloc(fb, struct ldb_message_element);
 
@@ -1131,69 +1135,82 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
        /* Loop over mi and call generate_remote for each attribute */
        for (i = 0; i < msg->num_elements; i++) {
                const struct ldb_map_attribute *attr;
-               enum ldb_map_attr_type map_type;
+               int k;
+               int mapped = 0;
 
                if (ldb_attr_cmp(msg->elements[i].name, "isMapped") == 0)
                        continue;
 
-               attr = map_find_attr_local(privdat, msg->elements[i].name);
+               for (k = 0; privdat->attribute_maps[k].local_name; k++) 
+               {
+                       if (ldb_attr_cmp(privdat->attribute_maps[k].local_name, msg->elements[i].name) != 0)
+                               continue;
 
-               if (!attr) {
-                       ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Undefined local attribute '%s', ignoring\n", msg->elements[i].name);
-                       map_type = MAP_IGNORE;
-               } else map_type = attr->type;
-       
-               switch (map_type) {
-               case MAP_IGNORE: /* Add to fallback message */
-                       elm = talloc(fb, struct ldb_message_element);
+                       attr = &privdat->attribute_maps[k];
 
-                       elm->num_values = msg->elements[i].num_values;
-                       elm->values = talloc_reference(elm, msg->elements[i].values);
-                       elm->name = talloc_strdup(elm, msg->elements[i].name);
-                       
-                       ldb_msg_add(module->ldb, fb, elm, msg->elements[i].flags);      
-                       break;
-               case MAP_RENAME:
-                       elm = talloc(mp, struct ldb_message_element);
+                       switch (attr->type) {
+                       case MAP_IGNORE: continue;
+                       case MAP_RENAME:
+                                elm = talloc(mp, struct ldb_message_element);
 
-                       elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
-                       elm->num_values = msg->elements[i].num_values;
-                       elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
-                       for (j = 0; j < elm->num_values; j++) {
-                               elm->values[j] = msg->elements[i].values[j];
-                       }
+                                elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
+                                elm->num_values = msg->elements[i].num_values;
+                                elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
+                                for (j = 0; j < elm->num_values; j++) {
+                                        elm->values[j] = msg->elements[i].values[j];
+                                }
 
-                       ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
-                       break;
+                                ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
+                                mapped++;
+                                continue;
 
-               case MAP_CONVERT:
-                       elm = talloc(mp, struct ldb_message_element);
+                       case MAP_CONVERT:
+                                elm = talloc(mp, struct ldb_message_element);
 
-                       elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
-                       elm->num_values = msg->elements[i].num_values;
-                       elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
-                       
-                       for (j = 0; j < elm->num_values; j++) {
-                               elm->values[j] = attr->u.convert.convert_local(module, mp, &msg->elements[i].values[j]);
-                       }
+                                elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
+                                elm->num_values = msg->elements[i].num_values;
+                                elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
 
-                       ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
-                       break;
+                                for (j = 0; j < elm->num_values; j++) {
+                                        elm->values[j] = attr->u.convert.convert_local(module, mp, &msg->elements[i].values[j]);
+                                }
 
-               case MAP_KEEP:
-                       elm = talloc(mp, struct ldb_message_element);
+                                ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
+                                mapped++;
+                                continue;
+
+                       case MAP_KEEP:
+                                elm = talloc(mp, struct ldb_message_element);
+
+                                elm->num_values = msg->elements[i].num_values;
+                                elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
+                                for (j = 0; j < elm->num_values; j++) {
+                                        elm->values[j] = msg->elements[i].values[j];
+                                }
+
+                                elm->name = talloc_strdup(elm, msg->elements[i].name);
+
+                                ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);     
+                                mapped++;
+                                continue;
+
+                       case MAP_GENERATE:
+                                attr->u.generate.generate_remote(module, attr->local_name, msg, mp, fb);
+                                mapped++;
+                                continue;
+                       } 
+               }
+
+               if (mapped == 0) {/* Add to fallback message */
+                       elm = talloc(fb, struct ldb_message_element);
 
                        elm->num_values = msg->elements[i].num_values;
                        elm->values = talloc_reference(elm, msg->elements[i].values);
                        elm->name = talloc_strdup(elm, msg->elements[i].name);
                        
-                       ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);      
-                       break;
+                       ldb_msg_add(module->ldb, fb, elm, msg->elements[i].flags);      
 
-               case MAP_GENERATE:
-                       attr->u.generate.generate_remote(module, attr->local_name, msg, mp, fb);
-                       break;
-               } 
+               }
        }
 
        if (fb->num_elements > 0) {
@@ -1356,7 +1373,11 @@ static struct ldb_val map_convert_local_dn(struct ldb_module *module, TALLOC_CTX
 
        newval = talloc(ctx, struct ldb_val);
        newval->data = (uint8_t *)ldb_dn_linearize(ctx, newdn);
-       newval->length = strlen((char *)newval->data);
+       if (newval->data) {
+               newval->length = strlen((char *)newval->data);
+       } else {
+               newval->length = 0;
+       }
 
        talloc_free(newdn);
 
index 984a4a2cd54c62d197aeac372ef4de5c7d34814b..42eba23aa6270e85be48be3eb834baf6a6a63e8d 100644 (file)
@@ -2,6 +2,7 @@
    ldb database library - map backend
 
    Copyright (C) Jelmer Vernooij 2005
+       Development sponsored by the Google Summer of Code program
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -65,6 +66,9 @@ struct ldb_map_attribute
                struct {
                        const char *remote_name;
                        struct ldb_val (*convert_local) (struct ldb_module *, TALLOC_CTX *, const struct ldb_val *);
+                       
+                       /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name 
+                        * that is non-NULL before it. */
                        struct ldb_val (*convert_remote) (struct ldb_module *, TALLOC_CTX *, const struct ldb_val *);
                } convert;
        
index 916617638b5165776892c19c50077a18ac5e69c8..9a24f702718e68ec9b016043796e3d33a23321eb 100644 (file)
@@ -1,7 +1,2 @@
 TODO (SoC project):
  - fix ntPwdHash / lmPwdHash bug
- - ldb_map
-  - convert_remote() can be NULL!
-  - new way of finding remote attribute in map_add()
-   - loop over all attributes 
-    - if local one present, run!
index 6ca759265065c69ff343cea203c82947b0cd9d96..6ea8da3492eabb1a0e423e4e4896073f9376f73f 100755 (executable)
@@ -128,6 +128,7 @@ assert(msg[0].cn == "Niemand");
 println("Checking for data in destination database");
 msg = s3.search("(cn=Niemand)");
 assert(msg.length >= 1);
+printVars(msg);
 assert(msg[0].sambaSID == "S-1-5-21-4231626423-2410014848-2360679739-2001");
 assert(msg[0].displayName == "Niemand");
 
@@ -189,3 +190,4 @@ println("Checking whether record is gone...");
 msg = s4.search("(cn=Niemand)");
 assert(msg.length == 0);
 
+return 0;