summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map.c315
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map.h1
-rw-r--r--source4/lib/ldb/samba/samba3sam.c2
-rwxr-xr-xsource4/lib/ldb/tests/test-samba3sam.sh39
-rw-r--r--source4/lib/samba3/PLAN5
-rw-r--r--source4/scripting/libjs/upgrade.js159
-rw-r--r--source4/setup/upgrade55
7 files changed, 475 insertions, 101 deletions
diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c
index 1a8ea2afc4..79d3c26f90 100644
--- a/source4/lib/ldb/ldb_map/ldb_map.c
+++ b/source4/lib/ldb/ldb_map/ldb_map.c
@@ -34,6 +34,22 @@
* (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);
}
diff --git a/source4/lib/ldb/ldb_map/ldb_map.h b/source4/lib/ldb/ldb_map/ldb_map.h
index 60e09975b7..02fec649c6 100644
--- a/source4/lib/ldb/ldb_map/ldb_map.h
+++ b/source4/lib/ldb/ldb_map/ldb_map.h
@@ -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__ */
diff --git a/source4/lib/ldb/samba/samba3sam.c b/source4/lib/ldb/samba/samba3sam.c
index aef50e4d3e..f7d83ced8f 100644
--- a/source4/lib/ldb/samba/samba3sam.c
+++ b/source4/lib/ldb/samba/samba3sam.c
@@ -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");
}
diff --git a/source4/lib/ldb/tests/test-samba3sam.sh b/source4/lib/ldb/tests/test-samba3sam.sh
index 988806d895..995a513d54 100755
--- a/source4/lib/ldb/tests/test-samba3sam.sh
+++ b/source4/lib/ldb/tests/test-samba3sam.sh
@@ -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
diff --git a/source4/lib/samba3/PLAN b/source4/lib/samba3/PLAN
index dd2f8e0005..87add2096e 100644
--- a/source4/lib/samba3/PLAN
+++ b/source4/lib/samba3/PLAN
@@ -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
diff --git a/source4/scripting/libjs/upgrade.js b/source4/scripting/libjs/upgrade.js
index 60570935f6..3a6d2eec0a 100644
--- a/source4/scripting/libjs/upgrade.js
+++ b/source4/scripting/libjs/upgrade.js
@@ -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
+}
diff --git a/source4/setup/upgrade b/source4/setup/upgrade
index 447e5ee4f9..5d0b14bdd7 100644
--- a/source4/setup/upgrade
+++ b/source4/setup/upgrade
@@ -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;