From d7bd297df71ca718124a3407916485de55500933 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Jul 2008 15:15:54 +1000 Subject: Collapse auxillary classes in LDAP schema conversion. MS-ADTS 3.1.1.3.1.1.5 describes the behaviour of auxiliary classes. In effect, these are additional MUST or MAY attributes that are appeneded to the parent class (the auxiliary does not become listed in the objectClass attribute), and so we do just that, and merge them here, for export to OpenLDAP as it's schema. Andrew Bartlett (This used to be commit d674e92591ea90eb3b2117d8dd21f79f718d7730) --- source4/lib/ldb/tools/ad2oLschema.c | 110 ++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) (limited to 'source4/lib/ldb') diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c index ac343c783f..df6fc91688 100644 --- a/source4/lib/ldb/tools/ad2oLschema.c +++ b/source4/lib/ldb/tools/ad2oLschema.c @@ -107,6 +107,8 @@ static const char *oc_attrs[] = { "governsID", "description", "subClassOf", + "systemAuxiliaryClass", + "auxiliaryClass", NULL }; @@ -247,6 +249,78 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct return schemadn; } +static bool merge_attr_list(TALLOC_CTX *mem_ctx, + struct ldb_message_element *attrs, struct ldb_message_element *new_attrs) +{ + struct ldb_val *values; + if (!new_attrs) { + return true; + } + + values = talloc_realloc(mem_ctx, + attrs->values, struct ldb_val, attrs->num_values + new_attrs->num_values); + + attrs->values = values; + + memcpy(&attrs->values[attrs->num_values], new_attrs->values, sizeof(*new_attrs->values) * new_attrs->num_values); + attrs->num_values = attrs->num_values + new_attrs->num_values; + + /* Add sort and unique implementation here */ + + return true; +} + +static bool find_aux_classes(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_dn *schema_dn, + struct ldb_message_element *aux_class, struct ldb_message_element *must, + struct ldb_message_element *sys_must, struct ldb_message_element *may, + struct ldb_message_element *sys_may) +{ + int i, ret; + struct ldb_message *msg; + struct ldb_result *res; + + for (i=0; aux_class && i < aux_class->num_values; i++) { + ret = ldb_search_exp_fmt(ldb, mem_ctx, &res, + schema_dn, LDB_SCOPE_SUBTREE, oc_attrs, + "(&(objectClass=classSchema)(lDAPDisplayName=%s))", + aux_class->values[i].data); + if (ret != LDB_SUCCESS) { + return false; + } + + msg = res->msgs[0]; + + if (!merge_attr_list(mem_ctx, must, ldb_msg_find_element(msg, "mustContain"))) { + return false; + } + if (!merge_attr_list(mem_ctx, sys_must, ldb_msg_find_element(msg, "systemMustContain"))) { + return false; + } + if (!merge_attr_list(mem_ctx, may, ldb_msg_find_element(msg, "mayContain"))) { + return false; + } + if (!merge_attr_list(mem_ctx, sys_may, ldb_msg_find_element(msg, "systemMayContain"))) { + return false; + } + + + if (res->count == 0) { + return false; + } + + if (!find_aux_classes(mem_ctx, ldb, schema_dn, + ldb_msg_find_element(msg, "auxiliaryClass"), must, sys_must, may, sys_may)) { + return false; + } + if (!find_aux_classes(mem_ctx, ldb, schema_dn, + ldb_msg_find_element(msg, "systemAuxiliaryClass"), must, sys_must, may, sys_may)) { + return false; + } + } + return true; +} + + #define IF_NULL_FAIL_RET(x) do { \ if (!x) { \ ret.failures++; \ @@ -478,6 +552,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ struct ldb_message_element *sys_must = ldb_msg_find_element(msg, "systemMustContain"); struct ldb_message_element *may = ldb_msg_find_element(msg, "mayContain"); struct ldb_message_element *sys_may = ldb_msg_find_element(msg, "systemMayContain"); + struct ldb_message_element *aux_class = ldb_msg_find_element(msg, "auxiliaryClass"); + struct ldb_message_element *sys_aux_class = ldb_msg_find_element(msg, "systemAuxiliaryClass"); char *schema_entry = NULL; int j; @@ -493,6 +569,32 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ continue; } + if (must == NULL) { + must = talloc_zero(mem_ctx, struct ldb_message_element); + } + + if (may == NULL) { + may = talloc_zero(mem_ctx, struct ldb_message_element); + } + + if (sys_must == NULL) { + sys_must = talloc_zero(mem_ctx, struct ldb_message_element); + } + + if (sys_may == NULL) { + sys_may = talloc_zero(mem_ctx, struct ldb_message_element); + } + + if (!find_aux_classes(mem_ctx, ldb, schemadn, aux_class, must, sys_must, may, sys_may)) { + ret.failures++; + continue; + } + + if (!find_aux_classes(mem_ctx, ldb, schemadn, sys_aux_class, must, sys_must, may, sys_may)) { + ret.failures++; + continue; + } + /* We might have been asked to remap this oid, due to a conflict */ for (j=0; oid_map && oid_map[j].old_oid; j++) { if (strcasecmp(oid, oid_map[j].old_oid) == 0) { @@ -594,13 +696,13 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ } \ } while (0) - if (must || sys_must) { + if ((must && must->values) || (sys_must && sys_must->values)) { schema_entry = talloc_asprintf_append(schema_entry, " MUST ("); IF_NULL_FAIL_RET(schema_entry); APPEND_ATTRS(must); - if (must && sys_must) { + if (must && must->values && sys_must && sys_must->values) { schema_entry = talloc_asprintf_append(schema_entry, \ " $"); \ } @@ -611,13 +713,13 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ IF_NULL_FAIL_RET(schema_entry); } - if (may || sys_may) { + if ((may && may->values) || (sys_may && sys_may->values)) { schema_entry = talloc_asprintf_append(schema_entry, " MAY ("); IF_NULL_FAIL_RET(schema_entry); APPEND_ATTRS(may); - if (may && sys_may) { + if (may && may->values && sys_may && sys_may->values) { schema_entry = talloc_asprintf_append(schema_entry, \ " $"); \ } -- cgit