mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
r9899: Be more conservative about what is sent to the remote server in ldb_map.
(This used to be commit 76e943d441
)
This commit is contained in:
parent
6ff97621fa
commit
e2e2508b58
@ -85,7 +85,7 @@ static struct ldb_val convert_unix_name2id(struct ldb_module *module, TALLOC_CTX
|
||||
static struct ldb_val encode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
|
||||
{
|
||||
struct dom_sid *sid = dom_sid_parse_talloc(ctx, (char *)val->data);
|
||||
struct ldb_val *out = talloc_zero(out, struct ldb_val);
|
||||
struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
|
||||
NTSTATUS status;
|
||||
|
||||
if (sid == NULL) {
|
||||
@ -128,9 +128,34 @@ static struct ldb_val decode_sid(struct ldb_module *module, TALLOC_CTX *ctx, con
|
||||
}
|
||||
|
||||
const struct ldb_map_objectclass samba3_objectclasses[] = {
|
||||
{ "group", "sambaGroupMapping" },
|
||||
{ "user", "sambaSAMAccount" },
|
||||
{ "domain", "sambaDomain" },
|
||||
{
|
||||
.local_name = "group",
|
||||
.remote_name = "sambaGroupMapping",
|
||||
.musts = { "gidNumber", "sambaSID", "sambaGroupType", NULL },
|
||||
.mays = { "displayName", "description", "sambaSIDList", NULL },
|
||||
},
|
||||
{
|
||||
.local_name = "user",
|
||||
.remote_name = "sambaSAMAccount",
|
||||
.base_classes = { "top", NULL },
|
||||
.musts = { "uid", "sambaSID", NULL },
|
||||
.mays = { "cn", "sambaLMPassword", "sambaNTPassword",
|
||||
"sambaPwdLastSet", "sambaLogonTime", "sambaLogoffTime",
|
||||
"sambaKickoffTime", "sambaPwdCanChange", "sambaPwdMustChange",
|
||||
"sambaAcctFlags", "displayName", "sambaHomePath", "sambaHomeDrive",
|
||||
"sambaLogonScript", "sambaProfilePath", "description", "sambaUserWorkstations",
|
||||
"sambaPrimaryGroupSID", "sambaDomainName", "sambaMungedDial",
|
||||
"sambaBadPasswordCount", "sambaBadPasswordTime",
|
||||
"sambaPasswordHistory", "sambaLogonHours", NULL }
|
||||
|
||||
},
|
||||
{
|
||||
.local_name = "domain",
|
||||
.remote_name = "sambaDomain",
|
||||
.base_classes = { "top", NULL },
|
||||
.musts = { "sambaDomainName", "sambaSID", NULL },
|
||||
.mays = { "sambaNextRid", "sambaNextGroupRid", "sambaNextUserRid", "sambaAlgorithmicRidBase", NULL },
|
||||
},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@ -237,17 +262,6 @@ const struct ldb_map_attribute samba3_attributes[] =
|
||||
},
|
||||
},
|
||||
|
||||
/* gidNumber -> unixName */
|
||||
{
|
||||
.local_name = "unixName",
|
||||
.type = MAP_CONVERT,
|
||||
.u = {
|
||||
.convert = {
|
||||
.remote_name = "gidNumber",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/* uid -> unixName */
|
||||
{
|
||||
.local_name = "unixName",
|
||||
|
@ -27,15 +27,13 @@
|
||||
#include "ldb/include/ldb_private.h"
|
||||
#include "ldb/modules/ldb_map.h"
|
||||
|
||||
/*
|
||||
* - map_message_outgoing() should:
|
||||
* - modify: not worry about anything simply map and hope everything
|
||||
* will be ok.
|
||||
* - make a list of remote objectclasses that will be used
|
||||
* given the attributes that are available
|
||||
* - only add attribute to the remote message if
|
||||
* it is allowed by the objectclass
|
||||
*
|
||||
/* FIXME:
|
||||
* - per remote objectclass:
|
||||
* - remote name
|
||||
* - local name
|
||||
* - remote bases
|
||||
* - musts
|
||||
* - mays
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -95,6 +93,17 @@ static const struct ldb_map_attribute builtin_attribute_maps[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ldb_map_objectclass *map_find_objectclass_remote(struct ldb_map_context *privdat, const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; privdat->objectclass_maps[i].remote_name; i++) {
|
||||
if (!ldb_attr_cmp(privdat->objectclass_maps[i].remote_name, name))
|
||||
return &privdat->objectclass_maps[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct map_private {
|
||||
struct ldb_map_context context;
|
||||
const char *last_err_string;
|
||||
@ -105,41 +114,39 @@ static struct ldb_map_context *map_get_privdat(struct ldb_module *module)
|
||||
return &((struct map_private *)module->private_data)->context;
|
||||
}
|
||||
|
||||
static const struct ldb_map_objectclass *map_find_objectclass_local(struct ldb_map_context *privdat, const char *name)
|
||||
/* Check whether the given attribute can fit into the specified
|
||||
* message, obeying objectClass restrictions */
|
||||
static int map_msg_valid_attr(struct ldb_module *module, const struct ldb_message *msg, const char *attr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; privdat->objectclass_maps[i].local_name; i++) {
|
||||
if (!ldb_attr_cmp(privdat->objectclass_maps[i].local_name, name))
|
||||
return &privdat->objectclass_maps[i];
|
||||
}
|
||||
struct ldb_map_context *map = module->private_data;
|
||||
int i, j;
|
||||
struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Decide whether a add/modify should be pushed to the
|
||||
* remote LDAP server. We currently only do this if we see an objectClass we know */
|
||||
static int map_is_mappable(struct ldb_map_context *privdat, const struct ldb_message *msg)
|
||||
{
|
||||
int i;
|
||||
struct ldb_message_element *el;
|
||||
|
||||
if (ldb_dn_is_special(msg->dn))
|
||||
return 0;
|
||||
|
||||
el = ldb_msg_find_element(msg, "objectClass");
|
||||
|
||||
/* No objectClass... */
|
||||
if (el == NULL) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Can't find objectClass");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < el->num_values; i++) {
|
||||
if (map_find_objectclass_local(privdat, (char *)el->values[i].data))
|
||||
return 1;
|
||||
const struct ldb_map_objectclass *class = map_find_objectclass_remote(map, (char *)el->values[i].data);
|
||||
|
||||
if (!class)
|
||||
continue;
|
||||
|
||||
for (j = 0; class->musts[j]; j++) {
|
||||
if (!ldb_attr_cmp(class->musts[j], attr))
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (j = 0; class->mays[j]; j++) {
|
||||
if (!ldb_attr_cmp(class->mays[j], attr))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
@ -154,6 +161,40 @@ static const struct ldb_map_attribute *map_find_attr_local(struct ldb_map_contex
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if a given attribute can be created by doing mapping from a local attribute to a remote one */
|
||||
static int map_msg_can_map_attr(struct ldb_module *module, const struct ldb_message *msg, const char *attr_name)
|
||||
{
|
||||
struct ldb_map_context *map = module->private_data;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < msg->num_elements; i++) {
|
||||
const struct ldb_map_attribute *attr = map_find_attr_local(map, msg->elements[i].name);
|
||||
|
||||
if (!attr)
|
||||
continue;
|
||||
|
||||
switch (attr->type) {
|
||||
case MAP_IGNORE: continue;
|
||||
case MAP_KEEP:
|
||||
if (ldb_attr_cmp(attr->local_name, attr_name) == 0) return 1;
|
||||
break;
|
||||
case MAP_RENAME:
|
||||
case MAP_CONVERT:
|
||||
if (ldb_attr_cmp(attr->u.rename.remote_name, attr_name) == 0) return 1;
|
||||
break;
|
||||
case MAP_GENERATE:
|
||||
for (j = 0; attr->u.generate.remote_names[j]; j++) {
|
||||
if (ldb_attr_cmp(attr->u.generate.remote_names[j], attr_name) == 0) return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* find an attribute by the remote name */
|
||||
static const struct ldb_map_attribute *map_find_attr_remote(struct ldb_map_context *privdat, const char *attr)
|
||||
{
|
||||
@ -547,8 +588,6 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
|
||||
|
||||
msg->dn = map_remote_dn(module, 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() */
|
||||
|
||||
@ -638,94 +677,6 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
|
||||
return msg;
|
||||
}
|
||||
|
||||
/* Used for add, modify */
|
||||
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 = map_get_privdat(module);
|
||||
struct ldb_message_element *elm;
|
||||
int i,j;
|
||||
|
||||
*fb = talloc_zero(module, struct ldb_message);
|
||||
(*fb)->dn = talloc_reference(*fb, mo->dn);
|
||||
|
||||
*mp = talloc_zero(module, struct ldb_message);
|
||||
(*mp)->dn = map_local_dn(module, module, mo->dn);
|
||||
|
||||
/* Loop over mi and call generate_remote for each attribute */
|
||||
for (i = 0; i < mo->num_elements; i++) {
|
||||
const struct ldb_map_attribute *attr = map_find_attr_local(privdat, mo->elements[i].name);
|
||||
enum ldb_map_attr_type map_type;
|
||||
|
||||
if (!attr) {
|
||||
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: /* 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(*mp, struct ldb_message_element);
|
||||
|
||||
elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
|
||||
elm->num_values = mo->elements[i].num_values;
|
||||
elm->values = talloc_reference(elm, mo->elements[i].values);
|
||||
|
||||
ldb_msg_add(module->ldb, *mp, elm, mo->elements[i].flags);
|
||||
break;
|
||||
|
||||
case MAP_CONVERT:
|
||||
elm = talloc(*mp, struct ldb_message_element);
|
||||
|
||||
elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
|
||||
elm->num_values = mo->elements[i].num_values;
|
||||
elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
|
||||
|
||||
for (j = 0; j < elm->num_values; j++) {
|
||||
elm->values[j] = attr->u.convert.convert_local(module, *mp, &mo->elements[i].values[j]);
|
||||
}
|
||||
|
||||
ldb_msg_add(module->ldb, *mp, elm, mo->elements[i].flags);
|
||||
break;
|
||||
|
||||
case MAP_KEEP:
|
||||
elm = talloc(*mp, 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, *mp, elm, mo->elements[i].flags);
|
||||
break;
|
||||
|
||||
case MAP_GENERATE:
|
||||
attr->u.generate.generate_remote(module, attr->local_name, mo, *mp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*fb)->num_elements == 0) {
|
||||
ldb_msg_add_string(module->ldb, *fb, "isMapped", "TRUE");
|
||||
}
|
||||
|
||||
if ((*mp)->num_elements == 0) {
|
||||
/* No elements, discard.. */
|
||||
talloc_free(*mp);
|
||||
*mp = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
rename a record
|
||||
*/
|
||||
@ -734,6 +685,13 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con
|
||||
struct ldb_map_context *privdat = map_get_privdat(module);
|
||||
struct ldb_dn *n_olddn, *n_newdn;
|
||||
int fb_ret, mp_ret;
|
||||
|
||||
fb_ret = ldb_next_rename_record(module, olddn, newdn);
|
||||
|
||||
if (fb_ret != -1) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record renamed");
|
||||
return fb_ret;
|
||||
}
|
||||
|
||||
n_olddn = map_local_dn(module, module, olddn);
|
||||
n_newdn = map_local_dn(module, module, newdn);
|
||||
@ -743,16 +701,12 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Mapped record renamed");
|
||||
}
|
||||
|
||||
fb_ret = ldb_next_rename_record(module, olddn, newdn);
|
||||
ldb_next_rename_record(module, olddn, newdn);
|
||||
|
||||
if (fb_ret != -1) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record renamed");
|
||||
}
|
||||
|
||||
talloc_free(n_olddn);
|
||||
talloc_free(n_newdn);
|
||||
|
||||
return (fb_ret == -1 && mp_ret == -1)?-1:0;
|
||||
return mp_ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -764,6 +718,12 @@ static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
|
||||
struct ldb_dn *newdn;
|
||||
int fb_ret, mp_ret;
|
||||
|
||||
fb_ret = ldb_next_delete_record(module, dn);
|
||||
if (fb_ret != -1) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record deleted");
|
||||
return fb_ret;
|
||||
}
|
||||
|
||||
newdn = map_local_dn(module, module, dn);
|
||||
|
||||
mp_ret = ldb_delete(privdat->mapped_ldb, newdn);
|
||||
@ -771,14 +731,11 @@ static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Mapped record deleted");
|
||||
}
|
||||
|
||||
fb_ret = ldb_next_delete_record(module, dn);
|
||||
if (fb_ret != -1) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record deleted");
|
||||
}
|
||||
ldb_next_delete_record(module, newdn);
|
||||
|
||||
talloc_free(newdn);
|
||||
|
||||
return (fb_ret == -1 && mp_ret == -1)?-1:0;
|
||||
return mp_ret;
|
||||
}
|
||||
|
||||
/* search fallback database */
|
||||
@ -869,7 +826,7 @@ static int map_search_bytree_mp(struct ldb_module *module, const struct ldb_dn *
|
||||
|
||||
merged = ldb_map_message_incoming(module, attrs, newres[i]);
|
||||
|
||||
/* Merge with additional data from local database */
|
||||
/* Merge with additional data from fallback database */
|
||||
extraret = ldb_next_search(module, merged->dn, LDB_SCOPE_BASE, "", NULL, &extrares);
|
||||
|
||||
if (extraret == -1) {
|
||||
@ -888,10 +845,6 @@ static int map_search_bytree_mp(struct ldb_module *module, const struct ldb_dn *
|
||||
for (j = 0; j < extrares[0]->num_elements; j++) {
|
||||
ldb_msg_add(module->ldb, merged, &(extrares[0]->elements[j]), extrares[0]->elements[j].flags);
|
||||
}
|
||||
|
||||
ldb_msg_add_string(module->ldb, merged, "extraMapped", "TRUE");
|
||||
} else {
|
||||
ldb_msg_add_string(module->ldb, merged, "extraMapped", "FALSE");
|
||||
}
|
||||
|
||||
if (ldb_match_msg(module->ldb, merged, tree, base, scope) != 0) {
|
||||
@ -966,6 +919,20 @@ static int map_search(struct ldb_module *module, const struct ldb_dn *base,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msg_contains_objectclass(const struct ldb_message *msg, const char *name)
|
||||
{
|
||||
struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass");
|
||||
int i;
|
||||
|
||||
for (i = 0; i < el->num_values; i++) {
|
||||
if (ldb_attr_cmp((char *)el->values[i].data, name) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
add a record
|
||||
*/
|
||||
@ -974,32 +941,159 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
|
||||
int ret;
|
||||
struct ldb_map_context *privdat = map_get_privdat(module);
|
||||
struct ldb_message *fb, *mp;
|
||||
struct ldb_message_element *ocs;
|
||||
int i;
|
||||
|
||||
if (!map_is_mappable(privdat, msg)) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add");
|
||||
|
||||
if (ldb_dn_is_special(msg->dn)) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added fallback record");
|
||||
return ldb_next_add_record(module, msg);
|
||||
}
|
||||
|
||||
if (ldb_map_message_outgoing(module, msg, &fb, &mp) == -1)
|
||||
return -1;
|
||||
mp = talloc_zero(module, struct ldb_message);
|
||||
mp->dn = map_local_dn(module, mp, msg->dn);
|
||||
|
||||
if (fb != NULL) {
|
||||
ret = ldb_next_add_record(module, fb);
|
||||
if (ret == -1) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Adding fallback record failed");
|
||||
return -1;
|
||||
fb = talloc_zero(module, struct ldb_message);
|
||||
fb->dn = talloc_reference(fb, msg->dn);
|
||||
|
||||
/* We add objectClass, so 'top' should be no problem */
|
||||
ldb_msg_add_string(module->ldb, mp, "objectClass", "top");
|
||||
|
||||
/* make a list of remote objectclasses that can be used
|
||||
* given the attributes that are available and add to
|
||||
* mp_msg */
|
||||
for (i = 0; privdat->objectclass_maps[i].local_name; i++) {
|
||||
int j, has_musts, has_baseclasses;
|
||||
|
||||
/* Add this objectClass to the list if all musts are present */
|
||||
for (j = 0; privdat->objectclass_maps[i].musts[j]; j++) {
|
||||
if (!map_msg_can_map_attr(module, msg, privdat->objectclass_maps[i].musts[j]))
|
||||
break;
|
||||
}
|
||||
|
||||
has_musts = (privdat->objectclass_maps[i].musts[j] == NULL);
|
||||
|
||||
/* Check if base classes are present as well */
|
||||
for (j = 0; privdat->objectclass_maps[i].base_classes[j]; j++) {
|
||||
if (!msg_contains_objectclass(mp, privdat->objectclass_maps[i].base_classes[j]))
|
||||
break;
|
||||
}
|
||||
|
||||
has_baseclasses = (privdat->objectclass_maps[i].base_classes[j] == NULL);
|
||||
|
||||
/* Apparently, it contains all required elements */
|
||||
if (has_musts && has_baseclasses) {
|
||||
ldb_msg_add_string(module->ldb, mp, "objectClass", privdat->objectclass_maps[i].remote_name);
|
||||
}
|
||||
}
|
||||
|
||||
ocs = ldb_msg_find_element(mp, "objectClass");
|
||||
if (ocs->num_values == 1) { /* Only top */
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added fallback record");
|
||||
return ldb_next_add_record(module, msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* - try to map as much attributes as possible where allowed and add them to mp_msg
|
||||
* - add other attributes to fb_msg
|
||||
*/
|
||||
for (i = 0; i < msg->num_elements; i++) {
|
||||
const struct ldb_map_attribute *attr;
|
||||
struct ldb_message_element *elm;
|
||||
enum ldb_map_attr_type map_type;
|
||||
int j;
|
||||
int mapped = 0;
|
||||
|
||||
if (ldb_attr_cmp(msg->elements[i].name, "objectClass") == 0)
|
||||
continue;
|
||||
|
||||
attr = map_find_attr_local(privdat, msg->elements[i].name);
|
||||
|
||||
if (!attr) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Undefined local attribute '%s', ignoring\n", msg->elements[i].name);
|
||||
map_type = MAP_IGNORE;
|
||||
} else map_type = attr->type;
|
||||
|
||||
/* Decide whether or not we need to map or fallback */
|
||||
switch (map_type) {
|
||||
case MAP_GENERATE:
|
||||
attr->u.generate.generate_remote(module, attr->local_name, msg, mp, fb);
|
||||
continue;
|
||||
case MAP_KEEP:
|
||||
mapped = map_msg_valid_attr(module, mp, attr->local_name);
|
||||
case MAP_IGNORE: mapped = 0; break;
|
||||
case MAP_CONVERT:
|
||||
case MAP_RENAME: mapped = map_msg_valid_attr(module, mp, attr->u.rename.remote_name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mapped) {
|
||||
switch (map_type) {
|
||||
case MAP_KEEP:
|
||||
elm = talloc(fb, struct ldb_message_element);
|
||||
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_reference(elm, msg->elements[i].values);
|
||||
elm->name = talloc_strdup(elm, msg->elements[i].name);
|
||||
break;
|
||||
|
||||
case MAP_RENAME:
|
||||
elm = talloc(mp, struct ldb_message_element);
|
||||
|
||||
elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_reference(elm, msg->elements[i].values);
|
||||
break;
|
||||
|
||||
case MAP_CONVERT:
|
||||
elm = talloc(mp, struct ldb_message_element);
|
||||
|
||||
elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
|
||||
|
||||
for (j = 0; j < elm->num_values; j++) {
|
||||
elm->values[j] = attr->u.convert.convert_local(module, mp, &msg->elements[i].values[j]);
|
||||
}
|
||||
|
||||
mapped = map_msg_valid_attr(module, mp, attr->u.convert.remote_name);
|
||||
|
||||
break;
|
||||
|
||||
case MAP_GENERATE:
|
||||
case MAP_IGNORE:
|
||||
ldb_debug(module->ldb, LDB_DEBUG_FATAL, "This line should never be reached");
|
||||
break;
|
||||
}
|
||||
ldb_msg_add(module->ldb, mp, elm, 0);
|
||||
} else {
|
||||
elm = talloc(fb, struct ldb_message_element);
|
||||
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_reference(elm, msg->elements[i].values);
|
||||
elm->name = talloc_strdup(elm, msg->elements[i].name);
|
||||
|
||||
ldb_msg_add(module->ldb, fb, elm, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ret = ldb_add(privdat->mapped_ldb, mp);
|
||||
if (ret == -1) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Adding mapped record failed: %s", ldb_errstring(privdat->mapped_ldb));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added mapped record");
|
||||
|
||||
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_WARNING, "Adding fallback record failed: %s", ldb_next_errstring(module));
|
||||
return -1;
|
||||
}
|
||||
|
||||
talloc_free(fb);
|
||||
|
||||
if (mp != NULL) {
|
||||
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(mp);
|
||||
|
||||
return ret;
|
||||
@ -1013,25 +1107,106 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
|
||||
{
|
||||
struct ldb_map_context *privdat = map_get_privdat(module);
|
||||
struct ldb_message *fb, *mp;
|
||||
int ret;
|
||||
struct ldb_message_element *elm;
|
||||
int fb_ret, mp_ret;
|
||||
int i,j;
|
||||
|
||||
if (!map_is_mappable(privdat, msg))
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_modify");
|
||||
|
||||
if (ldb_dn_is_special(msg->dn))
|
||||
return ldb_next_modify_record(module, msg);
|
||||
|
||||
if (ldb_map_message_outgoing(module, msg, &fb, &mp) == -1)
|
||||
return -1;
|
||||
fb = talloc_zero(module, struct ldb_message);
|
||||
fb->dn = talloc_reference(fb, msg->dn);
|
||||
|
||||
if (fb != NULL) {
|
||||
ret = ldb_next_modify_record(module, fb);
|
||||
talloc_free(fb);
|
||||
mp = talloc_zero(module, struct ldb_message);
|
||||
mp->dn = map_local_dn(module, mp, msg->dn);
|
||||
|
||||
/* Loop over mi and call generate_remote for each attribute */
|
||||
for (i = 0; i < msg->num_elements; i++) {
|
||||
const struct ldb_map_attribute *attr;
|
||||
enum ldb_map_attr_type map_type;
|
||||
|
||||
if (ldb_attr_cmp(msg->elements[i].name, "isMapped") == 0)
|
||||
continue;
|
||||
|
||||
attr = map_find_attr_local(privdat, msg->elements[i].name);
|
||||
|
||||
if (!attr) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Undefined local attribute '%s', ignoring\n", msg->elements[i].name);
|
||||
map_type = MAP_IGNORE;
|
||||
} else map_type = attr->type;
|
||||
|
||||
switch (map_type) {
|
||||
case MAP_IGNORE: /* Add to fallback message */
|
||||
elm = talloc(fb, struct ldb_message_element);
|
||||
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_reference(elm, msg->elements[i].values);
|
||||
elm->name = talloc_strdup(elm, msg->elements[i].name);
|
||||
|
||||
ldb_msg_add(module->ldb, fb, elm, msg->elements[i].flags);
|
||||
break;
|
||||
case MAP_RENAME:
|
||||
elm = talloc(mp, struct ldb_message_element);
|
||||
|
||||
elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
|
||||
for (j = 0; j < elm->num_values; j++) {
|
||||
elm->values[j] = msg->elements[i].values[j];
|
||||
}
|
||||
|
||||
ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
|
||||
break;
|
||||
|
||||
case MAP_CONVERT:
|
||||
elm = talloc(mp, struct ldb_message_element);
|
||||
|
||||
elm->name = talloc_strdup(elm, attr->u.rename.remote_name);
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_array(elm, struct ldb_val, elm->num_values);
|
||||
|
||||
for (j = 0; j < elm->num_values; j++) {
|
||||
elm->values[j] = attr->u.convert.convert_local(module, mp, &msg->elements[i].values[j]);
|
||||
}
|
||||
|
||||
ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
|
||||
break;
|
||||
|
||||
case MAP_KEEP:
|
||||
elm = talloc(mp, struct ldb_message_element);
|
||||
|
||||
elm->num_values = msg->elements[i].num_values;
|
||||
elm->values = talloc_reference(elm, msg->elements[i].values);
|
||||
elm->name = talloc_strdup(elm, msg->elements[i].name);
|
||||
|
||||
ldb_msg_add(module->ldb, mp, elm, msg->elements[i].flags);
|
||||
break;
|
||||
|
||||
case MAP_GENERATE:
|
||||
attr->u.generate.generate_remote(module, attr->local_name, msg, mp, fb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mp != NULL) {
|
||||
ret = ldb_modify(privdat->mapped_ldb, mp);
|
||||
talloc_free(mp);
|
||||
if (fb->num_elements > 0) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Modifying fallback record with %d elements", fb->num_elements);
|
||||
fb_ret = ldb_next_modify_record(module, fb);
|
||||
if (fb_ret == -1) {
|
||||
ldb_msg_add_string(module->ldb, fb, "isMapped", "TRUE");
|
||||
fb_ret = ldb_next_add_record(module, fb);
|
||||
}
|
||||
}
|
||||
talloc_free(fb);
|
||||
|
||||
return ret;
|
||||
if (mp->num_elements > 0) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Modifying mapped record with %d elements", mp->num_elements);
|
||||
mp_ret = ldb_modify(privdat->mapped_ldb, mp);
|
||||
}
|
||||
talloc_free(mp);
|
||||
|
||||
return (mp_ret == -1 || fb_ret == -1)?-1:0;
|
||||
}
|
||||
|
||||
static int map_lock(struct ldb_module *module, const char *lockname)
|
||||
|
@ -81,7 +81,8 @@ struct ldb_map_attribute
|
||||
struct ldb_module *,
|
||||
const char *local_attr,
|
||||
const struct ldb_message *local,
|
||||
struct ldb_message *remote);
|
||||
struct ldb_message *remote_mp,
|
||||
struct ldb_message *remote_fb);
|
||||
|
||||
/* Name(s) for this attribute on the remote server. This is an array since
|
||||
* one local attribute's data can be split up into several attributes
|
||||
@ -92,15 +93,22 @@ struct ldb_map_attribute
|
||||
} u;
|
||||
};
|
||||
|
||||
#define LDB_MAP_MAX_SUBCLASSES 10
|
||||
#define LDB_MAP_MAX_MUSTS 10
|
||||
#define LDB_MAP_MAX_MAYS 50
|
||||
struct ldb_map_objectclass
|
||||
{
|
||||
const char *local_name;
|
||||
const char *remote_name;
|
||||
const char *base_classes[LDB_MAP_MAX_SUBCLASSES];
|
||||
const char *musts[LDB_MAP_MAX_MUSTS];
|
||||
const char *mays[LDB_MAP_MAX_MAYS];
|
||||
};
|
||||
|
||||
struct ldb_map_context
|
||||
{
|
||||
struct ldb_map_attribute *attribute_maps;
|
||||
/* NOTE: Always declare base classes first here */
|
||||
const struct ldb_map_objectclass *objectclass_maps;
|
||||
struct ldb_context *mapped_ldb;
|
||||
};
|
||||
|
@ -541,11 +541,6 @@ function upgrade(subobj, samba3, message, paths)
|
||||
// Enable samba3sam module if original passdb backend was ldap
|
||||
if (ldapurl != undefined) {
|
||||
message("Enabling Samba3 LDAP mappings for SAM database\n");
|
||||
var ldif = sprintf("
|
||||
dn: @MAP=samba3sam
|
||||
@MAP_URL: %s", ldapurl);
|
||||
ok = samdb.add(ldif);
|
||||
assert(ok);
|
||||
|
||||
ok = samdb.modify("
|
||||
dn: @MODULES
|
||||
@ -557,6 +552,12 @@ replace: @LIST
|
||||
message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
|
||||
ret = ret + 1;
|
||||
}
|
||||
|
||||
ok = samdb.add(sprintf("
|
||||
dn: @MAP=samba3sam
|
||||
@MAP_URL: %s", ldapurl));
|
||||
assert(ok);
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
43
testdata/samba3/samba3.ldif
vendored
43
testdata/samba3/samba3.ldif
vendored
@ -1,12 +1,19 @@
|
||||
dn: ou=Users,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectclass: sambaDomain
|
||||
objectclass: top
|
||||
sambaSID: S-1-5-21-4231626423-2410014848-2360679739
|
||||
sambaNextRid: 2000
|
||||
sambaDomainName: TESTS
|
||||
|
||||
dn: ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: organizationalUnit
|
||||
ou: Users
|
||||
|
||||
dn: ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: organizationalUnit
|
||||
ou: Groups
|
||||
|
||||
dn: uid=nobody,ou=Users,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: uid=nobody,ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
cn: nobody
|
||||
sn: nobody
|
||||
objectClass: inetOrgPerson
|
||||
@ -33,7 +40,7 @@ sambaAcctFlags: [NU ]
|
||||
sambaSID: S-1-5-21-4231626423-2410014848-2360679739-2998
|
||||
loginShell: /bin/false
|
||||
|
||||
dn: cn=Domain Admins,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Domain Admins,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 512
|
||||
@ -44,7 +51,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-512
|
||||
sambaGroupType: 2
|
||||
displayName: Domain Admins
|
||||
|
||||
dn: cn=Domain Users,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Domain Users,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 513
|
||||
@ -54,7 +61,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-513
|
||||
sambaGroupType: 2
|
||||
displayName: Domain Users
|
||||
|
||||
dn: cn=Domain Guests,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Domain Guests,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 514
|
||||
@ -64,7 +71,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-514
|
||||
sambaGroupType: 2
|
||||
displayName: Domain Guests
|
||||
|
||||
dn: cn=Print Operators,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Print Operators,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 550
|
||||
@ -74,7 +81,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-550
|
||||
sambaGroupType: 2
|
||||
displayName: Print Operators
|
||||
|
||||
dn: cn=Backup Operators,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Backup Operators,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 551
|
||||
@ -84,7 +91,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-551
|
||||
sambaGroupType: 2
|
||||
displayName: Backup Operators
|
||||
|
||||
dn: cn=Replicator,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Replicator,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 552
|
||||
@ -94,7 +101,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-552
|
||||
sambaGroupType: 2
|
||||
displayName: Replicator
|
||||
|
||||
dn: cn=Domain Computers,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Domain Computers,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 553
|
||||
@ -104,7 +111,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-553
|
||||
sambaGroupType: 2
|
||||
displayName: Domain Computers
|
||||
|
||||
dn: cn=Administrators,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Administrators,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 544
|
||||
@ -114,7 +121,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-544
|
||||
sambaGroupType: 2
|
||||
displayName: Administrators
|
||||
|
||||
dn: cn=Users,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Users,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 545
|
||||
@ -124,7 +131,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-545
|
||||
sambaGroupType: 2
|
||||
displayName: users
|
||||
|
||||
dn: cn=Guests,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Guests,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 546
|
||||
@ -135,7 +142,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-546
|
||||
sambaGroupType: 2
|
||||
displayName: Guests
|
||||
|
||||
dn: cn=Power Users,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Power Users,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 547
|
||||
@ -145,7 +152,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-547
|
||||
sambaGroupType: 2
|
||||
displayName: Power Users
|
||||
|
||||
dn: cn=Account Operators,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Account Operators,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 548
|
||||
@ -155,7 +162,7 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-548
|
||||
sambaGroupType: 2
|
||||
displayName: Account Operators
|
||||
|
||||
dn: cn=Server Operators,ou=Groups,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Server Operators,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: posixGroup
|
||||
objectClass: sambaGroupMapping
|
||||
gidNumber: 549
|
||||
@ -165,11 +172,11 @@ sambaSID: S-1-5-21-4231626423-2410014848-2360679739-549
|
||||
sambaGroupType: 2
|
||||
displayName: Server Operators
|
||||
|
||||
dn: ou=Computers,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: ou=Computers,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: organizationalUnit
|
||||
ou: Computers
|
||||
|
||||
dn: uid=Administrator,ou=Users,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: uid=Administrator,ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
cn: Administrator
|
||||
sn: Administrator
|
||||
objectClass: inetOrgPerson
|
||||
|
@ -40,6 +40,16 @@ assert(ldif != undefined);
|
||||
ok = s4.add(ldif);
|
||||
assert(ok);
|
||||
|
||||
var ldif = sys.file_load(mypath + "../../source/setup/provision_templates.ldif");
|
||||
var subobj = new Object();
|
||||
subobj.BASEDN = "dc=vernstok,dc=nl";
|
||||
ldif = substitute_var(ldif, subobj);
|
||||
assert(ldif != undefined);
|
||||
ok = s4.add(ldif);
|
||||
assert(ok);
|
||||
|
||||
|
||||
|
||||
ok = s4.add(sprintf("dn: @MAP=samba3sam
|
||||
@MAP_URL: %s", s3url));
|
||||
assert(ok);
|
||||
@ -57,7 +67,6 @@ assert(ok);
|
||||
|
||||
msg = s4.search("(ou=Users)");
|
||||
assert(msg.length == 1);
|
||||
assert(msg['mappedFromDn'] == msg['dn']);
|
||||
|
||||
println("Looking up by non-mapped attribute");
|
||||
msg = s4.search("(cn=Administrator)");
|
||||
@ -76,9 +85,8 @@ assert(msg.length == 0);
|
||||
println("Looking up mapped entry containing SID");
|
||||
msg = s4.search("(cn=Replicator)");
|
||||
assert(msg.length == 1);
|
||||
assert(msg[0].dn == "cn=Replicator,ou=Groups,ou=Tests,dc=vernstok,dc=nl");
|
||||
assert(msg[0].dn == "cn=Replicator,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl");
|
||||
assert(msg[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
|
||||
assert(msg[0].mappedFromDn == msg[0].dn);
|
||||
|
||||
println("Checking mapping of objectclass");
|
||||
var oc = msg[0].objectclass;
|
||||
@ -89,24 +97,23 @@ for (var i in oc) {
|
||||
println("Adding a record that will be fallbacked");
|
||||
ok = s4.add("
|
||||
dn: cn=Foo,dc=idealx,dc=org
|
||||
unixName: root
|
||||
lastLogon: 20000
|
||||
foo: bar
|
||||
blah: Blie
|
||||
cn: Foo
|
||||
showInAdvancedViewOnly: TRUE
|
||||
");
|
||||
assert(ok);
|
||||
|
||||
println("Checking for existance of record");
|
||||
msg = s4.search("(cn=Foo)", new Array('unixName','lastLogon','cn','showInAdvancedViewOnly'));
|
||||
msg = s4.search("(cn=Foo)", new Array('foo','blah','cn','showInAdvancedViewOnly'));
|
||||
assert(msg.length == 1);
|
||||
assert(msg[0].showInAdvancedViewOnly == "TRUE");
|
||||
assert(msg[0].cn == "Foo");
|
||||
assert(msg[0].unixName == "root");
|
||||
assert(msg[0].lastLogon == 20000);
|
||||
assert(msg[0].foo == "bar");
|
||||
assert(msg[0].blah == "Blie");
|
||||
|
||||
println("Adding record that will be mapped");
|
||||
ok = s4.add("
|
||||
dn: cn=Niemand,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
objectClass: user
|
||||
unixName: blah
|
||||
cn: Niemand
|
||||
@ -116,15 +123,17 @@ assert(ok);
|
||||
println("Checking for existance of record (mapped)");
|
||||
msg = s4.search("(unixName=blah)", new Array('unixName','cn','dn'));
|
||||
assert(msg.length == 1);
|
||||
assert(msg[0].cn == "Niemand");
|
||||
|
||||
println("Checking for data in destination database");
|
||||
msg = s3.search("(cn=Niemand)");
|
||||
msg = s3.search("(displayName=Niemand)");
|
||||
assert(msg.length >= 1);
|
||||
assert(msg[0].sambaSID == "S-1-5-21-4231626423-2410014848-2360679739-2001");
|
||||
assert(msg[0].displayName == "Niemand");
|
||||
|
||||
println("Adding attribute...");
|
||||
ok = s4.modify("
|
||||
dn: cn=Niemand,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
changetype: modify
|
||||
add: description
|
||||
description: Blah
|
||||
@ -134,11 +143,13 @@ assert(ok);
|
||||
println("Checking whether changes are still there...");
|
||||
msg = s4.search("(cn=Niemand)");
|
||||
assert(msg.length >= 1);
|
||||
printVars(msg);
|
||||
assert(msg[0].cn == "Niemand");
|
||||
assert(msg[0].description == "Blah");
|
||||
|
||||
println("Modifying attribute...");
|
||||
ok = s4.modify("
|
||||
dn: cn=Niemand,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
changetype: modify
|
||||
replace: description
|
||||
description: Blie
|
||||
@ -152,7 +163,7 @@ assert(msg[0].description == "Blie");
|
||||
|
||||
println("Deleting attribute...");
|
||||
ok = s4.modify("
|
||||
dn: cn=Niemand,ou=Tests,dc=vernstok,dc=nl
|
||||
dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
|
||||
changetype: modify
|
||||
delete: description
|
||||
");
|
||||
@ -164,7 +175,7 @@ assert(msg.length >= 1);
|
||||
assert(msg[0].description == undefined);
|
||||
|
||||
println("Renaming record...");
|
||||
ok = s4.rename("cn=Niemand,ou=Tests,dc=vernstok,dc=nl", "cn=Niemand,dc=vernstok,dc=nl");
|
||||
ok = s4.rename("cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl", "cn=Niemand,dc=vernstok,dc=nl");
|
||||
|
||||
println("Checking whether DN has changed...");
|
||||
msg = s4.search("(cn=Niemand)");
|
||||
|
Loading…
Reference in New Issue
Block a user