From: Andrew Bartlett Date: Wed, 2 Jul 2008 05:15:54 +0000 (+1000) Subject: Collapse auxillary classes in LDAP schema conversion. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d674e92591ea90eb3b2117d8dd21f79f718d7730;p=thirdparty%2Fsamba.git 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 --- diff --git a/source/lib/ldb/tools/ad2oLschema.c b/source/lib/ldb/tools/ad2oLschema.c index ac343c783fe..df6fc91688d 100644 --- a/source/lib/ldb/tools/ad2oLschema.c +++ b/source/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, \ " $"); \ }