mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r23560: - Activate metze's schema modules (from metze's schema-loading-13 patch).
- samba3sam.js: rework the samba3sam test to not use objectCategory, as it's has special rules (dnsName a simple match) - ldap.js: Test the ordering of the objectClass attributes for the baseDN - schema_init.c: Load the mayContain and mustContain (and system...) attributes when reading the schema from ldb - To make the schema load not suck in terms of performance, write the schema into a static global variable - ldif_handlers.c: Match objectCategory for equality and canonicolisation based on the loaded schema, not simple tring manipuation - ldb_msg.c: don't duplicate attributes when adding attributes to a list - kludge_acl.c: return allowedAttributesEffective based on schema results and privilages Andrew Bartlett
This commit is contained in:
parent
5410b23ea6
commit
dcff83ebe4
@ -37,6 +37,7 @@
|
||||
#include "ldb/include/ldb_private.h"
|
||||
#include "auth/auth.h"
|
||||
#include "libcli/security/security.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
|
||||
/* Kludge ACL rules:
|
||||
*
|
||||
@ -105,13 +106,74 @@ struct kludge_acl_context {
|
||||
int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *);
|
||||
|
||||
enum user_is user_type;
|
||||
bool allowedAttributes;
|
||||
bool allowedAttributesEffective;
|
||||
const char **attrs;
|
||||
};
|
||||
|
||||
/* read all objectClasses */
|
||||
|
||||
static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_message *msg,
|
||||
const char *attrName)
|
||||
{
|
||||
struct ldb_message_element *oc_el = ldb_msg_find_element(msg, "objectClass");
|
||||
struct ldb_message_element *allowedAttributes;
|
||||
const struct dsdb_schema *schema = dsdb_get_schema(ldb);
|
||||
const struct dsdb_class *class;
|
||||
int i, j, ret;
|
||||
ret = ldb_msg_add_empty(msg, attrName, 0, &allowedAttributes);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i=0; i < oc_el->num_values; i++) {
|
||||
class = dsdb_class_by_lDAPDisplayName(schema, (const char *)oc_el->values[i].data);
|
||||
if (!class) {
|
||||
/* We don't know this class? what is going on? */
|
||||
continue;
|
||||
}
|
||||
for (j=0; class->mayContain && class->mayContain[j]; j++) {
|
||||
ldb_msg_add_string(msg, attrName, class->mayContain[j]);
|
||||
}
|
||||
for (j=0; class->mustContain && class->mustContain[j]; j++) {
|
||||
ldb_msg_add_string(msg, attrName, class->mustContain[j]);
|
||||
}
|
||||
for (j=0; class->systemMayContain && class->systemMayContain[j]; j++) {
|
||||
ldb_msg_add_string(msg, attrName, class->systemMayContain[j]);
|
||||
}
|
||||
for (j=0; class->systemMustContain && class->systemMustContain[j]; j++) {
|
||||
ldb_msg_add_string(msg, attrName, class->systemMustContain[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (allowedAttributes->num_values > 1) {
|
||||
qsort(allowedAttributes->values,
|
||||
allowedAttributes->num_values,
|
||||
sizeof(*allowedAttributes->values),
|
||||
data_blob_cmp);
|
||||
|
||||
for (i=1 ; i < allowedAttributes->num_values; i++) {
|
||||
struct ldb_val *val1 = &allowedAttributes->values[i-1];
|
||||
struct ldb_val *val2 = &allowedAttributes->values[i];
|
||||
if (data_blob_cmp(val1, val2) == 0) {
|
||||
memmove(val1, val2, (allowedAttributes->num_values - i) * sizeof( struct ldb_val));
|
||||
allowedAttributes->num_values--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* find all attributes allowed by all these objectClasses */
|
||||
|
||||
static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
|
||||
{
|
||||
struct kludge_acl_context *ac;
|
||||
struct kludge_private_data *data;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
if (!context || !ares) {
|
||||
ldb_set_errstring(ldb, "NULL Context or Result in callback");
|
||||
@ -121,12 +183,28 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
|
||||
ac = talloc_get_type(context, struct kludge_acl_context);
|
||||
data = talloc_get_type(ac->module->private_data, struct kludge_private_data);
|
||||
|
||||
if (ares->type == LDB_REPLY_ENTRY
|
||||
&& data && data->password_attrs) /* if we are not initialized just get through */
|
||||
if (ares->type != LDB_REPLY_ENTRY) {
|
||||
return ac->up_callback(ldb, ac->up_context, ares);
|
||||
}
|
||||
|
||||
if (ac->allowedAttributes) {
|
||||
ret = kludge_acl_allowedAttributes(ldb, ares->message, "allowedAttributes");
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (data && data->password_attrs) /* if we are not initialized just get through */
|
||||
{
|
||||
switch (ac->user_type) {
|
||||
case SYSTEM:
|
||||
case ADMINISTRATOR:
|
||||
if (ac->allowedAttributesEffective) {
|
||||
ret = kludge_acl_allowedAttributes(ldb, ares->message, "allowedAttributesEffective");
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* remove password attributes */
|
||||
@ -136,6 +214,12 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
|
||||
}
|
||||
}
|
||||
|
||||
if ((ac->allowedAttributes || ac->allowedAttributesEffective) &&
|
||||
(!ldb_attr_in_list(ac->attrs, "objectClass") &&
|
||||
!ldb_attr_in_list(ac->attrs, "*"))) {
|
||||
ldb_msg_remove_attr(ares->message, "objectClass");
|
||||
}
|
||||
|
||||
return ac->up_callback(ldb, ac->up_context, ares);
|
||||
|
||||
error:
|
||||
@ -163,6 +247,7 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
|
||||
ac->up_context = req->context;
|
||||
ac->up_callback = req->callback;
|
||||
ac->user_type = what_is_user(module);
|
||||
ac->attrs = req->op.search.attrs;
|
||||
|
||||
down_req = talloc_zero(req, struct ldb_request);
|
||||
if (down_req == NULL) {
|
||||
@ -175,6 +260,14 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
|
||||
down_req->op.search.tree = req->op.search.tree;
|
||||
down_req->op.search.attrs = req->op.search.attrs;
|
||||
|
||||
ac->allowedAttributes = ldb_attr_in_list(req->op.search.attrs, "allowedAttributes");
|
||||
|
||||
ac->allowedAttributesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedAttributesEffective");
|
||||
|
||||
if (ac->allowedAttributes || ac->allowedAttributesEffective) {
|
||||
down_req->op.search.attrs
|
||||
= ldb_attr_list_copy_add(down_req, down_req->op.search.attrs, "objectClass");
|
||||
}
|
||||
|
||||
/* FIXME: I hink we should copy the tree and keep the original
|
||||
* unmodified. SSS */
|
||||
|
@ -54,6 +54,10 @@ static int schema_fsmo_init(struct ldb_module *module)
|
||||
NULL
|
||||
};
|
||||
|
||||
if (dsdb_get_schema(module->ldb)) {
|
||||
return ldb_next_init(module);
|
||||
}
|
||||
|
||||
schema_dn = samdb_schema_dn(module->ldb);
|
||||
if (!schema_dn) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING,
|
||||
|
@ -50,6 +50,7 @@ struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
|
||||
if (!ldb) {
|
||||
return NULL;
|
||||
}
|
||||
dsdb_make_schema_global(ldb);
|
||||
return ldb;
|
||||
}
|
||||
|
||||
|
@ -323,6 +323,34 @@ WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CT
|
||||
talloc_steal(mem_ctx, (p)->elem); \
|
||||
} while (0)
|
||||
|
||||
#define GET_STRING_LIST_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
|
||||
int get_string_list_counter; \
|
||||
struct ldb_message_element *get_string_list_el = ldb_msg_find_element(msg, attr); \
|
||||
if (get_string_list_el == NULL) { \
|
||||
if (strict) { \
|
||||
d_printf("%s: %s == NULL\n", __location__, attr); \
|
||||
return WERR_INVALID_PARAM; \
|
||||
} else { \
|
||||
(p)->elem = NULL; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
(p)->elem = talloc_array(mem_ctx, const char *, get_string_list_el->num_values + 1); \
|
||||
for (get_string_list_counter=0; \
|
||||
get_string_list_counter < get_string_list_el->num_values; \
|
||||
get_string_list_counter++) { \
|
||||
(p)->elem[get_string_list_counter] = talloc_strndup((p)->elem, \
|
||||
(const char *)get_string_list_el->values[get_string_list_counter].data, \
|
||||
get_string_list_el->values[get_string_list_counter].length); \
|
||||
if (!(p)->elem[get_string_list_counter]) { \
|
||||
d_printf("%s: talloc_strndup failed for %s\n", __location__, attr); \
|
||||
return WERR_NOMEM; \
|
||||
} \
|
||||
(p)->elem[get_string_list_counter+1] = NULL; \
|
||||
} \
|
||||
talloc_steal(mem_ctx, (p)->elem); \
|
||||
} while (0)
|
||||
|
||||
#define GET_BOOL_LDB(msg, attr, p, elem, strict) do { \
|
||||
const char *str; \
|
||||
str = samdb_result_string(msg, attr, NULL);\
|
||||
@ -466,13 +494,14 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
|
||||
|
||||
obj->systemAuxiliaryClass = NULL;
|
||||
obj->systemPossSuperiors = NULL;
|
||||
obj->systemMustContain = NULL;
|
||||
obj->systemMayContain = NULL;
|
||||
|
||||
obj->auxiliaryClass = NULL;
|
||||
obj->possSuperiors = NULL;
|
||||
obj->mustContain = NULL;
|
||||
obj->mayContain = NULL;
|
||||
|
||||
GET_STRING_LIST_LDB(msg, "systemMustContain", mem_ctx, obj, systemMustContain, False);
|
||||
GET_STRING_LIST_LDB(msg, "systemMayContain", mem_ctx, obj, systemMayContain, False);
|
||||
GET_STRING_LIST_LDB(msg, "mustContain", mem_ctx, obj, mustContain, False);
|
||||
GET_STRING_LIST_LDB(msg, "mayContain", mem_ctx, obj, mayContain, False);
|
||||
|
||||
GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
|
||||
|
||||
@ -930,6 +959,23 @@ const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema,
|
||||
const char *cn)
|
||||
{
|
||||
struct dsdb_class *cur;
|
||||
|
||||
if (!cn) return NULL;
|
||||
|
||||
/* TODO: add binary search */
|
||||
for (cur = schema->classes; cur; cur = cur->next) {
|
||||
if (strcasecmp(cur->cn, cn) != 0) continue;
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
|
||||
uint32_t id)
|
||||
{
|
||||
@ -964,6 +1010,22 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
static struct dsdb_schema *global_schema;
|
||||
|
||||
int dsdb_set_global_schema(struct ldb_context *ldb)
|
||||
{
|
||||
int ret;
|
||||
if (!global_schema) {
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
ret = ldb_set_opaque(ldb, "dsdb_schema", global_schema);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
const struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb)
|
||||
{
|
||||
const void *p;
|
||||
@ -983,6 +1045,26 @@ const struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb)
|
||||
return schema;
|
||||
}
|
||||
|
||||
void dsdb_make_schema_global(struct ldb_context *ldb)
|
||||
{
|
||||
const void *p;
|
||||
const struct dsdb_schema *schema;
|
||||
|
||||
/* see if we have a cached copy */
|
||||
p = ldb_get_opaque(ldb, "dsdb_schema");
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
schema = talloc_get_type(p, struct dsdb_schema);
|
||||
if (!schema) {
|
||||
return;
|
||||
}
|
||||
|
||||
talloc_steal(NULL, schema);
|
||||
global_schema = schema;
|
||||
}
|
||||
|
||||
WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df)
|
||||
{
|
||||
struct ldb_ldif *ldif;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "lib/ldb/include/ldb_errors.h"
|
||||
#include "lib/ldb/samba/ldif_handlers.h"
|
||||
#include "db_wrap.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
|
||||
static struct tdb_wrap *tdb_list;
|
||||
|
||||
@ -127,6 +128,10 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(lp_sam_url(), url) == 0) {
|
||||
dsdb_set_global_schema(ldb);
|
||||
}
|
||||
|
||||
ret = ldb_register_samba_handlers(ldb);
|
||||
if (ret == -1) {
|
||||
talloc_free(ldb);
|
||||
|
@ -666,7 +666,15 @@ const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *att
|
||||
{
|
||||
const char **ret;
|
||||
int i;
|
||||
for (i=0;attrs[i];i++) /* noop */ ;
|
||||
bool found = false;
|
||||
for (i=0;attrs[i];i++) {
|
||||
if (ldb_attr_cmp(attrs[i], new_attr) == 0) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return ldb_attr_list_copy(mem_ctx, attrs);
|
||||
}
|
||||
ret = talloc_array(mem_ctx, const char *, i+2);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
@ -686,7 +694,7 @@ const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *att
|
||||
int ldb_attr_in_list(const char * const *attrs, const char *attr)
|
||||
{
|
||||
int i;
|
||||
for (i=0;attrs[i];i++) {
|
||||
for (i=0;attrs && attrs[i];i++) {
|
||||
if (ldb_attr_cmp(attrs[i], attr) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -299,66 +299,53 @@ static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_c
|
||||
const struct ldb_val *in, struct ldb_val *out)
|
||||
{
|
||||
struct ldb_dn *dn1 = NULL;
|
||||
char *oc1, *oc2;
|
||||
const struct dsdb_schema *schema = dsdb_get_schema(ldb);
|
||||
const struct dsdb_class *class;
|
||||
|
||||
if (!schema) {
|
||||
*out = data_blob_talloc(mem_ctx, in->data, in->length);
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
dn1 = ldb_dn_new(mem_ctx, ldb, (char *)in->data);
|
||||
if ( ! ldb_dn_validate(dn1)) {
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)in->data, in->length);
|
||||
} else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
|
||||
const char *lDAPDisplayName = talloc_strndup(mem_ctx, (char *)in->data, in->length);
|
||||
class = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName);
|
||||
talloc_free(lDAPDisplayName);
|
||||
} else if (ldb_dn_get_comp_num(dn1) >= 1 && ldb_attr_cmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
|
||||
const struct ldb_val *val = ldb_dn_get_rdn_val(dn1);
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
const char *cn = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
class = dsdb_class_by_cn(schema, cn);
|
||||
talloc_free(cn);
|
||||
} else {
|
||||
talloc_free(dn1);
|
||||
return -1;
|
||||
}
|
||||
talloc_free(dn1);
|
||||
|
||||
if (!class) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
oc2 = ldb_casefold(ldb, mem_ctx, oc1);
|
||||
out->data = (void *)oc2;
|
||||
out->length = strlen(oc2);
|
||||
talloc_free(oc1);
|
||||
talloc_free(dn1);
|
||||
return 0;
|
||||
*out = data_blob_string_const(talloc_strdup(mem_ctx, class->lDAPDisplayName));
|
||||
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx,
|
||||
const struct ldb_val *v1,
|
||||
const struct ldb_val *v2)
|
||||
{
|
||||
struct ldb_dn *dn1 = NULL, *dn2 = NULL;
|
||||
const char *oc1, *oc2;
|
||||
|
||||
dn1 = ldb_dn_new(mem_ctx, ldb, (char *)v1->data);
|
||||
if ( ! ldb_dn_validate(dn1)) {
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)v1->data, v1->length);
|
||||
} else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
|
||||
const struct ldb_val *val = ldb_dn_get_rdn_val(dn1);
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
int ret1, ret2;
|
||||
struct ldb_val v1_canon, v2_canon;
|
||||
ret1 = ldif_canonicalise_objectCategory(ldb, mem_ctx, v1, &v1_canon);
|
||||
ret2 = ldif_canonicalise_objectCategory(ldb, mem_ctx, v2, &v2_canon);
|
||||
|
||||
if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
|
||||
return ldb_attr_cmp(v1_canon.data, v2_canon.data);
|
||||
} else {
|
||||
oc1 = NULL;
|
||||
return strcasecmp(v1->data, v2->data);
|
||||
}
|
||||
|
||||
dn2 = ldb_dn_new(mem_ctx, ldb, (char *)v2->data);
|
||||
if ( ! ldb_dn_validate(dn2)) {
|
||||
oc2 = talloc_strndup(mem_ctx, (char *)v2->data, v2->length);
|
||||
} else if (ldb_dn_get_comp_num(dn2) >= 2 && strcasecmp(ldb_dn_get_rdn_name(dn2), "cn") == 0) {
|
||||
const struct ldb_val *val = ldb_dn_get_rdn_val(dn2);
|
||||
oc2 = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
} else {
|
||||
oc2 = NULL;
|
||||
}
|
||||
|
||||
oc1 = ldb_casefold(ldb, mem_ctx, oc1);
|
||||
oc2 = ldb_casefold(ldb, mem_ctx, oc2);
|
||||
if (!oc1 && oc2) {
|
||||
return -1;
|
||||
}
|
||||
if (oc1 && !oc2) {
|
||||
return 1;
|
||||
}
|
||||
if (!oc1 && !oc2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return strcmp(oc1, oc2);
|
||||
}
|
||||
|
||||
#define LDB_SYNTAX_SAMBA_SID "LDB_SYNTAX_SAMBA_SID"
|
||||
|
@ -611,7 +611,7 @@ function provision(subobj, message, blank, paths, session_info, credentials, lda
|
||||
var modify_ok = setup_ldb_modify("provision_schema_basedn_modify.ldif", info, samdb);
|
||||
if (!modify_ok) {
|
||||
if (!add_ok) {
|
||||
message("Failed to both add and modify schema dn: + samdb.errstring() + "\n");
|
||||
message("Failed to both add and modify schema dn:" + samdb.errstring() + "\n");
|
||||
message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n");
|
||||
assert(modify_ok);
|
||||
}
|
||||
@ -744,7 +744,7 @@ function provision_schema(subobj, message, tmp_schema_path, paths)
|
||||
var modify_ok = setup_ldb_modify("provision_schema_basedn_modify.ldif", info, samdb);
|
||||
if (!modify_ok) {
|
||||
if (!add_ok) {
|
||||
message("Failed to both add and modify schema dn: + samdb.errstring() + "\n");
|
||||
message("Failed to both add and modify schema dn: " + samdb.errstring() + "\n");
|
||||
message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n");
|
||||
assert(modify_ok);
|
||||
}
|
||||
@ -882,16 +882,18 @@ function provision_guess()
|
||||
"extended_dn",
|
||||
"asq",
|
||||
"samldb",
|
||||
"password_hash",
|
||||
"operational",
|
||||
"objectclass",
|
||||
"rdn_name",
|
||||
"show_deleted",
|
||||
"partition");
|
||||
subobj.MODULES_LIST = join(",", modules_list);
|
||||
subobj.DOMAINDN_MOD = "objectguid";
|
||||
subobj.CONFIGDN_MOD = "objectguid";
|
||||
subobj.SCHEMADN_MOD = "objectguid";
|
||||
subobj.DOMAINDN_MOD = "pdc_fsmo,password_hash";
|
||||
subobj.CONFIGDN_MOD = "naming_fsmo";
|
||||
subobj.SCHEMADN_MOD = "schema_fsmo";
|
||||
subobj.DOMAINDN_MOD2 = ",objectguid";
|
||||
subobj.CONFIGDN_MOD2 = ",objectguid";
|
||||
subobj.SCHEMADN_MOD2 = ",objectguid";
|
||||
|
||||
subobj.EXTENSIBLEOBJECT = "# no objectClass: extensibleObject for local ldb";
|
||||
subobj.ACI = "# no aci for local ldb";
|
||||
|
@ -132,11 +132,11 @@ if (ldapbackend) {
|
||||
subobj["LDAPMODULE"] = "entryUUID";
|
||||
}
|
||||
subobj["DOMAINDN_LDB"] = subobj["LDAPBACKEND"];
|
||||
subobj["DOMAINDN_MOD"] = subobj["LDAPMODULE"] + ",paged_searches";
|
||||
subobj["DOMAINDN_MOD2"] = subobj["LDAPMODULE"] + ",paged_searches";
|
||||
subobj["CONFIGDN_LDB"] = subobj["LDAPBACKEND"];
|
||||
subobj["CONFIGDN_MOD"] = subobj["LDAPMODULE"] + ",paged_searches";
|
||||
subobj["CONFIGDN_MOD2"] = subobj["LDAPMODULE"] + ",paged_searches";
|
||||
subobj["SCHEMADN_LDB"] = subobj["LDAPBACKEND"];
|
||||
subobj["SCHEMADN_MOD"] = subobj["LDAPMODULE"] + ",paged_searches";
|
||||
subobj["SCHEMADN_MOD2"] = subobj["LDAPMODULE"] + ",paged_searches";
|
||||
}
|
||||
|
||||
if (!provision_validate(subobj, message)) {
|
||||
|
@ -5,9 +5,9 @@ partition: ${DOMAINDN}:${DOMAINDN_LDB}
|
||||
replicateEntries: @SUBCLASSES
|
||||
replicateEntries: @ATTRIBUTES
|
||||
replicateEntries: @INDEXLIST
|
||||
modules:${SCHEMADN}:${SCHEMADN_MOD}
|
||||
modules:${CONFIGDN}:${CONFIGDN_MOD}
|
||||
modules:${DOMAINDN}:${DOMAINDN_MOD}
|
||||
modules:${SCHEMADN}:${SCHEMADN_MOD}${SCHEMADN_MOD2}
|
||||
modules:${CONFIGDN}:${CONFIGDN_MOD}${CONFIGDN_MOD2}
|
||||
modules:${DOMAINDN}:${DOMAINDN_MOD}${DOMAINDN_MOD2}
|
||||
|
||||
dn: @MODULES
|
||||
@LIST: ${MODULES_LIST}
|
||||
|
@ -23,3 +23,21 @@ fSMORoleOwner: CN=NTDS Settings,CN=${NETBIOSNAME},CN=Servers,CN=${DEFAULTSITE},C
|
||||
-
|
||||
replace: objectVersion
|
||||
objectVersion: 30
|
||||
-
|
||||
replace: prefixMap
|
||||
prefixMap:: QkRTRAAAAAAiAAAAAAACACIAAAAAAAAAAgAAAAQAAgABAAAAAgAAAAgAAgACAAAACA
|
||||
AAAAwAAgADAAAACAAAABAAAgAEAAAACAAAABQAAgAFAAAACAAAABgAAgAGAAAACAAAABwAAgAHAAA
|
||||
ACAAAACAAAgAIAAAAAgAAACQAAgAJAAAACAAAACgAAgAKAAAACAAAACwAAgATAAAACAAAADAAAgAU
|
||||
AAAACAAAADQAAgAVAAAACQAAADgAAgAWAAAACQAAADwAAgAXAAAACgAAAEAAAgAYAAAAAgAAAEQAA
|
||||
gAZAAAAAgAAAEgAAgAaAAAAAgAAAEwAAgALAAAACgAAAFAAAgAMAAAACQAAAFQAAgANAAAACgAAAF
|
||||
gAAgAOAAAACQAAAFwAAgAPAAAACgAAAGAAAgAQAAAACQAAAGQAAgARAAAACQAAAGgAAgASAAAACgA
|
||||
AAGwAAgAbAAAACQAAAHAAAgAcAAAACQAAAHQAAgAdAAAACAAAAHgAAgAeAAAACAAAAHwAAgAfAAAA
|
||||
CQAAAIAAAgAgAAAACQAAAIQAAgAhAAAACQAAAIgAAgACAAAAVQQAAAIAAABVBgAACAAAACqGSIb3F
|
||||
AECCAAAACqGSIb3FAEDCAAAAGCGSAFlAgIBCAAAAGCGSAFlAgIDCAAAAGCGSAFlAgEFCAAAAGCGSA
|
||||
FlAgEEAgAAAFUFAAAIAAAAKoZIhvcUAQQIAAAAKoZIhvcUAQUIAAAACZImiZPyLGQIAAAAYIZIAYb
|
||||
4QgMJAAAACZImiZPyLGQBAAAACQAAAGCGSAGG+EIDAQAAAAoAAAAqhkiG9xQBBbZYAAACAAAAVRUA
|
||||
AAIAAABVEgAAAgAAAFUUAAAKAAAAKoZIhvcUAQSCBAAACQAAACqGSIb3FAEFOAAAAAoAAAAqhkiG9
|
||||
xQBBIIGAAAJAAAAKoZIhvcUAQU5AAAACgAAACqGSIb3FAEEggcAAAkAAAAqhkiG9xQBBToAAAAJAA
|
||||
AAKoZIhvcUAQVJAAAACgAAACqGSIb3FAEEgjEAAAkAAAArBgEEAYs6ZXcAAAAJAAAAYIZIAYb4QgM
|
||||
CAAAACAAAACsGAQQBgXoBCAAAACqGSIb3DQEJCQAAAAmSJomT8ixkBAAAAAkAAAArBgEEAbd9BAEA
|
||||
AAAJAAAAKwYBBAG3fQQC
|
||||
|
@ -25,7 +25,7 @@ if (options.ARGV.length != 1) {
|
||||
|
||||
var host = options.ARGV[0];
|
||||
|
||||
function basic_tests(ldb, gc_ldb, base_dn, configuration_dn)
|
||||
function basic_tests(ldb, gc_ldb, base_dn, configuration_dn, schema_dn)
|
||||
{
|
||||
println("Running basic tests");
|
||||
|
||||
@ -473,6 +473,33 @@ objectClass: user
|
||||
assert(res.error == 0);
|
||||
assert (res.msgs.length > 0);
|
||||
|
||||
println("Testing objectCategory canonacolisation");
|
||||
var attrs = new Array("cn");
|
||||
var res = ldb.search("objectCategory=ntDsDSA", configuration_dn, ldb.SCOPE_SUBTREE, attrs);
|
||||
assert(res.error == 0);
|
||||
if (res.msgs.length == 0) {
|
||||
println("Didn't find any records with objectCategory=ntDsDSA");
|
||||
}
|
||||
assert(res.msgs.length != 0);
|
||||
|
||||
var attrs = new Array("cn");
|
||||
var res = ldb.search("objectCategory=CN=ntDs-DSA," + schema_dn, configuration_dn, ldb.SCOPE_SUBTREE, attrs);
|
||||
assert(res.error == 0);
|
||||
if (res.msgs.length == 0) {
|
||||
println("Didn't find any records with objectCategory=CN=ntDs-DSA," + schema_dn);
|
||||
}
|
||||
assert(res.msgs.length != 0);
|
||||
|
||||
println("Testing objectClass attribute order on "+ base_dn);
|
||||
var attrs = new Array("objectclass");
|
||||
var res = ldb.search("objectClass=domain", base_dn, ldb.SCOPE_BASE, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
|
||||
assert(res.msgs[0].objectClass[0] == "top");
|
||||
assert(res.msgs[0].objectClass[1] == "domain");
|
||||
assert(res.msgs[0].objectClass[2] == "domainDNS");
|
||||
|
||||
}
|
||||
|
||||
function basedn_tests(ldb, gc_ldb)
|
||||
@ -522,6 +549,15 @@ function find_configurationdn(ldb)
|
||||
return res.msgs[0].configurationNamingContext;
|
||||
}
|
||||
|
||||
function find_schemadn(ldb)
|
||||
{
|
||||
var attrs = new Array("schemaNamingContext");
|
||||
var res = ldb.search("", "", ldb.SCOPE_BASE, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
return res.msgs[0].schemaNamingContext;
|
||||
}
|
||||
|
||||
/* use command line creds if available */
|
||||
ldb.credentials = options.get_credentials();
|
||||
gc_ldb.credentials = options.get_credentials();
|
||||
@ -529,6 +565,7 @@ gc_ldb.credentials = options.get_credentials();
|
||||
var ok = ldb.connect("ldap://" + host);
|
||||
var base_dn = find_basedn(ldb);
|
||||
var configuration_dn = find_configurationdn(ldb);
|
||||
var schema_dn = find_schemadn(ldb);
|
||||
|
||||
printf("baseDN: %s\n", base_dn);
|
||||
|
||||
@ -537,7 +574,7 @@ if (!ok) {
|
||||
gc_ldb = undefined;
|
||||
}
|
||||
|
||||
basic_tests(ldb, gc_ldb, base_dn, configuration_dn)
|
||||
basic_tests(ldb, gc_ldb, base_dn, configuration_dn, schema_dn)
|
||||
|
||||
basedn_tests(ldb, gc_ldb)
|
||||
|
||||
|
@ -270,7 +270,7 @@ objectClass: user
|
||||
cn: X
|
||||
codePage: x
|
||||
revision: x
|
||||
objectCategory: x
|
||||
dnsHostName: x
|
||||
nextRid: y
|
||||
lastLogon: x
|
||||
description: x
|
||||
@ -282,7 +282,7 @@ objectClass: top
|
||||
cn: Y
|
||||
codePage: x
|
||||
revision: x
|
||||
objectCategory: y
|
||||
dnsHostName: y
|
||||
nextRid: y
|
||||
lastLogon: y
|
||||
description: x
|
||||
@ -292,7 +292,7 @@ objectClass: top
|
||||
cn: Z
|
||||
codePage: x
|
||||
revision: y
|
||||
objectCategory: z
|
||||
dnsHostName: z
|
||||
nextRid: y
|
||||
lastLogon: z
|
||||
description: y
|
||||
@ -342,86 +342,86 @@ description: y
|
||||
|
||||
/* Search remote record by local DN */
|
||||
dn = s4.dn("cn=A");
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
assert(res.msgs[0].dn == dn);
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
|
||||
/* Search remote record by remote DN */
|
||||
dn = s3.dn("cn=A");
|
||||
attrs = new Array("objectCategory", "lastLogon", "sambaLogonTime");
|
||||
attrs = new Array("dnsHostName", "lastLogon", "sambaLogonTime");
|
||||
res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
assert(res.msgs[0].dn == dn);
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == undefined);
|
||||
assert(res.msgs[0].sambaLogonTime == "x");
|
||||
|
||||
/* Search split record by local DN */
|
||||
dn = s4.dn("cn=X");
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
assert(res.msgs[0].dn == dn);
|
||||
assert(res.msgs[0].objectCategory == "x");
|
||||
assert(res.msgs[0].dnsHostName == "x");
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
|
||||
/* Search split record by remote DN */
|
||||
dn = s3.dn("cn=X");
|
||||
attrs = new Array("objectCategory", "lastLogon", "sambaLogonTime");
|
||||
attrs = new Array("dnsHostName", "lastLogon", "sambaLogonTime");
|
||||
res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
assert(res.msgs[0].dn == dn);
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == undefined);
|
||||
assert(res.msgs[0].sambaLogonTime == "x");
|
||||
|
||||
println("Testing search by attribute");
|
||||
|
||||
/* Search by ignored attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(revision=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
|
||||
/* Search by kept attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(description=y)", NULL, ldb. SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[0].objectCategory == "z");
|
||||
assert(res.msgs[0].dnsHostName == "z");
|
||||
assert(res.msgs[0].lastLogon == "z");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "z");
|
||||
|
||||
/* Search by renamed attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(badPwdCount=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
|
||||
/* Search by converted attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon", "objectSid");
|
||||
attrs = new Array("dnsHostName", "lastLogon", "objectSid");
|
||||
/* TODO:
|
||||
Using the SID directly in the parse tree leads to conversion
|
||||
errors, letting the search fail with no results.
|
||||
@ -431,23 +431,23 @@ description: y
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[0].objectCategory == "x");
|
||||
assert(res.msgs[0].dnsHostName == "x");
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
assert(res.msgs[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[1].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
|
||||
|
||||
/* Search by generated attribute */
|
||||
/* 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");
|
||||
attrs = new Array("dnsHostName", "lastLogon", "primaryGroupID");
|
||||
res = ldb.search("(primaryGroupID=512)", NULL, ldb. SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 1);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
assert(res.msgs[0].primaryGroupID == "512");
|
||||
|
||||
@ -468,23 +468,23 @@ description: y
|
||||
*/
|
||||
|
||||
/* Search by remote name of renamed attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(sambaBadPasswordCount=*)", "", ldb. SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 0);
|
||||
|
||||
/* Search by objectClass */
|
||||
attrs = new Array("objectCategory", "lastLogon", "objectClass");
|
||||
attrs = new Array("dnsHostName", "lastLogon", "objectClass");
|
||||
res = ldb.search("(objectClass=user)", NULL, ldb. SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[0].objectCategory == "x");
|
||||
assert(res.msgs[0].dnsHostName == "x");
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
assert(res.msgs[0].objectClass != undefined);
|
||||
assert(res.msgs[0].objectClass[3] == "user");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[1].objectClass != undefined);
|
||||
assert(res.msgs[1].objectClass[0] == "user");
|
||||
@ -494,19 +494,19 @@ description: y
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 3);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[0].objectClass != undefined);
|
||||
for (i=0;i<res.msgs[0].objectClass.length;i++) {
|
||||
assert(res.msgs[0].objectClass[i] != "user");
|
||||
}
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[1].objectClass != undefined);
|
||||
assert(res.msgs[1].objectClass[3] == "user");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[2].objectCategory == undefined);
|
||||
assert(res.msgs[2].dnsHostName == undefined);
|
||||
assert(res.msgs[2].lastLogon == "x");
|
||||
assert(res.msgs[2].objectClass != undefined);
|
||||
assert(res.msgs[2].objectClass[0] == "user");
|
||||
@ -514,43 +514,43 @@ description: y
|
||||
println("Testing search by parse tree");
|
||||
|
||||
/* Search by conjunction of local attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(&(codePage=x)(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
|
||||
/* Search by conjunction of remote attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(&(lastLogon=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[0].objectCategory == "x");
|
||||
assert(res.msgs[0].dnsHostName == "x");
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
|
||||
/* Search by conjunction of local and remote attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(&(codePage=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
|
||||
/* Search by conjunction of local and remote attribute w/o match */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(&(codePage=x)(nextRid=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 0);
|
||||
@ -559,203 +559,203 @@ description: y
|
||||
assert(res.msgs.length == 0);
|
||||
|
||||
/* Search by disjunction of local attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
res = ldb.search("(|(revision=x)(objectCategory=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(|(revision=x)(dnsHostName=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
|
||||
/* Search by disjunction of remote attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(|(badPwdCount=x)(lastLogon=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 3);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[2].objectCategory == undefined);
|
||||
assert(res.msgs[2].dnsHostName == undefined);
|
||||
assert(res.msgs[2].lastLogon == "x");
|
||||
|
||||
/* Search by disjunction of local and remote attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(|(revision=x)(lastLogon=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 3);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "y");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[2].objectCategory == "x");
|
||||
assert(res.msgs[2].dnsHostName == "x");
|
||||
assert(res.msgs[2].lastLogon == "x");
|
||||
|
||||
/* Search by disjunction of local and remote attribute w/o match */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(|(codePage=y)(nextRid=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 0);
|
||||
|
||||
/* Search by negated local attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 4);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[2].objectCategory == "z");
|
||||
assert(res.msgs[2].dnsHostName == "z");
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
assert(res.msgs[3].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[3].objectCategory == undefined);
|
||||
assert(res.msgs[3].dnsHostName == undefined);
|
||||
assert(res.msgs[3].lastLogon == "z");
|
||||
|
||||
/* Search by negated remote attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 2);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[0].objectCategory == "z");
|
||||
assert(res.msgs[0].dnsHostName == "z");
|
||||
assert(res.msgs[0].lastLogon == "z");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "z");
|
||||
|
||||
/* Search by negated conjunction of local attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(&(codePage=x)(revision=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 4);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[2].objectCategory == "z");
|
||||
assert(res.msgs[2].dnsHostName == "z");
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
assert(res.msgs[3].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[3].objectCategory == undefined);
|
||||
assert(res.msgs[3].dnsHostName == undefined);
|
||||
assert(res.msgs[3].lastLogon == "z");
|
||||
|
||||
/* Search by negated conjunction of remote attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(&(lastLogon=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 4);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "y");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[2].objectCategory == "z");
|
||||
assert(res.msgs[2].dnsHostName == "z");
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
assert(res.msgs[3].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[3].objectCategory == undefined);
|
||||
assert(res.msgs[3].dnsHostName == undefined);
|
||||
assert(res.msgs[3].lastLogon == "z");
|
||||
|
||||
/* Search by negated conjunction of local and remote attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(&(codePage=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 4);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[2].objectCategory == "z");
|
||||
assert(res.msgs[2].dnsHostName == "z");
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
assert(res.msgs[3].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[3].objectCategory == undefined);
|
||||
assert(res.msgs[3].dnsHostName == undefined);
|
||||
assert(res.msgs[3].lastLogon == "z");
|
||||
|
||||
/* Search by negated disjunction of local attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
res = ldb.search("(!(|(revision=x)(objectCategory=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(|(revision=x)(dnsHostName=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[1].objectCategory == undefined);
|
||||
assert(res.msgs[1].dnsHostName == undefined);
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[2].objectCategory == "z");
|
||||
assert(res.msgs[2].dnsHostName == "z");
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
assert(res.msgs[3].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[3].objectCategory == undefined);
|
||||
assert(res.msgs[3].dnsHostName == undefined);
|
||||
assert(res.msgs[3].lastLogon == "z");
|
||||
|
||||
/* Search by negated disjunction of remote attributes */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(|(badPwdCount=x)(lastLogon=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 3);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=Y"));
|
||||
assert(res.msgs[0].objectCategory == "y");
|
||||
assert(res.msgs[0].dnsHostName == "y");
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[1].objectCategory == "z");
|
||||
assert(res.msgs[1].dnsHostName == "z");
|
||||
assert(res.msgs[1].lastLogon == "z");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[2].objectCategory == undefined);
|
||||
assert(res.msgs[2].dnsHostName == undefined);
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
|
||||
/* Search by negated disjunction of local and remote attribute */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(!(|(revision=x)(lastLogon=y)))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 3);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "x");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[1].objectCategory == "z");
|
||||
assert(res.msgs[1].dnsHostName == "z");
|
||||
assert(res.msgs[1].lastLogon == "z");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[2].objectCategory == undefined);
|
||||
assert(res.msgs[2].dnsHostName == undefined);
|
||||
assert(res.msgs[2].lastLogon == "z");
|
||||
|
||||
/* Search by complex parse tree */
|
||||
attrs = new Array("objectCategory", "lastLogon");
|
||||
res = ldb.search("(|(&(revision=x)(objectCategory=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
attrs = new Array("dnsHostName", "lastLogon");
|
||||
res = ldb.search("(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
|
||||
assert(res.error == 0);
|
||||
assert(res.msgs.length == 5);
|
||||
assert(res.msgs[0].dn == s4.dn("cn=B"));
|
||||
assert(res.msgs[0].objectCategory == undefined);
|
||||
assert(res.msgs[0].dnsHostName == undefined);
|
||||
assert(res.msgs[0].lastLogon == "y");
|
||||
assert(res.msgs[1].dn == s4.dn("cn=X"));
|
||||
assert(res.msgs[1].objectCategory == "x");
|
||||
assert(res.msgs[1].dnsHostName == "x");
|
||||
assert(res.msgs[1].lastLogon == "x");
|
||||
assert(res.msgs[2].dn == s4.dn("cn=A"));
|
||||
assert(res.msgs[2].objectCategory == undefined);
|
||||
assert(res.msgs[2].dnsHostName == undefined);
|
||||
assert(res.msgs[2].lastLogon == "x");
|
||||
assert(res.msgs[3].dn == s4.dn("cn=Z"));
|
||||
assert(res.msgs[3].objectCategory == "z");
|
||||
assert(res.msgs[3].dnsHostName == "z");
|
||||
assert(res.msgs[3].lastLogon == "z");
|
||||
assert(res.msgs[4].dn == s4.dn("cn=C"));
|
||||
assert(res.msgs[4].objectCategory == undefined);
|
||||
assert(res.msgs[4].dnsHostName == undefined);
|
||||
assert(res.msgs[4].lastLogon == "z");
|
||||
|
||||
/* Clean up */
|
||||
|
Loading…
Reference in New Issue
Block a user