Add LDB_MAP_RENDROP option
authorHoward Chu <hyc@symas.com>
Wed, 18 Sep 2013 23:50:34 +0000 (16:50 -0700)
committerNadezhda Ivanova <nivanova@symas.com>
Tue, 24 Sep 2013 01:40:25 +0000 (18:40 -0700)
Like LDB_MAP_RENAME, but drop the attribute if it occurs in an Add request.
Used for distinguishedName attribute, is read-only and generated but for
some bizarre reason AD allows it in an Add request.

Signed-off-by: Howard Chu <hyc@symas.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Nadezhda Ivanova <nivanova@symas.com>
lib/ldb/ldb_map/ldb_map.c
lib/ldb/ldb_map/ldb_map.h
lib/ldb/ldb_map/ldb_map_inbound.c
lib/ldb/ldb_map/ldb_map_outbound.c
source4/dsdb/samdb/ldb_modules/simple_ldap_map.c

index ce2d660c87eeb5f2ef6243c2f5fcfa0dd4114add..52b483bafe5c1ec80249fbafb9565c571981ee16 100644 (file)
@@ -332,6 +332,7 @@ const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_contex
                        break;
 
                case LDB_MAP_RENAME:
+               case LDB_MAP_RENDROP:
                case LDB_MAP_CONVERT:
                        if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) {
                                return map;
@@ -383,6 +384,7 @@ const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *ma
                return talloc_strdup(mem_ctx, attr);
 
        case LDB_MAP_RENAME:
+       case LDB_MAP_RENDROP:
        case LDB_MAP_CONVERT:
                return talloc_strdup(mem_ctx, map->u.rename.remote_name);
 
@@ -524,6 +526,7 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
                        /* fall through */
                case LDB_MAP_KEEP:
                case LDB_MAP_RENAME:
+               case LDB_MAP_RENDROP:
                        name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i));
                        if (name == NULL) goto failed;
 
@@ -599,6 +602,7 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
                        /* fall through */
                case LDB_MAP_KEEP:
                case LDB_MAP_RENAME:
+               case LDB_MAP_RENDROP:
                        name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i));
                        if (name == NULL) goto failed;
 
index 5db3e02a08a401183d7988bb4cb32359029a9821..46ef3cca45a8a48a39de001aef57c380af9186f9 100644 (file)
@@ -63,9 +63,10 @@ struct ldb_map_attribute {
                LDB_MAP_KEEP,   /* Keep as is. Same name locally and remotely. */
                LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */
                LDB_MAP_CONVERT, /* Rename + convert data */
-               LDB_MAP_GENERATE /* Use generate function for generating new name/data.
+               LDB_MAP_GENERATE, /* Use generate function for generating new name/data.
                                                Used for generating attributes based on 
                                                multiple remote attributes. */
+               LDB_MAP_RENDROP /* Rename the attribute. Strip from Add requests. */
        } type;
        
        /* if set, will be called for search expressions that contain this attribute */
index 38dd5ac066d714e2d7661af592ef64120075ff38..06d52aa1d6374f1c64096ce26ac8a36a9bbf70e4 100644 (file)
@@ -65,7 +65,7 @@ static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *modul
 
 /* Add a message element either to a local or to a remote message,
  * depending on whether it goes into the local or remote partition. */
-static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old)
+static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old)
 {
        const struct ldb_map_context *data = map_get_context(module);
        const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name);
@@ -81,6 +81,13 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
        }
 
        switch (map->type) {
+       case LDB_MAP_RENDROP:
+               if (optype != LDB_ADD) {
+                       /* do the same as LDB_MAP_RENAME */
+                       el = ldb_msg_el_map_local(module, remote, map, old);
+                       break;
+               }
+               /* fall through */
        case LDB_MAP_IGNORE:
                goto local;
 
@@ -157,7 +164,7 @@ static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_mes
 
 /* Split message elements that stay in the local partition from those
  * that are mapped into the remote partition. */
-static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg)
+static int ldb_msg_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg)
 {
        /* const char * const names[]; */
        struct ldb_context *ldb;
@@ -175,7 +182,7 @@ static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *loca
                        continue;
                }
 
-               ret = ldb_msg_el_partition(module, local, remote, msg, msg->elements[i].name, &msg->elements[i]);
+               ret = ldb_msg_el_partition(module, optype, local, remote, msg, msg->elements[i].name, &msg->elements[i]);
                if (ret) {
                        return ret;
                }
@@ -408,7 +415,7 @@ int ldb_map_add(struct ldb_module *module, struct ldb_request *req)
        remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn);
 
        /* Split local from remote message */
-       ldb_msg_partition(module, ac->local_msg, remote_msg, msg);
+       ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg);
 
        /* Prepare the remote operation */
        ret = ldb_build_add_req(&ac->remote_req, ldb,
@@ -518,7 +525,7 @@ int ldb_map_modify(struct ldb_module *module, struct ldb_request *req)
        remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn);
 
        /* Split local from remote message */
-       ldb_msg_partition(module, ac->local_msg, remote_msg, msg);
+       ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg);
 
        /* Prepare the remote operation */
        ret = ldb_build_mod_req(&ac->remote_req, ldb,
index 5be5e765158ccae2122b05bcf38996c602b91a08..b6357bdca332c0f6db0bf733bb018548828e180e 100644 (file)
@@ -134,6 +134,7 @@ static const char **map_attrs_collect_remote(struct ldb_module *module, void *me
                        goto named;
 
                case LDB_MAP_RENAME:
+               case LDB_MAP_RENDROP:
                case LDB_MAP_CONVERT:
                        name = map->u.rename.remote_name;
                        goto named;
@@ -241,7 +242,7 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
 
        for (i = 0; data->attribute_maps[i].local_name; i++) {
                struct ldb_map_attribute *am = &data->attribute_maps[i];
-               if ((am->type == LDB_MAP_RENAME &&
+               if (((am->type == LDB_MAP_RENAME || am->type == LDB_MAP_RENDROP) &&
                        !strcmp(am->u.rename.remote_name, attr_name))
                    || (am->type == LDB_MAP_CONVERT &&
                        !strcmp(am->u.convert.remote_name, attr_name))) {
@@ -306,6 +307,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
                remote_name = attr_name;
                break;
        case LDB_MAP_RENAME:
+       case LDB_MAP_RENDROP:
                remote_name = map->u.rename.remote_name;
                break;
        case LDB_MAP_GENERATE:
@@ -327,6 +329,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
                /* fall through */
        case LDB_MAP_KEEP:
        case LDB_MAP_RENAME:
+       case LDB_MAP_RENDROP:
                old = ldb_msg_find_element(remote, remote_name);
                if (old) {
                        el = ldb_msg_el_map_remote(module, local, map, attr_name, old);
@@ -834,7 +837,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
                return 0;
        }
 
-       if (map->type == LDB_MAP_RENAME) {
+       if (map->type == LDB_MAP_RENAME || map->type == LDB_MAP_RENDROP) {
                /* Nothing more to do here, the attribute has been renamed */
                return 0;
        }
index 918c1bd51ea35928a0bd61622e633ee1ab2caa5f..64dd8635085ec3f49e03c8d88364b18893e0edbb 100644 (file)
@@ -362,7 +362,7 @@ static const struct ldb_map_attribute entryuuid_attributes[] =
        },
        {
                .local_name = "distinguishedName",
-               .type = LDB_MAP_RENAME,
+               .type = LDB_MAP_RENDROP,
                .u = {
                        .rename = {
                                 .remote_name = "entryDN"