summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/samba3sam.c14
-rw-r--r--source4/lib/ldb/common/ldb_msg.c14
-rw-r--r--source4/lib/ldb/include/ldb_private.h2
-rw-r--r--source4/lib/ldb/modules/ldb_map.c21
-rw-r--r--source4/lib/ldb/modules/ldb_map_outbound.c214
-rw-r--r--source4/lib/ldb/modules/ldb_map_private.h2
-rwxr-xr-xtestprogs/ejs/samba3sam.js74
7 files changed, 263 insertions, 78 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c
index 341fad4bd9..6c7c3c7066 100644
--- a/source4/dsdb/samdb/ldb_modules/samba3sam.c
+++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c
@@ -52,22 +52,25 @@
/* In Samba4 but not in Samba3:
*/
-static struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *attr, const struct ldb_message *remote)
+/* From a sambaPrimaryGroupSID, generate a primaryGroupID (integer) attribute */
+static struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *local_attr, const struct ldb_message *remote)
{
struct ldb_message_element *el;
- const char *sid = ldb_msg_find_attr_as_string(remote, attr, NULL);
-
+ const char *sid = ldb_msg_find_attr_as_string(remote, "sambaPrimaryGroupSID", NULL);
+ const char *p;
+
if (!sid)
return NULL;
- if (strchr(sid, '-') == NULL)
+ p = strrchr(sid, '-');
+ if (!p)
return NULL;
el = talloc_zero(ctx, struct ldb_message_element);
el->name = talloc_strdup(ctx, "primaryGroupID");
el->num_values = 1;
el->values = talloc_array(ctx, struct ldb_val, 1);
- el->values[0].data = (uint8_t *)talloc_strdup(el->values, strchr(sid, '-')+1);
+ el->values[0].data = (uint8_t *)talloc_strdup(el->values, strrchr(sid, '-')+1);
el->values[0].length = strlen((char *)el->values[0].data);
return el;
@@ -80,6 +83,7 @@ static void generate_sambaPrimaryGroupSID(struct ldb_module *module, const char
struct dom_sid *sid;
NTSTATUS status;
+ /* We need the domain, so we get it from the objectSid that we hope is here... */
sidval = ldb_msg_find_ldb_val(local, "objectSid");
if (!sidval)
diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c
index 9cb4cf5ed0..65d1ecacb7 100644
--- a/source4/lib/ldb/common/ldb_msg.c
+++ b/source4/lib/ldb/common/ldb_msg.c
@@ -654,7 +654,7 @@ const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs)
/*
copy an attribute list. This only copies the array, not the elements
- (ie. the elements are left as the same pointers)
+ (ie. the elements are left as the same pointers). The new attribute is added to the list.
*/
const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr)
{
@@ -738,6 +738,18 @@ void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
}
/*
+ remove the specified element in a search result
+*/
+void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el)
+{
+ int n = (el - msg->elements);
+ if (n != msg->num_elements-1) {
+ memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+ }
+ msg->num_elements--;
+}
+
+/*
return a LDAP formatted time string
*/
char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t)
diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h
index 3902bb2fc2..f4049188ad 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -211,6 +211,8 @@ int check_critical_controls(struct ldb_control **controls);
/* The following definitions come from lib/ldb/common/ldb_utf8.c */
char *ldb_casefold_default(void *context, void *mem_ctx, const char *s);
+void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el);
+
/**
Obtain current/next database sequence number
*/
diff --git a/source4/lib/ldb/modules/ldb_map.c b/source4/lib/ldb/modules/ldb_map.c
index 32e64f3eb2..bbd7b9603d 100644
--- a/source4/lib/ldb/modules/ldb_map.c
+++ b/source4/lib/ldb/modules/ldb_map.c
@@ -390,13 +390,14 @@ const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *m
/* Merge two lists of attributes into a single one. */
-int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs)
+int map_attrs_merge(struct ldb_module *module, void *mem_ctx,
+ const char ***attrs, const char * const *more_attrs)
{
int i, j, k;
for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ;
for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ;
-
+
*attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1);
if (*attrs == NULL) {
map_oom(module);
@@ -404,7 +405,7 @@ int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attr
}
for (k = 0; k < j; k++) {
- (*attrs)[i+k] = more_attrs[k];
+ (*attrs)[i + k] = more_attrs[k];
}
(*attrs)[i+k] = NULL;
@@ -416,7 +417,8 @@ int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attr
* ================== */
/* Map an ldb value into the remote partition. */
-struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val)
+struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx,
+ const struct ldb_map_attribute *map, const struct ldb_val *val)
{
if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) {
return map->u.convert.convert_local(module, mem_ctx, val);
@@ -426,7 +428,8 @@ struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const
}
/* Map an ldb value back into the local partition. */
-struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val)
+struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx,
+ const struct ldb_map_attribute *map, const struct ldb_val *val)
{
if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) {
return map->u.convert.convert_remote(module, mem_ctx, val);
@@ -679,7 +682,7 @@ static void map_objectclass_generate_remote(struct ldb_module *module, const cha
int i;
/* Find old local objectClass */
- oc = ldb_msg_find_element(old, local_attr);
+ oc = ldb_msg_find_element(old, "objectClass");
if (oc == NULL) {
return;
}
@@ -743,14 +746,14 @@ static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module,
}
/* Generate a local message with a mapped objectClass. */
-static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *remote_attr, const struct ldb_message *remote)
+static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote)
{
struct ldb_message_element *el, *oc;
struct ldb_val val;
int i;
/* Find old remote objectClass */
- oc = ldb_msg_find_element(remote, remote_attr);
+ oc = ldb_msg_find_element(remote, "objectClass");
if (oc == NULL) {
return NULL;
}
@@ -772,7 +775,7 @@ static struct ldb_message_element *map_objectclass_generate_local(struct ldb_mod
}
/* Copy remote element name "objectClass" */
- el->name = talloc_strdup(el, remote_attr);
+ el->name = talloc_strdup(el, local_attr);
/* Convert all remote objectClasses */
for (i = 0; i < el->num_values; i++) {
diff --git a/source4/lib/ldb/modules/ldb_map_outbound.c b/source4/lib/ldb/modules/ldb_map_outbound.c
index dc213f36d1..505df79533 100644
--- a/source4/lib/ldb/modules/ldb_map_outbound.c
+++ b/source4/lib/ldb/modules/ldb_map_outbound.c
@@ -75,7 +75,8 @@ failed:
}
/* Collect attributes that are mapped into the remote partition. */
-static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, const char * const *attrs)
+static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx,
+ const char * const *attrs)
{
const struct ldb_map_context *data = map_get_context(module);
const char **result;
@@ -172,10 +173,10 @@ failed:
/* Split attributes that stay in the local partition from those that
* are mapped into the remote partition. */
-static int map_attrs_partition(struct ldb_module *module, void *local_ctx, void *remote_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs)
+static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs)
{
- *local_attrs = map_attrs_select_local(module, local_ctx, attrs);
- *remote_attrs = map_attrs_collect_remote(module, remote_ctx, attrs);
+ *local_attrs = map_attrs_select_local(module, mem_ctx, attrs);
+ *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs);
return 0;
}
@@ -213,7 +214,11 @@ static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_ele
}
/* Map a message element back into the local partition. */
-static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old)
+static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module,
+ void *mem_ctx,
+ const struct ldb_map_attribute *map,
+ const char *attr_name,
+ const struct ldb_message_element *old)
{
struct ldb_message_element *el;
int i;
@@ -232,7 +237,12 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
return NULL;
}
- el->name = map_attr_map_remote(el, map, old->name);
+ el->name = talloc_strdup(el, attr_name);
+ if (el->name == NULL) {
+ talloc_free(el);
+ map_oom(module);
+ return NULL;
+ }
for (i = 0; i < el->num_values; i++) {
el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]);
@@ -242,37 +252,64 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
}
/* Merge a remote message element into a local message. */
-static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const char *attr_name, const struct ldb_message_element *old)
+static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local,
+ struct ldb_message *remote, const char *attr_name)
{
const struct ldb_map_context *data = map_get_context(module);
- const struct ldb_map_attribute *map = map_attr_find_remote(data, attr_name);
- struct ldb_message_element *el=NULL;
+ const struct ldb_map_attribute *map;
+ struct ldb_message_element *old, *el=NULL;
+ const char *remote_name = NULL;
+
+ /* We handle wildcards in ldb_msg_el_merge_wildcard */
+ if (ldb_attr_cmp(attr_name, "*") == 0) {
+ return 0;
+ }
+
+ map = map_attr_find_local(data, attr_name);
/* Unknown attribute in remote message:
* skip, attribute was probably auto-generated */
if (map == NULL) {
- ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: "
- "Skipping attribute '%s': no mapping found\n",
- old->name);
return 0;
}
switch (map->type) {
case MAP_IGNORE:
- return -1;
+ break;
+ case MAP_CONVERT:
+ remote_name = map->u.convert.remote_name;
+ break;
+ case MAP_KEEP:
+ remote_name = attr_name;
+ break;
+ case MAP_RENAME:
+ remote_name = map->u.rename.remote_name;
+ break;
+ case MAP_GENERATE:
+ break;
+ }
+
+ switch (map->type) {
+ case MAP_IGNORE:
+ return 0;
case MAP_CONVERT:
if (map->u.convert.convert_remote == NULL) {
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
"'convert_remote' not set\n",
- old->name);
+ attr_name);
return 0;
}
/* fall through */
case MAP_KEEP:
case MAP_RENAME:
- el = ldb_msg_el_map_remote(module, local, map, old);
+ old = ldb_msg_find_element(remote, remote_name);
+ if (old) {
+ el = ldb_msg_el_map_remote(module, local, map, attr_name, old);
+ } else {
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
+ }
break;
case MAP_GENERATE:
@@ -280,21 +317,72 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
"'generate_local' not set\n",
- old->name);
+ attr_name);
return 0;
}
- el = map->u.generate.generate_local(module, local, old->name, remote);
+ el = map->u.generate.generate_local(module, local, attr_name, remote);
+ if (!el) {
+ /* Generation failure is probably due to lack of source attributes */
+ return LDB_ERR_NO_SUCH_ATTRIBUTE;
+ }
break;
}
if (el == NULL) {
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
return ldb_msg_replace(local, el);
}
+/* Handle wildcard parts of merging a remote message element into a local message. */
+static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local,
+ struct ldb_message *remote)
+{
+ const struct ldb_map_context *data = map_get_context(module);
+ const struct ldb_map_attribute *map = map_attr_find_local(data, "*");
+ struct ldb_message_element *el=NULL;
+ int i, ret;
+
+ /* Perhaps we have a mapping for "*" */
+ if (map && map->type == MAP_KEEP) {
+ /* We copy everything over, and hope that anything with a
+ more specific rule is overwritten, or caught by the test below */
+ for (i = 0; i < remote->num_elements; i++) {
+ if (map_attr_find_local(data, remote->elements[i].name)) {
+ /* The name this would have been copied to has a more specific mapping */
+ continue;
+ }
+ el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name,
+ &remote->elements[i]);
+ if (el == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_msg_replace(local, el);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+
+ /* Now walk the list of possible mappings, and apply each */
+ for (i = 0; data->attribute_maps[i].local_name; i++) {
+ ret = ldb_msg_el_merge(module, local, remote,
+ data->attribute_maps[i].local_name);
+ if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ continue;
+ } else if (ret) {
+ return ret;
+ } else {
+ continue;
+ }
+ }
+
+ return 0;
+}
+
/* Mapping messages
* ================ */
@@ -314,16 +402,36 @@ static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *ms
}
/* Merge a local and a remote message into a single local one. */
-static int ldb_msg_merge_remote(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote)
+static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local,
+ struct ldb_message *remote)
{
int i, ret;
+ const char * const *attrs = ac->all_attrs;
+ if (!attrs) {
+ ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ for (i = 0; attrs && attrs[i]; i++) {
+ if (ldb_attr_cmp(attrs[i], "*") == 0) {
+ ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);
+ if (ret) {
+ return ret;
+ }
+ break;
+ }
+ }
/* Try to map each attribute back;
* Add to local message is possible,
* Overwrite old local attribute if necessary */
- for (i = 0; i < remote->num_elements; i++) {
- ret = ldb_msg_el_merge(module, local, remote, remote->elements[i].name, &remote->elements[i]);
- if (ret) {
+ for (i = 0; attrs && attrs[i]; i++) {
+ ret = ldb_msg_el_merge(ac->module, local, remote,
+ attrs[i]);
+ if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ } else if (ret) {
return ret;
}
}
@@ -335,7 +443,7 @@ static int ldb_msg_merge_remote(struct ldb_module *module, struct ldb_message *l
* ====================== */
/* Map a search result back into the local partition. */
-static int map_reply_remote(struct ldb_module *module, struct ldb_reply *ares)
+static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares)
{
struct ldb_message *msg;
struct ldb_dn *dn;
@@ -349,19 +457,19 @@ static int map_reply_remote(struct ldb_module *module, struct ldb_reply *ares)
/* Create a new result message */
msg = ldb_msg_new(ares);
if (msg == NULL) {
- map_oom(module);
+ map_oom(ac->module);
return -1;
}
/* Merge remote message into new message */
- ret = ldb_msg_merge_remote(module, msg, ares->message);
+ ret = ldb_msg_merge_remote(ac, msg, ares->message);
if (ret) {
talloc_free(msg);
return ret;
}
/* Create corresponding local DN */
- dn = ldb_dn_map_rebase_remote(module, msg, ares->message->dn);
+ dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn);
if (dn == NULL) {
talloc_free(msg);
return -1;
@@ -419,7 +527,8 @@ static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx
case LDB_OP_OR:
case LDB_OP_AND: /* attributes stored in list of subtrees */
for (i = 0; i < tree->u.list.num_elements; i++) {
- ret = ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.list.elements[i]);
+ ret = ldb_parse_tree_collect_attrs(module, mem_ctx,
+ attrs, tree->u.list.elements[i]);
if (ret) {
return ret;
}
@@ -827,23 +936,34 @@ static int ldb_parse_tree_partition(struct ldb_module *module, void *local_ctx,
/* Collect a list of attributes required either explicitly from a
* given list or implicitly from a given parse tree; split the
* collected list into local and remote parts. */
-static int map_attrs_collect_and_partition(struct ldb_module *module, void *local_ctx, void *remote_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *search_attrs, const struct ldb_parse_tree *tree)
+static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac,
+ const char * const *search_attrs,
+ const struct ldb_parse_tree *tree)
{
void *tmp_ctx;
const char **tree_attrs;
+ const char **remote_attrs;
+ const char **local_attrs;
int ret;
/* Clear initial lists of partitioned attributes */
- *local_attrs = NULL;
- *remote_attrs = NULL;
+
+ /* Clear initial lists of partitioned attributes */
/* There is no tree, just partition the searched attributes */
if (tree == NULL) {
- return map_attrs_partition(module, local_ctx, remote_ctx, local_attrs, remote_attrs, search_attrs);
+ ret = map_attrs_partition(module, ac,
+ &local_attrs, &remote_attrs, search_attrs);
+ if (ret == 0) {
+ ac->local_attrs = local_attrs;
+ ac->remote_attrs = remote_attrs;
+ ac->all_attrs = search_attrs;
+ }
+ return ret;
}
/* Create context for temporary memory */
- tmp_ctx = talloc_new(local_ctx);
+ tmp_ctx = talloc_new(ac);
if (tmp_ctx == NULL) {
goto oom;
}
@@ -869,8 +989,15 @@ static int map_attrs_collect_and_partition(struct ldb_module *module, void *loca
}
/* Split local from remote attributes */
- ret = map_attrs_partition(module, local_ctx, remote_ctx, local_attrs, remote_attrs, tree_attrs);
-
+ ret = map_attrs_partition(module, ac, &local_attrs,
+ &remote_attrs, tree_attrs);
+
+ if (ret == 0) {
+ ac->local_attrs = local_attrs;
+ ac->remote_attrs = remote_attrs;
+ talloc_steal(ac, tree_attrs);
+ ac->all_attrs = tree_attrs;
+ }
done:
/* Free temporary memory */
talloc_free(tmp_ctx);
@@ -911,10 +1038,12 @@ int map_up_callback(struct ldb_context *ldb, const struct ldb_request *req, stru
/* Limit result to requested attrs */
if ((req->op.search.attrs) && (!ldb_attr_in_list(req->op.search.attrs, "*"))) {
- for (i = 0; i < ares->message->num_elements; i++) {
+ for (i = 0; i < ares->message->num_elements; ) {
const struct ldb_message_element *el = &ares->message->elements[i];
if (!ldb_attr_in_list(req->op.search.attrs, el->name)) {
- ldb_msg_remove_attr(ares->message, el->name);
+ ldb_msg_remove_element(ares->message, el);
+ } else {
+ i++;
}
}
}
@@ -995,7 +1124,7 @@ int map_remote_search_callback(struct ldb_context *ldb, void *context, struct ld
}
/* Map result record into a local message */
- ret = map_reply_remote(ac->module, ares);
+ ret = map_reply_remote(ac, ares);
if (ret) {
talloc_free(ares);
return LDB_ERR_OPERATIONS_ERROR;
@@ -1042,7 +1171,6 @@ int map_search(struct ldb_module *module, struct ldb_request *req)
struct ldb_handle *h;
struct map_context *ac;
struct ldb_parse_tree *local_tree, *remote_tree;
- const char **local_attrs, **remote_attrs;
int ret;
const char *wildcard[] = { "*", NULL };
@@ -1096,16 +1224,18 @@ int map_search(struct ldb_module *module, struct ldb_request *req)
}
/* Split local from remote attrs */
- ret = map_attrs_collect_and_partition(module, ac, ac->search_reqs[0], &local_attrs, &remote_attrs, attrs, req->op.search.tree);
+ ret = map_attrs_collect_and_partition(module, ac,
+ attrs, req->op.search.tree);
if (ret) {
goto failed;
}
- ac->local_attrs = local_attrs;
- ac->search_reqs[0]->op.search.attrs = remote_attrs;
+ ac->search_reqs[0]->op.search.attrs = ac->remote_attrs;
/* Split local from remote tree */
- ret = ldb_parse_tree_partition(module, ac, ac->search_reqs[0], &local_tree, &remote_tree, req->op.search.tree);
+ ret = ldb_parse_tree_partition(module, ac, ac->search_reqs[0],
+ &local_tree, &remote_tree,
+ req->op.search.tree);
if (ret) {
goto failed;
}
diff --git a/source4/lib/ldb/modules/ldb_map_private.h b/source4/lib/ldb/modules/ldb_map_private.h
index ae53ebbdd4..8a08d0a5b6 100644
--- a/source4/lib/ldb/modules/ldb_map_private.h
+++ b/source4/lib/ldb/modules/ldb_map_private.h
@@ -36,6 +36,8 @@ struct map_context {
const struct ldb_dn *local_dn;
const struct ldb_parse_tree *local_tree;
const char * const *local_attrs;
+ const char * const *remote_attrs;
+ const char * const *all_attrs;
struct ldb_request *orig_req;
struct ldb_request *local_req;
diff --git a/testprogs/ejs/samba3sam.js b/testprogs/ejs/samba3sam.js
index 446b39facf..076d434360 100755
--- a/testprogs/ejs/samba3sam.js
+++ b/testprogs/ejs/samba3sam.js
@@ -43,7 +43,7 @@ function setup_modules(ldb, s3, s4, ldif)
var ldif = "
dn: @MAP=samba3sam
@FROM: " + s4.BASEDN + "
-@TO: " + s3.BASEDN + "
+@TO: sambaDomainName=TESTS," + s3.BASEDN + "
dn: @MODULES
@LIST: rootdse,paged_results,server_sort,extended_dn,asq,samldb,objectclass,password_hash,operational,objectguid,rdn_name,samba3sam,partition
@@ -79,7 +79,7 @@ function test_s3sam_search(ldb)
var msg = ldb.search("(cn=Replicator)");
assert(msg.length == 1);
println(msg[0].dn);
- assert(msg[0].dn == "cn=Replicator,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl");
+ assert(msg[0].dn == "cn=Replicator,ou=Groups,dc=vernstok,dc=nl");
assert(msg[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
println("Checking mapping of objectClass");
@@ -94,30 +94,36 @@ function test_s3sam_search(ldb)
assert(msg != undefined);
assert(msg.length == 2);
for (var i = 0; i < msg.length; i++) {
- assert((msg[i].dn == "unixName=Administrator,ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl") ||
- (msg[i].dn == "unixName=nobody,ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl"));
+ assert((msg[i].dn == "unixName=Administrator,ou=Users,dc=vernstok,dc=nl") ||
+ (msg[i].dn == "unixName=nobody,ou=Users,dc=vernstok,dc=nl"));
}
}
function test_s3sam_modify(ldb, s3)
{
+ var msg, ok;
println("Adding a record that will be fallbacked");
ok = ldb.add("
-dn: cn=Foo,dc=idealx,dc=org
+dn: cn=Foo
foo: bar
blah: Blie
cn: Foo
showInAdvancedViewOnly: TRUE
");
+ if (!ok) {
+ println(ldb.errstring());
+ assert(ok);
+ }
assert(ok);
println("Checking for existence of record (local)");
/* TODO: This record must be searched in the local database, which is currently only supported for base searches
* msg = ldb.search("(cn=Foo)", new Array('foo','blah','cn','showInAdvancedViewOnly'));
* TODO: Actually, this version should work as well but doesn't...
- * msg = ldb.search("(cn=Foo)", "dc=idealx,dc=org", ldb.LDB_SCOPE_SUBTREE new Array('foo','blah','cn','showInAdvancedViewOnly'));
+ *
*/
- msg = ldb.search("", "cn=Foo,dc=idealx,dc=org", ldb.LDB_SCOPE_BASE new Array('foo','blah','cn','showInAdvancedViewOnly'));
+ var attrs = new Array('foo','blah','cn','showInAdvancedViewOnly');
+ msg = ldb.search("(cn=Foo)", "cn=Foo", ldb.LDB_SCOPE_BASE, attrs);
assert(msg.length == 1);
assert(msg[0].showInAdvancedViewOnly == "TRUE");
assert(msg[0].foo == "bar");
@@ -125,12 +131,16 @@ showInAdvancedViewOnly: TRUE
println("Adding record that will be mapped");
ok = ldb.add("
-dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
+dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
objectClass: user
unixName: bin
unicodePwd: geheim
cn: Niemand
");
+ if (!ok) {
+ println(ldb.errstring());
+ assert(ok);
+ }
assert(ok);
println("Checking for existence of record (remote)");
@@ -148,6 +158,7 @@ cn: Niemand
println("Checking for existence of record (local || remote)");
msg = ldb.search("(|(unixName=bin)(unicodePwd=geheim))", new Array('unixName','cn','dn', 'unicodePwd'));
+ println("got " + msg.length + " replies");
assert(msg.length == 1); // TODO: should check with more records
assert(msg[0].cn == "Niemand");
assert(msg[0].unixName == "bin" || msg[0].unicodePwd == "geheim");
@@ -160,11 +171,15 @@ cn: Niemand
println("Adding attribute...");
ok = ldb.modify("
-dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
+dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
add: description
description: Blah
");
+ if (!ok) {
+ println(ldb.errstring());
+ assert(ok);
+ }
assert(ok);
println("Checking whether changes are still there...");
@@ -175,11 +190,15 @@ description: Blah
println("Modifying attribute...");
ok = ldb.modify("
-dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
+dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
replace: description
description: Blie
");
+ if (!ok) {
+ println(ldb.errstring());
+ assert(ok);
+ }
assert(ok);
println("Checking whether changes are still there...");
@@ -189,10 +208,14 @@ description: Blie
println("Deleting attribute...");
ok = ldb.modify("
-dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
+dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
delete: description
");
+ if (!ok) {
+ println(ldb.errstring());
+ assert(ok);
+ }
assert(ok);
println("Checking whether changes are no longer there...");
@@ -201,19 +224,23 @@ delete: description
assert(msg[0].description == undefined);
println("Renaming record...");
- ok = ldb.rename("cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl", "cn=Niemand,dc=vernstok,dc=nl");
+ ok = ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl", "cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
+ assert(ok);
println("Checking whether DN has changed...");
- msg = ldb.search("(cn=Niemand)");
+ msg = ldb.search("(cn=Niemand2)");
assert(msg.length == 1);
- assert(msg[0].dn == "cn=Niemand,dc=vernstok,dc=nl");
+ assert(msg[0].dn == "cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
println("Deleting record...");
- ok = ldb.del("cn=Niemand,dc=vernstok,dc=nl");
- assert(ok);
+ ok = ldb.del("cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
+ if (!ok) {
+ println(ldb.errstring());
+ assert(ok);
+ }
println("Checking whether record is gone...");
- msg = ldb.search("(cn=Niemand)");
+ msg = ldb.search("(cn=Niemand2)");
assert(msg.length == 0);
}
@@ -401,13 +428,13 @@ description: y
/* In most cases, this even works when the mapping is missing
* a `convert_operator' by enumerating the remote db. */
attrs = new Array("objectCategory", "lastLogon", "primaryGroupID");
- res = ldb.search("(primaryGroupID=1-5-21-4231626423-2410014848-2360679739-512)", NULL, ldb. SCOPE_DEFAULT, attrs);
+ res = ldb.search("(primaryGroupID=512)", NULL, ldb. SCOPE_DEFAULT, attrs);
assert(res != undefined);
assert(res.length == 1);
assert(res[0].dn == s4.dn("cn=A"));
assert(res[0].objectCategory == undefined);
assert(res[0].lastLogon == "x");
- assert(res[0].primaryGroupID == "1-5-21-4231626423-2410014848-2360679739-512");
+ assert(res[0].primaryGroupID == "512");
/* TODO: There should actually be two results, A and X. The
* primaryGroupID of X seems to get corrupted somewhere, and the
@@ -1107,6 +1134,11 @@ function make_dn(rdn)
return rdn + ",sambaDomainName=TESTS," + this.BASEDN;
}
+function make_s4dn(rdn)
+{
+ return rdn + "," + this.BASEDN;
+}
+
var ldb = ldb_init();
sys = sys_init();
@@ -1118,12 +1150,12 @@ samba4.file = prefix + "/" + "samba4.ldb";
samba4.url = "tdb://" + samba4.file;
samba4.BASEDN = "dc=vernstok,dc=nl";
samba4.db = ldb_init();
-samba4.dn = make_dn;
+samba4.dn = make_s4dn;
var samba3 = new Object("samba3 partition info");
samba3.file = prefix + "/" + "samba3.ldb";
samba3.url = "tdb://" + samba3.file;
-samba3.BASEDN = "cn=Samba3Sam," + samba4.BASEDN;
+samba3.BASEDN = "cn=Samba3Sam";
samba3.db = ldb_init();
samba3.dn = make_dn;