r9744: - [upgrade.js] Start working on smb.conf conversion.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 29 Aug 2005 15:54:10 +0000 (15:54 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:34:55 +0000 (13:34 -0500)
- [ldb_map] Support storing non-mappable data in a fallback LDB

source/lib/ldb/ldb_map/ldb_map.c
source/lib/ldb/ldb_map/ldb_map.h
source/lib/ldb/samba/samba3sam.c
source/lib/ldb/tests/test-samba3sam.sh
source/lib/samba3/PLAN
source/scripting/libjs/upgrade.js
source/setup/upgrade

index 1a8ea2afc4071f733b8f539688098efc77bcccf9..79d3c26f9061638a39a60b750dddf2e7d9ff0180 100644 (file)
  *     (use MAP_GENERATE instead ?) 
  */
 
+/*
+ - special attribute 'isMapped'
+ - add/modify
+       - split up ldb_message into fallback and mapped parts if is_mappable
+ - search: 
+       - search local one for not isMapped entries
+       - remove remote attributes from ldb_parse_tree
+       - search remote one
+        - per record, search local one for additional data (by dn)
+        - test if (full expression) is now true
+ - delete
+       - delete both
+ - rename
+       - rename locally and remotely
+*/
+
 static const struct ldb_map_attribute builtin_attribute_maps[];
 
 struct map_private {
@@ -41,6 +57,16 @@ struct map_private {
        const char *last_err_string;
 };
 
+static struct ldb_map_context *map_get_privdat(struct ldb_module *module)
+{
+       return &((struct map_private *)module->private_data)->context;
+}
+
+static BOOL map_is_mappable(struct ldb_map_context *privdat, const struct ldb_message *msg)
+{
+       /* FIXME */
+       return True;
+}
 
 /* find an attribute by the local name */
 static const struct ldb_map_attribute *map_find_attr_local(struct ldb_map_context *privdat, const char *attr)
@@ -88,7 +114,7 @@ static struct ldb_parse_tree *ldb_map_parse_tree(struct ldb_module *module, TALL
        struct ldb_parse_tree *new_tree;
        enum ldb_map_attr_type map_type;
        struct ldb_val value, newvalue;
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
 
        if (tree == NULL)
                return NULL;
@@ -103,16 +129,31 @@ static struct ldb_parse_tree *ldb_map_parse_tree(struct ldb_module *module, TALL
                
                new_tree = talloc_memdup(ctx, tree, sizeof(*tree));
                new_tree->u.list.elements = talloc_array(new_tree, struct ldb_parse_tree *, tree->u.list.num_elements);
-               for (i = 0; i < new_tree->u.list.num_elements; i++) {
-                       new_tree->u.list.elements[i] = ldb_map_parse_tree(module, new_tree, tree->u.list.elements[i]);
+               new_tree->u.list.num_elements = 0;
+               for (i = 0; i < tree->u.list.num_elements; i++) {
+                       struct ldb_parse_tree *child = ldb_map_parse_tree(module, new_tree, tree->u.list.elements[i]);
+                       
+                       if (child) {
+                               new_tree->u.list.elements[i] = child;
+                               new_tree->u.list.num_elements++;
+                       }
                }
 
                return new_tree;
        }
                
        if (tree->operation == LDB_OP_NOT) {
+               struct ldb_parse_tree *child;
+               
                new_tree = talloc_memdup(ctx, tree, sizeof(*tree));
-               new_tree->u.isnot.child = ldb_map_parse_tree(module, new_tree, tree->u.isnot.child);
+               child = ldb_map_parse_tree(module, new_tree, tree->u.isnot.child);
+
+               if (!child) {
+                       talloc_free(new_tree);
+                       return NULL;
+               }
+
+               new_tree->u.isnot.child = child;
                return new_tree;
        }
 
@@ -125,7 +166,7 @@ static struct ldb_parse_tree *ldb_map_parse_tree(struct ldb_module *module, TALL
        attr = map_find_attr_local(privdat, tree->u.equality.attr);
 
        if (!attr) {
-               DEBUG(0, ("Unable to find local attribute '%s', leaving as is\n", tree->u.equality.attr));
+               ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Unable to find local attribute '%s', leaving as is\n", tree->u.equality.attr);
                map_type = MAP_KEEP;
        } else {
                map_type = attr->type;
@@ -137,12 +178,12 @@ static struct ldb_parse_tree *ldb_map_parse_tree(struct ldb_module *module, TALL
        }
 
        if (map_type == MAP_IGNORE) {
-               DEBUG(0, ("Search on ignored attribute '%s'!\n", tree->u.equality.attr));
+               ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Search on ignored attribute '%s'\n", tree->u.equality.attr);
                return NULL;
        }
 
        if (map_type == MAP_GENERATE) {
-               DEBUG(0, ("Can't do conversion for MAP_GENERATE in map_parse_tree without convert_operator for '%s'\n", tree->u.equality.attr));
+               ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Can't do conversion for MAP_GENERATE in map_parse_tree without convert_operator for '%s'\n", tree->u.equality.attr);
                return NULL;
        }
 
@@ -307,7 +348,7 @@ static const char **ldb_map_attrs(struct ldb_module *module, const char *const a
        int i;
        const char **ret;
        int ar_size = 0, last_element = 0;
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
 
        if (attrs == NULL) 
                return NULL;
@@ -324,7 +365,7 @@ static const char **ldb_map_attrs(struct ldb_module *module, const char *const a
                enum ldb_map_attr_type map_type;
 
                if (!attr) {
-                       DEBUG(0, ("Local attribute '%s' does not have a definition!\n", attrs[i]));
+                       ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Local attribute '%s' does not have a definition!\n", attrs[i]);
                        map_type = MAP_IGNORE;
                } else map_type = attr->type;
 
@@ -377,7 +418,7 @@ static const char **ldb_map_attrs(struct ldb_module *module, const char *const a
 
 static const char **available_local_attributes(struct ldb_module *module, const struct ldb_message *msg)
 {
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
        int i, j;
        int count = 0;
        const char **ret = talloc_array(module, const char *, 1);
@@ -428,11 +469,13 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
        int i, j;
        struct ldb_message *msg = talloc_zero(module, struct ldb_message);
        struct ldb_message_element *elm, *oldelm;
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
        const char **newattrs = NULL;
 
        msg->dn = map_remote_dn(privdat, module, mi->dn);
 
+       ldb_msg_add_string(module->ldb, msg, "mappedFromDn", ldb_dn_linearize(msg, mi->dn));
+
        /* Loop over attrs, find in ldb_map_attribute array and 
         * run generate() */
 
@@ -448,7 +491,7 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
                enum ldb_map_attr_type map_type;
 
                if (!attr) {
-                       DEBUG(0, ("Unable to find local attribute '%s' when generating incoming message\n", attrs[i]));
+                       ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Unable to find local attribute '%s' when generating incoming message\n", attrs[i]);
                        map_type = MAP_IGNORE;
                } else map_type = attr->type;
 
@@ -501,7 +544,7 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
                                ldb_msg_add(module->ldb, msg, elm, elm->flags);
                                break;
                        default: 
-                               DEBUG(0, ("Unknown attr->type for %s", attr->local_name));
+                               ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Unknown attr->type for %s", attr->local_name);
                                break;
                }
        }
@@ -512,13 +555,18 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
 }
 
 /* Used for add, modify */
-static struct ldb_message *ldb_map_message_outgoing(struct ldb_module *module, const struct ldb_message *mo)
+static int ldb_map_message_outgoing(struct ldb_module *module, const struct ldb_message *mo, struct ldb_message **fb, struct ldb_message **mp)
 {
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
        struct ldb_message *msg = talloc_zero(module, struct ldb_message);
        struct ldb_message_element *elm;
        int i,j;
-       
+
+       *fb = talloc_zero(module, struct ldb_message);
+       (*fb)->dn = talloc_reference(*fb, mo->dn);
+
+       *mp = msg;
+
        msg->private_data = mo->private_data;
        
        msg->dn = map_local_dn(privdat, module, mo->dn);
@@ -529,13 +577,21 @@ static struct ldb_message *ldb_map_message_outgoing(struct ldb_module *module, c
                enum ldb_map_attr_type map_type;
 
                if (!attr) {
-                       DEBUG(0, ("Undefined local attribute '%s', ignoring\n", mo->elements[i].name));
+                       ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Undefined local attribute '%s', ignoring\n", mo->elements[i].name);
                        map_type = MAP_IGNORE;
                        continue;
                } else map_type = attr->type;
 
                switch (map_type) {
-               case MAP_IGNORE: break;
+               case MAP_IGNORE: /* Add to fallback message */
+                       elm = talloc(*fb, struct ldb_message_element);
+
+                       elm->num_values = mo->elements[i].num_values;
+                       elm->values = talloc_reference(elm, mo->elements[i].values);
+                       elm->name = talloc_strdup(elm, mo->elements[i].name);
+                       
+                       ldb_msg_add(module->ldb, *fb, elm, mo->elements[i].flags);      
+                       break;
                case MAP_RENAME:
                        elm = talloc(msg, struct ldb_message_element);
 
@@ -576,22 +632,25 @@ static struct ldb_message *ldb_map_message_outgoing(struct ldb_module *module, c
                } 
        }
 
-       return msg;
+       return 0;
 }
 
+
 /*
   rename a record
 */
 static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
 {
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
        struct ldb_dn *n_olddn, *n_newdn;
        int ret;
+
+       ret = ldb_next_rename_record(module, olddn, newdn);
        
        n_olddn = map_local_dn(privdat, module, olddn);
        n_newdn = map_local_dn(privdat, module, newdn);
 
-       ret = ldb_next_rename_record(module, n_olddn, n_newdn);
+       ret = ldb_rename(privdat->mapped_ldb, n_olddn, n_newdn);
 
        talloc_free(n_olddn);
        talloc_free(n_newdn);
@@ -604,53 +663,149 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con
 */
 static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
 {
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       struct ldb_map_context *privdat = map_get_privdat(module);
        struct ldb_dn *newdn;
        int ret;
 
+       ret = ldb_next_delete_record(module, dn);
+       
        newdn = map_local_dn(privdat, module, dn);
 
-       ret = ldb_next_delete_record(module, newdn);
+       ret = ldb_delete(privdat->mapped_ldb, newdn);
 
        talloc_free(newdn);
 
        return ret;
 }
 
-/*
-  search for matching records using a ldb_parse_tree
-*/
-static int map_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
+/* search fallback database */
+static int map_search_bytree_fb(struct ldb_module *module, const struct ldb_dn *base,
                              enum ldb_scope scope, struct ldb_parse_tree *tree,
                              const char * const *attrs, struct ldb_message ***res)
 {
        int ret;
-       const char **newattrs;
+       struct ldb_parse_tree t_and, t_not, t_present, *childs[2];
+
+       t_present.operation = LDB_OP_PRESENT;
+       t_present.u.present.attr = talloc_strdup(NULL, "isMapped");
+
+       t_not.operation = LDB_OP_NOT;
+       t_not.u.isnot.child = &t_present;
+
+       childs[0] = &t_not;
+       childs[1] = tree;
+       t_and.operation = LDB_OP_AND;
+       t_and.u.list.num_elements = 2;
+       t_and.u.list.elements = childs;
+       
+       ret = ldb_next_search_bytree(module, base, scope, &t_and, attrs, res);
+
+       talloc_free(t_present.u.present.attr);
+
+       return ret;
+}
+
+static int map_search_bytree_mp(struct ldb_module *module, const struct ldb_dn *base,
+                             enum ldb_scope scope, struct ldb_parse_tree *tree,
+                             const char * const *attrs, struct ldb_message ***res)
+{
        struct ldb_parse_tree *new_tree;
        struct ldb_dn *new_base;
        struct ldb_message **newres;
-       struct ldb_map_context *privdat = &((struct map_private *)module->private_data)->context;
+       const char **newattrs;
+       int mpret, ret;
+       struct ldb_map_context *privdat = map_get_privdat(module);
        int i;
 
+       /*- search mapped database */
+
        new_tree = ldb_map_parse_tree(module, module, tree);
        newattrs = ldb_map_attrs(module, attrs); 
        new_base = map_local_dn(privdat, module, base);
 
-       ret = ldb_next_search_bytree(module, new_base, scope, new_tree, newattrs, &newres);
+       mpret = ldb_search_bytree(privdat->mapped_ldb, new_base, scope, new_tree, newattrs, &newres);
 
        talloc_free(new_base);
        talloc_free(new_tree);
        talloc_free(newattrs);
 
-       *res = talloc_array(module, struct ldb_message *, ret);
+       /*
+        - per returned record, search local one for additional data (by dn)
+        - test if (full expression) is now true
+       */
+
+
+       *res = talloc_array(module, struct ldb_message *, mpret);
 
-       for (i = 0; i < ret; i++) {
-               (*res)[i] = ldb_map_message_incoming(module, attrs, newres[i]);
+       ret = 0;
+
+       for (i = 0; i < mpret; i++) {
+               struct ldb_message *merged = ldb_map_message_incoming(module, attrs, newres[i]);
+               struct ldb_message **extrares = NULL;
+               int extraret;
+               
+               /* Merge with additional data from local database */
+               extraret = ldb_next_search(module, merged->dn, LDB_SCOPE_ONELEVEL, "", NULL, &extrares);
+
+               if (extraret > 1) {
+                       ldb_debug(module->ldb, LDB_DEBUG_ERROR, "More then one result for extra data!\n");
+                       return -1;
+               } else if (extraret == 1) {
+                       int j;
+                       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Extra data found for remote DN");
+                       for (j = 0; j < merged->num_elements; j++) {
+                               ldb_msg_add(module->ldb, merged, &extrares[0]->elements[j], extrares[0]->elements[j].flags);
+                       }
+               } else {
+                       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "No extra data found for remote DN");
+               }
+
+               talloc_free(extrares);
+               
+               if (ldb_match_msg(module->ldb, merged, tree, base, scope)) {
+                       (*res)[ret] = merged;
+                       ret++;
+               } else {
+                       ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Discarded merged message because it did not match");
+               }
+               
                talloc_free(newres[i]);
        }
 
        return ret;
 }
+
+
+/*
+  search for matching records using a ldb_parse_tree
+*/
+static int map_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
+                             enum ldb_scope scope, struct ldb_parse_tree *tree,
+                             const char * const *attrs, struct ldb_message ***res)
+{
+       int ret;
+       struct ldb_message **fbres, **mpres;
+       int i;
+       int ret_fb, ret_mp;
+
+       ret_fb = map_search_bytree_fb(module, base, scope, tree, attrs, &fbres);
+       if (ret_fb == -1)
+               return -1;
+
+       ret_mp = map_search_bytree_mp(module, base, scope, tree, attrs, &mpres);
+       if (ret_mp == -1)
+               return -1;
+
+       /* Merge results */
+       *res = talloc_array(module, struct ldb_message *, ret_fb + ret_mp);
+
+       for (i = 0; i < ret_fb; i++) (*res)[i] = fbres[i];
+       for (i = 0; i < ret_mp; i++) (*res)[ret_fb+i] = mpres[i];
+
+       return ret_fb + ret_mp;
+       
+       return ret;
+}
 /*
   search for matching records
 */
@@ -678,12 +833,33 @@ static int map_search(struct ldb_module *module, const struct ldb_dn *base,
 */
 static int map_add(struct ldb_module *module, const struct ldb_message *msg)
 {
-       struct ldb_message *nmsg = ldb_map_message_outgoing(module, msg);
        int ret;
+       struct ldb_map_context *privdat = map_get_privdat(module);
+       struct ldb_message *fb, *mp;
 
-       ret = ldb_next_add_record(module, nmsg);
+       if (!map_is_mappable(privdat, msg)) {
+               return ldb_next_add_record(module, msg);
+       }
 
-       talloc_free(nmsg);
+       if (ldb_map_message_outgoing(module, msg, &fb, &mp) == -1)
+               return -1;
+               
+       ldb_msg_add_string(module->ldb, fb, "isMapped", "TRUE");
+
+       ret = ldb_next_add_record(module, fb);
+       if (ret == -1) {
+               ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Adding fallback record failed");
+               return -1;
+       }
+               
+       ret = ldb_add(privdat->mapped_ldb, mp);
+       if (ret == -1) {
+               ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Adding mapped record failed");
+               return -1;
+       }
+
+       talloc_free(fb);
+       talloc_free(mp);
 
        return ret;
 }
@@ -694,12 +870,25 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
 */
 static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
 {
-       struct ldb_message *nmsg = ldb_map_message_outgoing(module, msg);
+       struct ldb_map_context *privdat = map_get_privdat(module);
+       struct ldb_message *fb, *mp;
        int ret;
 
-       ret = ldb_next_modify_record(module, nmsg);
+       if (!map_is_mappable(privdat, msg))
+               return ldb_next_modify_record(module, msg);
+               
+
+       if (ldb_map_message_outgoing(module, msg, &fb, &mp) == -1)
+               return -1;
+               
+       ldb_msg_add_string(module->ldb, fb, "isMapped", "TRUE");
+
+       ret = ldb_next_modify_record(module, fb);
+
+       ret = ldb_modify(privdat->mapped_ldb, mp);
 
-       talloc_free(nmsg);
+       talloc_free(fb);
+       talloc_free(mp);
 
        return ret;
 }
@@ -740,12 +929,41 @@ static const struct ldb_module_ops map_ops = {
        .errstring     = map_errstring
 };
 
+static char *map_find_url(struct ldb_context *ldb, const char *name)
+{
+       const char * const attrs[] = { "@MAP_URL" , NULL};
+       struct ldb_message **msg = NULL;
+       struct ldb_dn *mods;
+       char *url;
+       int ret;
+
+       mods = ldb_dn_string_compose(ldb, NULL, "@MAP=%s", name);
+       if (mods == NULL) {
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Can't construct DN");
+               return NULL;
+       }
+
+       ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &msg);
+       talloc_free(mods);
+       if (ret < 1) {
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Not enough results found looking for @MAP");
+               return NULL;
+       }
+
+       url = talloc_strdup(ldb, ldb_msg_find_string(msg[0], "@MAP_URL", NULL));
+
+       talloc_free(msg);
+
+       return url;
+}
+
 /* the init function */
-struct ldb_module *ldb_map_init(struct ldb_context *ldb, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls, const char *options[])
+struct ldb_module *ldb_map_init(struct ldb_context *ldb, const struct ldb_map_attribute *attrs, const struct ldb_map_objectclass *ocls, const char *name)
 {
        int i, j;
        struct ldb_module *ctx;
        struct map_private *data;
+       char *url;
 
        ctx = talloc(ldb, struct ldb_module);
        if (!ctx)
@@ -757,6 +975,21 @@ struct ldb_module *ldb_map_init(struct ldb_context *ldb, const struct ldb_map_at
                return NULL;
        }
 
+       data->context.mapped_ldb = ldb_init(data);
+       url = map_find_url(ldb, name);
+
+       if (!url) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "@MAP=%s not set!\n", name);
+               return NULL;
+       }
+
+       if (ldb_connect(data->context.mapped_ldb, url, 0, NULL) != 0) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to open mapped database for %s at '%s'\n", name, url);
+               return NULL;
+       }
+
+       talloc_free(url);
+
        data->last_err_string = NULL;
 
        /* Get list of attribute maps */
@@ -841,7 +1074,6 @@ static struct ldb_val map_convert_local_objectclass(struct ldb_map_context *map,
                }
        }
 
-       DEBUG(1, ("Unable to map local object class '%s'\n", (char *)val->data));
        return ldb_val_dup(ctx, val); 
 }
 
@@ -859,7 +1091,6 @@ static struct ldb_val map_convert_remote_objectclass(struct ldb_map_context *map
                }
        }
 
-       DEBUG(1, ("Unable to map remote object class '%s'\n", (char *)val->data));
        return ldb_val_dup(ctx, val); 
 }
 
index 60e09975b7b99228489ca167a4dc136a44780906..02fec649c691ec223e5d6d573fb92a633eb83ba9 100644 (file)
@@ -102,6 +102,7 @@ struct ldb_map_context
 {
        struct ldb_map_attribute *attribute_maps;
        const struct ldb_map_objectclass *objectclass_maps;
+       struct ldb_context *mapped_ldb;
 };
 
 #endif /* __LDB_MAP_H__ */
index aef50e4d3e1e2b7c80474cabd119ec57c9ca4f66..f7d83ced8f40a79c64438f573993154f35bcf7dc 100644 (file)
@@ -627,5 +627,5 @@ struct ldb_module *init_module(struct ldb_context *ldb, const char *options[])
 struct ldb_module *ldb_samba3sam_module_init(struct ldb_context *ldb, const char *options[])
 #endif
 {
-       return ldb_map_init(ldb, samba3_attributes, samba3_objectclasses, options);
+       return ldb_map_init(ldb, samba3_attributes, samba3_objectclasses, "samba3sam");
 }
index 988806d8956645305770520b86a38148e314ba08..995a513d5415b7834380786fb4f379011bd0ae88 100755 (executable)
@@ -1,39 +1,49 @@
 #!/bin/sh
 
-rm -f samba3.ldb
+rm -f samba3.ldb samba4.ldb
 
 echo "Adding samba3 LDIF..."
 $VALGRIND ldbadd -H tdb://samba3.ldb < samba3.ldif || exit 1
 
-LOC="-H tdb://samba3.ldb"
-OPT="-o modules:samba3sam $LOC"
+echo "Adding samba4 LDIF..."
+$VALGRIND ldbadd -H tdb://samba4.ldb <<EOF
+dn: @MODULES
+@LIST: samba3sam
+
+dn: @MAP=samba3sam
+@MAP_URL: tdb://samba3.ldb
+
+EOF
+
+LOC="-H tdb://samba4.ldb"
 
 echo "Looking up by non-mapped attribute"
-$VALGRIND ldbsearch $OPT "(cn=Administrator)" || exit 1
+$VALGRIND ldbsearch $LOC "(cn=Administrator)" || exit 1
 
 echo "Looking up by mapped attribute"
-$VALGRIND ldbsearch $OPT "(name=Backup Operators)" || exit 1
+$VALGRIND ldbsearch $LOC "(name=Backup Operators)" || exit 1
 
 echo "Looking up by old name of renamed attribute"
-$VALGRIND ldbsearch $OPT "(displayName=Backup Operators)" || exit 1
+$VALGRIND ldbsearch $LOC "(displayName=Backup Operators)" || exit 1
 
 echo "Adding a record"
-$VALGRIND ldbadd $OPT <<EOF
+$VALGRIND ldbadd $LOC <<EOF
 dn: cn=Foo,dc=idealx,dc=org
 unixName: root
 lastLogon: 20000
 cn: Foo
+showInAdvancedViewOnly: TRUE
 
 EOF
 
-echo "Checking for existance of record (mapped)"
-$VALGRIND ldbsearch $OPT "(cn=Foo)" unixName lastLogon cn || exit 1
+echo "Checking for existance of record"
+$VALGRIND ldbsearch $LOC "(cn=Foo)" unixName lastLogon cn showInAdvancedViewOnly || exit 1
 
-echo "Checking for existance of record (non-mapped)"
-$VALGRIND ldbsearch $LOC"(cn=foo)" uid sambaLogonTime cn || exit 1
+echo "Checking for persistence of non-mappable attribute"
+$VALGRIND ldbsearch $LOC "(cn=Foo)" showInAdvancedViewOnly | grep showInAdvancedViewOnly || exit 1
 
 echo "Adding record with mapped attribute in dn"
-$VALGRIND ldbadd $OPT <<EOF
+$VALGRIND ldbadd $LOC <<EOF
 dn: unixName=nobody,dc=idealx,dc=org
 unixName: nobody 
 cn: Niemand
@@ -41,7 +51,4 @@ cn: Niemand
 EOF
 
 echo "Checking for existance of record (mapped)"
-$VALGRIND ldbsearch $OPT "(unixName=nobody)" unixName cn dn || exit 1
-
-echo "Checking for existance of record (non-mapped)"
-$VALGRIND ldbsearch $OPT "(uid=nobody)" unixName cn dn || exit 1
+$VALGRIND ldbsearch $LOC "(unixName=nobody)" unixName cn dn || exit 1
index dd2f8e00057553238e8f77952a00198356118824..87add2096e462067c53b7c0767f6e8b6ea444d96 100644 (file)
@@ -31,7 +31,7 @@ Three possible viable approaches:
 (going with a combination of 1 and 2)
 
 ldb mapping backend:
- - do search in new and old (mapped) backend and merge results
+
 
 Upgrade process:
  - take libdir & smb.conf
@@ -39,3 +39,6 @@ Upgrade process:
  - write new smb.conf (ejs)
   - list of parameters to keep.. generate some of the others
  - add generated LDIF (ejs). Call out to current provisioning
+
+TODO:
+ - move ini parsing stuff to seperate file param/ini.c
index 60570935f6c064e8b3f66571b77cfe24a69621a1..3a6d2eec0a17479c183cdd1f79178af7952ddbc4 100644 (file)
@@ -68,17 +68,10 @@ data:: %s", keydn, rv.value, rv.type, base64(rv.data));
        return ldif;
 }
 
-function upgrade_sam_domain(samba3)
+function upgrade_sam_policy(samba3,dn)
 {
        var ldif = sprintf("
 dn: %s
-dc: FIXME
-objectClass: top
-objectClass: domain
-objectSid: %s
-objectGUID: %s
-name: %s
-oEMInformation: Provisioned by Samba4 (upgraded from Samba3)
 minPwdLength: %d
 pwdHistoryLength: %d
 minPwdAge: %d
@@ -90,7 +83,7 @@ samba3BadLockoutMinutes: %d
 samba3DisconnectTime: %d
 samba3RefuseMachinePwdChange: %d
 
-", domaindn, domsec.sid, domsec.guid, domainname, samba3.policy.min_password_length, 
+", dn, samba3.policy.min_password_length, 
        samba3.policy.password_history, samba3.policy.minimum_password_age,
        samba3.policy.maximum_password_age, samba3.policy.lockout_duration,
        samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password,
@@ -158,33 +151,6 @@ grp.comment, grp.nt_name, grp.sid, grp.sid_name_use);
        return ldif;
 }
 
-function upgrade_sam(samba3,domaindn)
-{
-       domainname = samba3.get_param("global", "workgroup");
-
-       if (domainname == undefined) {
-               DEBUG(0, ("No domain name specified in smb.conf!\n"));
-               return -1;
-       }
-
-       domsec = samba3.find_domainsecrets(domainname);
-
-       var ldif = upgrade_sam_domain(samba3,domaindn);
-
-       /* Users */
-       for (var i in samba3.samaccounts) {
-               ldif = ldif + upgrade_sam_account(samba3.samaccounts[i],domaindn);
-       }
-
-       /* Groups */
-       for (var i in samba3.group.groupmappings) {
-               ldif = ldif + upgrade_sam_group(samba3.group.groupmappings[i],domaindn);
-
-       }
-
-       return count;
-}
-
 function upgrade_winbind(samba3,domaindn)
 {
        var ldif = sprintf("
@@ -278,3 +244,124 @@ function upgrade_provision(samba3)
        subobj.RDN_DC       = rdn_list[0];
        return subobj;
 }
+
+var keep = new Array(
+       "dos charset", 
+       "unix charset",
+       "display charset",
+       "comment",
+       "path",
+       "directory",
+       "workgroup",
+       "realm",
+       "netbios name",
+       "netbios aliases",
+       "netbios scope",
+       "server string",
+       "interfaces",
+       "bind interfaces only",
+       "security",
+       "auth methods",
+       "encrypt passwords",
+       "null passwords",
+       "obey pam restrictions",
+       "password server",
+       "smb passwd file",
+       "sam database",
+       "spoolss database",
+       "wins database",
+       "private dir",
+       "passwd chat",
+       "password level",
+       "lanman auth",
+       "ntlm auth",
+       "client NTLMv2 auth",
+       "client lanman auth",
+       "client plaintext auth",
+       "read only",
+       "hosts allow",
+       "hosts deny",
+       "log level",
+       "debuglevel",
+       "log file",
+       "smb ports",
+       "nbt port",
+       "dgram port",
+       "cldap port",
+       "krb5 port",
+       "web port",
+       "tls enabled",
+       "tls keyfile",
+       "tls certfile",
+       "tls cafile",
+       "tls crlfile",
+       "swat directory",
+       "large readwrite",
+       "max protocol",
+       "min protocol",
+       "unicode",
+       "read raw",
+       "write raw",
+       "disable netbios",
+       "nt status support",
+       "announce version",
+       "announce as",
+       "max mux",
+       "max xmit",
+       "name resolve order",
+       "max wins ttl",
+       "min wins ttl",
+       "time server",
+       "unix extensions",
+       "use spnego",
+       "server signing",
+       "client signing",
+       "rpc big endian",
+       "max connections",
+       "paranoid server security",
+       "socket options",
+       "strict sync",
+       "case insensitive filesystem",
+       "max print jobs",
+       "printable",
+       "print ok",
+       "printer name",
+       "printer",
+       "map system",
+       "map hidden",
+       "map archive",
+       "domain logons",
+       "preferred master",
+       "prefered master",
+       "local master",
+       "domain master",
+       "browseable",
+       "browsable",
+       "wins server",
+       "wins support",
+       "csc policy",
+       "strict locking",
+       "config file",
+       "preload",
+       "auto services",
+       "lock dir",
+       "lock directory",
+       "pid directory",
+       "js include",
+       "setup directory",
+       "socket address",
+       "-valid",
+       "copy",
+       "include",
+       "available",
+       "volume",
+       "fstype",
+       "panic action",
+       "msdfs root",
+       "host msdfs",
+       "winbind separator");
+
+function upgrade_smbconf(samba3)
+{
+       //FIXME
+}
index 447e5ee4f92d552f3e50b3e85bb79aeabe9db7a3..5d0b14bdd7a9a40efc28193cc3880e50d4b5a059 100644 (file)
@@ -10,6 +10,8 @@ options = GetOptions(ARGV,
                "POPT_AUTOHELP",
                "POPT_COMMON_SAMBA",
                "POPT_COMMON_VERSION",
+               'ldif',
+               'dn=s',
                'quiet', 'blank');
 
 if (options == undefined) {
@@ -31,6 +33,13 @@ function message()
        }
 }
 
+function ldifprint(data)
+{
+       if (options["ldif"] != undefined) {
+               print data;
+       }
+}
+
 /*
  show some help
 */
@@ -40,6 +49,7 @@ function ShowHelp()
 Samba4 import tool
 
 provision [options] <libdir> <smbconf>
+ --ldif                                Dump LDIF
  --quiet                       Be quiet
  --blank                       do not add users or groups, just the structure
 
@@ -54,6 +64,10 @@ if (options.ARGV.length != 2) {
        exit(1);
 }
 
+if (options.dn == undefined) {
+       options.dn = "dc=example,dc=org";
+}
+
 message("Reading Samba3 databases and smb.conf\n");
 var samba3 = samba3_read(options.ARGV[0], options.ARGV[1]);
 
@@ -63,23 +77,54 @@ if (samba3 == undefined) {
 }
 
 message("Writing smb.conf\n");
-// FIXME
+var smbconf = upgrade_smbconf(samba3);
+// FIXME: Write!
 
 message("Provisioning\n");
 var subobj = upgrade_provision(samba3);
 provision(subobj, message, blank);
 
+var samdb = ldb_init();
+samdb.connect(lp.get("setup directory") + "/samdb.ldb");
+
 message("Importing account policies\n");
-// FIXME
+var ldif = upgrade_policy(samba3);
+ldifprint(ldif);
+samdb.modify(ldif);
+
+// FIXME: Enable samba3sam module if original passdb backend was ldap
 
 message("Importing users\n");
-// FIXME
+for (var i in samba3.samaccounts) {
+       message("Importing user '" + samba3.samaccounts[i].username + "'");
+       var ldif = upgrade_sam_account(samba3.samaccounts[i]);
+       ldifprint(ldif);
+       samdb.add(ldif);
+}
 
 message("Importing groups\n");
-// FIXME
+for (var i in samba3.groupmappings) {
+       message("Importing group '" + samba3.groupmappings[i].username + "'");
+       var ldif = upgrade_sam_group(samba3.groupmappings[i]);
+       ldifprint(ldif);
+       samdb.add(ldif);
+}
 
 message("Importing WINS data\n");
-// FIXME
+var ldif = upgrade_wins(samba3)
+ldifprint(ldif);
+setup_ldb(ldif, "wins", Object());
+
+message("Importing registry data\n");
+var hives = ["hkcr","hkcu","hklm","hkpd"]; 
+for (var i in hives) {
+       var regdb = ldb_init();
+       regdb.connect(lp.get("setup directory") + "/" + hives[i] + ".ldb");
+       var ldif = upgrade_registry(samba3, hives[i]);
+       ldifprint(ldif);
+       ldb.add(ldif);
+}
+
 
 message("All OK\n");
 return 0;