From 49b335c756d22d7f6acfa32a07fa291e04b49a87 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Aug 2006 06:14:21 +0000 Subject: r17600: Finish the schema conversion tool, and add a mapping file, used to map OIDs and skip built-in attributes. Andrew Bartlett (This used to be commit cb2b9d800d1228d41f7872a7b7c8ea5f07816c61) --- source4/lib/ldb/tools/ad2oLschema.c | 201 ++++++++++++++++++++++++---------- source4/lib/ldb/tools/convert.c | 2 +- source4/setup/provision_init.ldif | 2 + source4/setup/schema-map-openldap-2.3 | 31 ++++++ source4/setup/schema.ldif | 26 ++--- source4/setup/schema_samba4.ldif | 14 --- 6 files changed, 191 insertions(+), 85 deletions(-) create mode 100644 source4/setup/schema-map-openldap-2.3 diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c index 75b03dd3b0..fba2966a2e 100644 --- a/source4/lib/ldb/tools/ad2oLschema.c +++ b/source4/lib/ldb/tools/ad2oLschema.c @@ -105,6 +105,11 @@ static const char *oc_attrs[] = { "governsID", "description", "subClassOf", + "objectClassCategory", + "mustContain", + "systemMustContain", + "mayContain", + "systemMayContain", NULL }; @@ -229,6 +234,14 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct return schemadn; } +#define IF_NULL_FAIL_RET(x) do { \ + if (!x) { \ + ret.failures++; \ + return ret; \ + } \ + } while (0) + + static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_target target, FILE *in, FILE *out) { /* Read list of attributes to skip, OIDs to map */ @@ -242,6 +255,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ } *oid_map = NULL; int num_maps = 0; struct ldb_result *attrs_res, *objectclasses_res; + struct ldb_message *msg; struct ldb_dn *schemadn; struct schema_conv ret; @@ -252,24 +266,36 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ ret.failures = 0; while ((line = afdgets(fileno(in), mem_ctx, 0))) { - if (!*line) { - break; + /* Blank Line */ + if (line[0] == '\0') { + continue; + } + /* Comment */ + if (line[0] == '#') { + continue; } - if (isdigit(*line)) { + if (isdigit(line[0])) { char *p = strchr(line, ':'); + IF_NULL_FAIL_RET(p); if (!p) { ret.failures = 1; return ret; } + p[0] = '\0'; p++; oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_maps + 2); + trim_string(line, " ", " "); oid_map[num_maps].old_oid = talloc_steal(oid_map, line); + trim_string(p, " ", " "); oid_map[num_maps].new_oid = p; num_maps++; oid_map[num_maps].old_oid = NULL; } else { attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2); + trim_string(line, " ", " "); attrs_skip[num_skip] = talloc_steal(attrs_skip, line); + num_skip++; + attrs_skip[num_skip] = NULL; } } @@ -288,17 +314,19 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ } for (i=0; i < attrs_res->count; i++) { - const char *name = ldb_msg_find_attr_as_string(attrs_res->msgs[i], "lDAPDisplayName", NULL); - const char *description = ldb_msg_find_attr_as_string(attrs_res->msgs[i], "description", NULL); - const char *oid = ldb_msg_find_attr_as_string(attrs_res->msgs[i], "attributeID", NULL); - const char *syntax = ldb_msg_find_attr_as_string(attrs_res->msgs[i], "attributeSyntax", NULL); - BOOL single_value = ldb_msg_find_attr_as_bool(attrs_res->msgs[i], "isSingleValued", False); + msg = attrs_res->msgs[i]; + + const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL); + const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL); + const char *oid = ldb_msg_find_attr_as_string(msg, "attributeID", NULL); + const char *syntax = ldb_msg_find_attr_as_string(msg, "attributeSyntax", NULL); + BOOL single_value = ldb_msg_find_attr_as_bool(msg, "isSingleValued", False); const struct syntax_map *map = find_syntax_map_by_ad_oid(syntax); char *schema_entry = NULL; int j; /* We have been asked to skip some attributes/objectClasses */ - if (in_list(attrs_skip, name, False)) { + if (str_list_check_ci(attrs_skip, name)) { ret.skipped++; continue; } @@ -323,61 +351,49 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ " %s\n", oid); break; } - if (!schema_entry) { - ret.failures++; - break; - } + IF_NULL_FAIL_RET(schema_entry); schema_entry = talloc_asprintf_append(schema_entry, " NAME '%s'\n", name); - if (!schema_entry) { - ret.failures++; - return ret; - } - - if (!schema_entry) return ret; + IF_NULL_FAIL_RET(schema_entry); if (description) { schema_entry = talloc_asprintf_append(schema_entry, " DESC %s\n", description); - if (!schema_entry) { - ret.failures++; - return ret; - } + IF_NULL_FAIL_RET(schema_entry); } if (map) { + const char *syntax_oid; if (map->equality) { schema_entry = talloc_asprintf_append(schema_entry, " EQUALITY %s\n", map->equality); - if (!schema_entry) { - ret.failures++; - return ret; - } + IF_NULL_FAIL_RET(schema_entry); } if (map->substring) { schema_entry = talloc_asprintf_append(schema_entry, - " SUBSTRING %s\n", map->substring); - if (!schema_entry) { - ret.failures++; - return ret; + " SUBSTR %s\n", map->substring); + IF_NULL_FAIL_RET(schema_entry); + } + syntax_oid = map->Standard_OID; + /* We might have been asked to remap this oid, + * due to a conflict, or lack of + * implementation */ + for (j=0; syntax_oid && oid_map[j].old_oid; j++) { + if (strcmp(syntax_oid, oid_map[j].old_oid) == 0) { + syntax_oid = oid_map[j].new_oid; + break; } } schema_entry = talloc_asprintf_append(schema_entry, - " SYNTAX %s\n", map->Standard_OID); - if (!schema_entry) { - ret.failures++; - return ret; - } + " SYNTAX %s\n", syntax_oid); + IF_NULL_FAIL_RET(schema_entry); } if (single_value) { schema_entry = talloc_asprintf_append(schema_entry, " SINGLE-VALUE\n"); - if (!schema_entry) { - ret.failures++; - return ret; - } + IF_NULL_FAIL_RET(schema_entry); } schema_entry = talloc_asprintf_append(schema_entry, @@ -394,15 +410,21 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ } for (i=0; i < objectclasses_res->count; i++) { - const char *name = ldb_msg_find_attr_as_string(objectclasses_res->msgs[i], "lDAPDisplayName", NULL); - const char *description = ldb_msg_find_attr_as_string(objectclasses_res->msgs[i], "description", NULL); - const char *oid = ldb_msg_find_attr_as_string(objectclasses_res->msgs[i], "governsID", NULL); - const char *subClassOf = ldb_msg_find_attr_as_string(objectclasses_res->msgs[i], "subClassOf", NULL); + msg = objectclasses_res->msgs[i]; + const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL); + const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL); + const char *oid = ldb_msg_find_attr_as_string(msg, "governsID", NULL); + const char *subClassOf = ldb_msg_find_attr_as_string(msg, "subClassOf", NULL); + int objectClassCategory = ldb_msg_find_attr_as_int(msg, "objectClassCategory", 0); + struct ldb_message_element *must = ldb_msg_find_element(msg, "mustContain"); + 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"); char *schema_entry = NULL; int j; /* We have been asked to skip some attributes/objectClasses */ - if (in_list(attrs_skip, name, False)) { + if (str_list_check_ci(attrs_skip, name)) { ret.skipped++; continue; } @@ -418,7 +440,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ switch (target) { case TARGET_OPENLDAP: schema_entry = talloc_asprintf(mem_ctx, - "objectClass (\n" + "objectclass (\n" " %s\n", oid); break; case TARGET_FEDORA_DS: @@ -427,6 +449,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ " %s\n", oid); break; } + IF_NULL_FAIL_RET(schema_entry); if (!schema_entry) { ret.failures++; break; @@ -434,29 +457,93 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ schema_entry = talloc_asprintf_append(schema_entry, " NAME '%s'\n", name); - if (!schema_entry) { - ret.failures++; - return ret; - } + IF_NULL_FAIL_RET(schema_entry); if (!schema_entry) return ret; if (description) { schema_entry = talloc_asprintf_append(schema_entry, " DESC %s\n", description); - if (!schema_entry) { - ret.failures++; - return ret; - } + IF_NULL_FAIL_RET(schema_entry); } if (subClassOf) { schema_entry = talloc_asprintf_append(schema_entry, " SUP %s\n", subClassOf); - if (!schema_entry) { - ret.failures++; - return ret; + IF_NULL_FAIL_RET(schema_entry); + } + + switch (objectClassCategory) { + case 1: + schema_entry = talloc_asprintf_append(schema_entry, + " STRUCTURAL\n"); + IF_NULL_FAIL_RET(schema_entry); + break; + case 2: + schema_entry = talloc_asprintf_append(schema_entry, + " ABSTRACT\n"); + IF_NULL_FAIL_RET(schema_entry); + break; + case 3: + schema_entry = talloc_asprintf_append(schema_entry, + " AUXILIARY\n"); + IF_NULL_FAIL_RET(schema_entry); + break; + } + +#define APPEND_ATTRS(attributes) \ + do { \ + int k; \ + for (k=0; attributes && k < attributes->num_values; k++) { \ + schema_entry = talloc_asprintf_append(schema_entry, \ + " %s", \ + (const char *)attributes->values[k].data); \ + IF_NULL_FAIL_RET(schema_entry); \ + if (k != (attributes->num_values - 1)) { \ + schema_entry = talloc_asprintf_append(schema_entry, \ + " $"); \ + IF_NULL_FAIL_RET(schema_entry); \ + if ((k+1)%5 == 0) { \ + schema_entry = talloc_asprintf_append(schema_entry, \ + "\n "); \ + IF_NULL_FAIL_RET(schema_entry); \ + } \ + } \ + } \ + } while (0) + + if (must || sys_must) { + schema_entry = talloc_asprintf_append(schema_entry, + " MUST ("); + IF_NULL_FAIL_RET(schema_entry); + + APPEND_ATTRS(must); + if (must && sys_must) { + schema_entry = talloc_asprintf_append(schema_entry, \ + " $"); \ } + APPEND_ATTRS(sys_must); + + schema_entry = talloc_asprintf_append(schema_entry, + ")\n"); + IF_NULL_FAIL_RET(schema_entry); + } + + if (may || sys_may) { + schema_entry = talloc_asprintf_append(schema_entry, + " MAY ("); + IF_NULL_FAIL_RET(schema_entry); + + APPEND_ATTRS(may); + if (may && sys_may) { + schema_entry = talloc_asprintf_append(schema_entry, \ + " $"); \ + } + APPEND_ATTRS(sys_may); + + schema_entry = talloc_asprintf_append(schema_entry, + " )\n"); + IF_NULL_FAIL_RET(schema_entry); } schema_entry = talloc_asprintf_append(schema_entry, diff --git a/source4/lib/ldb/tools/convert.c b/source4/lib/ldb/tools/convert.c index 222bb3cfd0..35f56f51d3 100644 --- a/source4/lib/ldb/tools/convert.c +++ b/source4/lib/ldb/tools/convert.c @@ -48,7 +48,7 @@ static const struct syntax_map syntax_map[] = { .comment = "Case Insensitive String" }, { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.44", + .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.26", .AD_OID = "2.5.5.5", .equality = "caseExactIA5Match", .comment = "Printable String" diff --git a/source4/setup/provision_init.ldif b/source4/setup/provision_init.ldif index 7414368d44..914184a35b 100644 --- a/source4/setup/provision_init.ldif +++ b/source4/setup/provision_init.ldif @@ -10,6 +10,8 @@ dn: @INDEXLIST @IDXATTR: unixName @IDXATTR: privilege @IDXATTR: nCName +@IDXATTR: lDAPDisplayName +@IDXATTR: subClassOf dn: @ATTRIBUTES userPrincipalName: CASE_INSENSITIVE diff --git a/source4/setup/schema-map-openldap-2.3 b/source4/setup/schema-map-openldap-2.3 new file mode 100644 index 0000000000..f270b983c5 --- /dev/null +++ b/source4/setup/schema-map-openldap-2.3 @@ -0,0 +1,31 @@ +#Standard OpenLDAP attributes +name +labeledURI +objectClasses +createTimeStamp +attributeTypes +objectClass +userPassword +seeAlso +uid +subSchemaSubEntry +structuralObjectClass +modifyTimeStamp +distinguishedName +description +cn +dITContentRules +top +#Skip ObjectClasses +subSchema +# +#MiddleName has a conflicting OID +2.16.840.1.113730.3.1.34:1.3.6.1.4.1.7165.4.1.8 +#This large integer format is unimplemented in OpenLDAP 2.3 +1.2.840.113556.1.4.906:1.3.6.1.4.1.1466.115.121.1.27 +#This case insensitive string isn't available +1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.44 +#This type of DN isn't in OpenLDAP +1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.12 +#Treat Security Descriptors as binary +1.2.840.113556.1.4.907:1.3.6.1.4.1.1466.115.121.1.40 \ No newline at end of file diff --git a/source4/setup/schema.ldif b/source4/setup/schema.ldif index f4d31a5ed0..6f8f62d080 100644 --- a/source4/setup/schema.ldif +++ b/source4/setup/schema.ldif @@ -568,19 +568,19 @@ adminDisplayName: houseIdentifier attributeID: 2.5.4.51 attributeSyntax: 2.5.5.12 -#dn: CN=middleName,CN=Schema,CN=Configuration,${BASEDN} -#cn: middleName -#name: middleName -#objectClass: top -#objectClass: attributeSchema -#lDAPDisplayName: middleName -#isSingleValued: TRUE -#systemFlags: 16 -#systemOnly: FALSE -#schemaIDGUID: bf9679f2-0de6-11d0-a285-00aa003049e2 -#adminDisplayName: Other-Name -#attributeID: 2.16.840.1.113730.3.1.34 -#attributeSyntax: 2.5.5.12 +dn: CN=middleName,CN=Schema,CN=Configuration,${BASEDN} +cn: middleName +name: middleName +objectClass: top +objectClass: attributeSchema +lDAPDisplayName: middleName +isSingleValued: TRUE +systemFlags: 16 +systemOnly: FALSE +schemaIDGUID: bf9679f2-0de6-11d0-a285-00aa003049e2 +adminDisplayName: Other-Name +attributeID: 2.16.840.1.113730.3.1.34 +attributeSyntax: 2.5.5.12 dn: CN=replTopologyStayOfExecution,CN=Schema,CN=Configuration,${BASEDN} cn: replTopologyStayOfExecution diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif index 94b79bd31f..61af0936dc 100644 --- a/source4/setup/schema_samba4.ldif +++ b/source4/setup/schema_samba4.ldif @@ -106,20 +106,6 @@ adminDisplayName: Privilege attributeID: 1.3.6.1.4.1.7165.4.1.7 attributeSyntax: 2.5.5.4 -dn: CN=middleName,CN=Schema,CN=Configuration,${BASEDN} -cn: middleName -name: middleName -objectClass: top -objectClass: attributeSchema -lDAPDisplayName: middleName -sSingleValued: TRUE -systemFlags: 16 -systemOnly: FALSE -schemaIDGUID: bf9679f2-0de6-11d0-a285-00aa003049e2 -adminDisplayName: Other-Name -attributeID: 1.3.6.1.4.1.7165.4.1.8 -attributeSyntax: 2.5.5.12 - dn: CN=unixName,CN=Schema,CN=Configuration,${BASEDN} cn: unixName name: unixName -- cgit