summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-07-02 15:15:54 +1000
committerAndrew Bartlett <abartlet@samba.org>2008-07-02 15:15:54 +1000
commitd7bd297df71ca718124a3407916485de55500933 (patch)
treedb02936970679b8b094b6d92b6262dc513c34a2b
parent2a918a353f3d0e5dc64ac89ad3e32a564aa094c9 (diff)
downloadsamba-d7bd297df71ca718124a3407916485de55500933.tar.gz
samba-d7bd297df71ca718124a3407916485de55500933.tar.bz2
samba-d7bd297df71ca718124a3407916485de55500933.zip
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)
-rw-r--r--source4/lib/ldb/tools/ad2oLschema.c110
1 files changed, 106 insertions, 4 deletions
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, \
" $"); \
}