summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-03-06 12:12:24 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-03-06 12:12:24 +1100
commit8374d6f0dc1d6ce6c554b10b5133bd77c5ad6292 (patch)
tree15ecd6252cb446acbf4ba12b07c445d324997124 /source4/dsdb
parent8352650fee1233e68b489efe635f3661cab2b190 (diff)
downloadsamba-8374d6f0dc1d6ce6c554b10b5133bd77c5ad6292.tar.gz
samba-8374d6f0dc1d6ce6c554b10b5133bd77c5ad6292.tar.bz2
samba-8374d6f0dc1d6ce6c554b10b5133bd77c5ad6292.zip
Sort output of schema for OpenLDAP during conversion
This avoids the need to assume that the schema is sorted on load, which happens more often and is a major performace issue in the Samba4's use of ldb. Andrew Bartlett
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/schema/schema_convert_to_ol.c230
1 files changed, 132 insertions, 98 deletions
diff --git a/source4/dsdb/schema/schema_convert_to_ol.c b/source4/dsdb/schema/schema_convert_to_ol.c
index 375e4e3810..ebcb7ade59 100644
--- a/source4/dsdb/schema/schema_convert_to_ol.c
+++ b/source4/dsdb/schema/schema_convert_to_ol.c
@@ -23,6 +23,133 @@
#include "dsdb/samdb/samdb.h"
#include "system/locale.h"
+#define SEPERATOR "\n "
+
+struct attr_map {
+ char *old_attr;
+ char *new_attr;
+};
+
+struct oid_map {
+ char *old_oid;
+ char *new_oid;
+};
+
+static char *print_schema_recursive(char *append_to_string, struct dsdb_schema *schema, const char *print_class,
+ enum dsdb_schema_convert_target target,
+ const char **attrs_skip, const struct attr_map *attr_map, const struct oid_map *oid_map)
+{
+ char *out = append_to_string;
+ const struct dsdb_class *objectclass;
+ objectclass = dsdb_class_by_lDAPDisplayName(schema, print_class);
+ if (!objectclass) {
+ DEBUG(0, ("Cannot find class %s in schema\n", print_class));
+ return NULL;
+ }
+
+ do {
+ TALLOC_CTX *mem_ctx = talloc_new(append_to_string);
+ const char *name = objectclass->lDAPDisplayName;
+ const char *oid = objectclass->governsID_oid;
+ const char *subClassOf = objectclass->subClassOf;
+ int objectClassCategory = objectclass->objectClassCategory;
+ const char **must;
+ const char **may;
+ char *schema_entry = NULL;
+ const char *objectclass_name_as_list[] = {
+ objectclass->lDAPDisplayName,
+ NULL
+ };
+ int j;
+ int attr_idx;
+
+ if (!mem_ctx) {
+ DEBUG(0, ("Failed to create new talloc context\n"));
+ return NULL;
+ }
+
+ /* We have been asked to skip some attributes/objectClasses */
+ if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
+ 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) {
+ oid = oid_map[j].new_oid;
+ break;
+ }
+ }
+
+ /* We might have been asked to remap this name, due to a conflict */
+ for (j=0; name && attr_map && attr_map[j].old_attr; j++) {
+ if (strcasecmp(name, attr_map[j].old_attr) == 0) {
+ name = attr_map[j].new_attr;
+ break;
+ }
+ }
+
+ may = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MAY);
+
+ for (j=0; may && may[j]; j++) {
+ /* We might have been asked to remap this name, due to a conflict */
+ for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) {
+ if (strcasecmp(may[j], attr_map[attr_idx].old_attr) == 0) {
+ may[j] = attr_map[attr_idx].new_attr;
+ break;
+ }
+ }
+ }
+
+ must = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MUST);
+
+ for (j=0; must && must[j]; j++) {
+ /* We might have been asked to remap this name, due to a conflict */
+ for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) {
+ if (strcasecmp(must[j], attr_map[attr_idx].old_attr) == 0) {
+ must[j] = attr_map[attr_idx].new_attr;
+ break;
+ }
+ }
+ }
+
+ schema_entry = schema_class_description(mem_ctx, target,
+ SEPERATOR,
+ oid,
+ name,
+ NULL,
+ subClassOf,
+ objectClassCategory,
+ must,
+ may,
+ NULL);
+ if (schema_entry == NULL) {
+ DEBUG(0, ("failed to generate schema description for %s\n", name));
+ return NULL;
+ }
+
+ switch (target) {
+ case TARGET_OPENLDAP:
+ out = talloc_asprintf_append(out, "objectclass %s\n\n", schema_entry);
+ break;
+ case TARGET_FEDORA_DS:
+ out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry);
+ break;
+ }
+ talloc_free(mem_ctx);
+ } while (0);
+
+
+ for (objectclass=schema->classes; objectclass; objectclass = objectclass->next) {
+ if (ldb_attr_cmp(objectclass->subClassOf, print_class) == 0
+ && ldb_attr_cmp(objectclass->lDAPDisplayName, print_class) != 0) {
+ out = print_schema_recursive(out, schema, objectclass->lDAPDisplayName,
+ target, attrs_skip, attr_map, oid_map);
+ }
+ }
+ return out;
+}
+
/* Routine to linearise our internal schema into the format that
OpenLDAP and Fedora DS use for their backend.
@@ -47,20 +174,12 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str,
char *out;
const char **attrs_skip = NULL;
int num_skip = 0;
- struct oid_map {
- char *old_oid;
- char *new_oid;
- } *oid_map = NULL;
+ struct oid_map *oid_map = NULL;
int num_oid_maps = 0;
- struct attr_map {
- char *old_attr;
- char *new_attr;
- } *attr_map = NULL;
+ struct attr_map *attr_map = NULL;
int num_attr_maps = 0;
- struct dsdb_class *objectclass;
struct dsdb_attribute *attribute;
struct dsdb_schema *schema;
- const char *seperator;
enum dsdb_schema_convert_target target;
char *next_line = talloc_strdup(mem_ctx, mappings);
@@ -137,13 +256,12 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str,
DEBUG(0, ("No schema on ldb to convert!\n"));
return NULL;
}
+
switch (target) {
case TARGET_OPENLDAP:
- seperator = "\n ";
out = talloc_strdup(mem_ctx, "");
break;
case TARGET_FEDORA_DS:
- seperator = "\n ";
out = talloc_strdup(mem_ctx, "dn: cn=schema\n");
break;
}
@@ -198,7 +316,7 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str,
schema_entry = schema_attribute_description(mem_ctx,
target,
- seperator,
+ SEPERATOR,
oid,
name,
equality,
@@ -225,91 +343,7 @@ char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str,
}
}
- /* This is already sorted to have 'top' and similar classes first */
- for (objectclass=schema->classes; objectclass; objectclass = objectclass->next) {
- const char *name = objectclass->lDAPDisplayName;
- const char *oid = objectclass->governsID_oid;
- const char *subClassOf = objectclass->subClassOf;
- int objectClassCategory = objectclass->objectClassCategory;
- const char **must;
- const char **may;
- char *schema_entry = NULL;
- const char *objectclass_name_as_list[] = {
- objectclass->lDAPDisplayName,
- NULL
- };
- int j;
- int attr_idx;
-
- /* We have been asked to skip some attributes/objectClasses */
- if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
- 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) {
- oid = oid_map[j].new_oid;
- break;
- }
- }
-
- /* We might have been asked to remap this name, due to a conflict */
- for (j=0; name && attr_map && attr_map[j].old_attr; j++) {
- if (strcasecmp(name, attr_map[j].old_attr) == 0) {
- name = attr_map[j].new_attr;
- break;
- }
- }
-
- may = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MAY);
-
- for (j=0; may && may[j]; j++) {
- /* We might have been asked to remap this name, due to a conflict */
- for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) {
- if (strcasecmp(may[j], attr_map[attr_idx].old_attr) == 0) {
- may[j] = attr_map[attr_idx].new_attr;
- break;
- }
- }
- }
-
- must = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MUST);
-
- for (j=0; must && must[j]; j++) {
- /* We might have been asked to remap this name, due to a conflict */
- for (attr_idx=0; attr_map && attr_map[attr_idx].old_attr; attr_idx++) {
- if (strcasecmp(must[j], attr_map[attr_idx].old_attr) == 0) {
- must[j] = attr_map[attr_idx].new_attr;
- break;
- }
- }
- }
-
- schema_entry = schema_class_description(mem_ctx, target,
- seperator,
- oid,
- name,
- NULL,
- subClassOf,
- objectClassCategory,
- must,
- may,
- NULL);
- if (schema_entry == NULL) {
- DEBUG(0, ("failed to generate schema description for %s\n", name));
- return NULL;
- }
-
- switch (target) {
- case TARGET_OPENLDAP:
- out = talloc_asprintf_append(out, "objectclass %s\n\n", schema_entry);
- break;
- case TARGET_FEDORA_DS:
- out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry);
- break;
- }
- }
+ out = print_schema_recursive(out, schema, "top", target, attrs_skip, attr_map, oid_map);
return out;
}