summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-07-10 15:52:44 +1000
committerAndrew Bartlett <abartlet@samba.org>2008-07-10 15:52:44 +1000
commit83d90d6cd6029446f836774d7c68bc13ce9cd360 (patch)
tree1d4ad54ddc7b3d642c826e09257b6ccd8fa5c7fe
parent016d65ee980960d4ff9970028c3eb59bb06c210b (diff)
downloadsamba-83d90d6cd6029446f836774d7c68bc13ce9cd360.tar.gz
samba-83d90d6cd6029446f836774d7c68bc13ce9cd360.tar.bz2
samba-83d90d6cd6029446f836774d7c68bc13ce9cd360.zip
Make ad2oLschema even simpler, by moving the heavy work into dsdb.
This will allow the kludge_acl and schema code to leverage the same work. (We might even get schema validation soon! :-) Andrew Bartlett (This used to be commit cecd04ce1f8ce2af2fb654b3abc1499092405d60)
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c77
-rw-r--r--source4/dsdb/schema/schema.h9
-rw-r--r--source4/dsdb/schema/schema_init.c306
-rw-r--r--source4/utils/ad2oLschema.c344
4 files changed, 368 insertions, 368 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index 6f65c199ba..a397228723 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -37,17 +37,8 @@ static int schema_fsmo_init(struct ldb_module *module)
TALLOC_CTX *mem_ctx;
struct ldb_dn *schema_dn;
struct dsdb_schema *schema;
- struct ldb_result *schema_res;
- struct ldb_result *a_res;
- struct ldb_result *c_res;
char *error_string = NULL;
int ret;
- static const char *schema_attrs[] = {
- "prefixMap",
- "schemaInfo",
- "fSMORoleOwner",
- NULL
- };
if (dsdb_get_schema(module->ldb)) {
return ldb_next_init(module);
@@ -67,83 +58,25 @@ static int schema_fsmo_init(struct ldb_module *module)
return LDB_ERR_OPERATIONS_ERROR;
}
- /*
- * setup the prefix mappings and schema info
- */
- ret = ldb_search(module->ldb, schema_dn,
- LDB_SCOPE_BASE,
- NULL, schema_attrs,
- &schema_res);
+ ret = dsdb_schema_from_schema_dn(mem_ctx, module->ldb,
+ lp_iconv_convenience(ldb_get_opaque(module->ldb, "loadparm")),
+ schema_dn, &schema, &error_string);
+
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_reset_err_string(module->ldb);
ldb_debug(module->ldb, LDB_DEBUG_WARNING,
"schema_fsmo_init: no schema head present: (skip schema loading)\n");
talloc_free(mem_ctx);
return ldb_next_init(module);
- } else if (ret != LDB_SUCCESS) {
- ldb_asprintf_errstring(module->ldb,
- "schema_fsmo_init: failed to search the schema head: %s",
- ldb_errstring(module->ldb));
- talloc_free(mem_ctx);
- return ret;
- }
- talloc_steal(mem_ctx, schema_res);
- if (schema_res->count == 0) {
- ldb_debug(module->ldb, LDB_DEBUG_WARNING,
- "schema_fsmo_init: no schema head present: (skip schema loading)\n");
- talloc_free(mem_ctx);
- return ldb_next_init(module);
- } else if (schema_res->count > 1) {
- ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
- "schema_fsmo_init: [%u] schema heads found on a base search",
- schema_res->count);
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- /*
- * load the attribute definitions
- */
- ret = ldb_search(module->ldb, schema_dn,
- LDB_SCOPE_ONELEVEL,
- "(objectClass=attributeSchema)", NULL,
- &a_res);
- if (ret != LDB_SUCCESS) {
- ldb_asprintf_errstring(module->ldb,
- "schema_fsmo_init: failed to search attributeSchema objects: %s",
- ldb_errstring(module->ldb));
- talloc_free(mem_ctx);
- return ret;
- }
- talloc_steal(mem_ctx, a_res);
-
- /*
- * load the objectClass definitions
- */
- ret = ldb_search(module->ldb, schema_dn,
- LDB_SCOPE_ONELEVEL,
- "(objectClass=classSchema)", NULL,
- &c_res);
- if (ret != LDB_SUCCESS) {
- ldb_asprintf_errstring(module->ldb,
- "schema_fsmo_init: failed to search classSchema objects: %s",
- ldb_errstring(module->ldb));
- talloc_free(mem_ctx);
- return ret;
}
- talloc_steal(mem_ctx, c_res);
- ret = dsdb_schema_from_ldb_results(mem_ctx, module->ldb,
- lp_iconv_convenience(ldb_get_opaque(module->ldb, "loadparm")),
- schema_res, a_res, c_res, &schema, &error_string);
if (ret != LDB_SUCCESS) {
ldb_asprintf_errstring(module->ldb,
"schema_fsmo_init: dsdb_schema load failed: %s",
error_string);
talloc_free(mem_ctx);
- return ret;
}
-
+
/* dsdb_set_schema() steal schema into the ldb_context */
ret = dsdb_set_schema(module->ldb, schema);
if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 6fce354f7c..66cc867a19 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -158,6 +158,15 @@ struct dsdb_schema {
struct smb_iconv_convenience *iconv_convenience;
};
+enum dsdb_attr_list_query {
+ DSDB_SCHEMA_ALL_MAY,
+ DSDB_SCHEMA_ALL_MUST,
+ DSDB_SCHEMA_SYS_MAY,
+ DSDB_SCHEMA_SYS_MUST,
+ DSDB_SCHEMA_MAY,
+ DSDB_SCHEMA_MUST
+};
+
#include "dsdb/schema/proto.h"
#endif /* _DSDB_SCHEMA_H */
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 826f91b5f0..3a6a8f5553 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -2,8 +2,8 @@
Unix SMB/CIFS mplementation.
DSDB schema header
- Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
+ Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -624,7 +624,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
status = dsdb_attribute_from_ldb(schema, attrs_res->msgs[i], sa, sa);
if (!W_ERROR_IS_OK(status)) {
*error_string = talloc_asprintf(mem_ctx,
- "schema_fsmo_init: failed to load attriute definition: %s:%s",
+ "schema_fsmo_init: failed to load attribute definition: %s:%s",
ldb_dn_get_linearized(attrs_res->msgs[i]->dn),
win_errstr(status));
talloc_free(mem_ctx);
@@ -670,6 +670,191 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
return LDB_SUCCESS;
}
+/* This recursive load of the objectClasses presumes that they
+ * everything is in a strict subClassOf hirarchy.
+ *
+ * We load this in order so we produce certain outputs (such as the
+ * exported schema for openldap, and sorted objectClass attribute) 'in
+ * order' */
+
+static int fetch_oc_recursive(struct ldb_context *ldb, struct ldb_dn *schemadn,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result *search_from,
+ struct ldb_result *res_list)
+{
+ int i;
+ int ret = 0;
+ for (i=0; i < search_from->count; i++) {
+ struct ldb_result *res;
+ const char *name = ldb_msg_find_attr_as_string(search_from->msgs[i],
+ "lDAPDisplayname", NULL);
+
+ ret = ldb_search_exp_fmt(ldb, mem_ctx, &res,
+ schemadn, LDB_SCOPE_SUBTREE, NULL,
+ "(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))",
+ name, name);
+ if (ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
+ return ret;
+ }
+
+ res_list->msgs = talloc_realloc(res_list, res_list->msgs,
+ struct ldb_message *, res_list->count + 2);
+ if (!res_list->msgs) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ res_list->msgs[res_list->count] = talloc_move(res_list,
+ &search_from->msgs[i]);
+ res_list->count++;
+ res_list->msgs[res_list->count] = NULL;
+
+ if (res->count > 0) {
+ ret = fetch_oc_recursive(ldb, schemadn, mem_ctx, res, res_list);
+ }
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result **objectclasses_res)
+{
+ TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
+ struct ldb_result *top_res, *ret_res;
+ int ret;
+ if (!local_ctx) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* Downlaod 'top' */
+ ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
+ "(&(objectClass=classSchema)(lDAPDisplayName=top))",
+ NULL, &top_res);
+ if (ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ talloc_steal(local_ctx, top_res);
+
+ if (top_res->count != 1) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret_res = talloc_zero(local_ctx, struct ldb_result);
+ if (!ret_res) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = fetch_oc_recursive(ldb, schemadn, local_ctx, top_res, ret_res);
+
+ if (ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ *objectclasses_res = talloc_move(mem_ctx, &ret_res);
+ return ret;
+}
+
+int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct ldb_dn *schema_dn,
+ struct dsdb_schema **schema,
+ char **error_string_out)
+{
+ TALLOC_CTX *tmp_ctx;
+ char *error_string;
+ int ret;
+
+ struct ldb_result *schema_res;
+ struct ldb_result *a_res;
+ struct ldb_result *c_res;
+ static const char *schema_attrs[] = {
+ "prefixMap",
+ "schemaInfo",
+ "fSMORoleOwner",
+ NULL
+ };
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ dsdb_oom(error_string_out, mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /*
+ * setup the prefix mappings and schema info
+ */
+ ret = ldb_search(ldb, schema_dn,
+ LDB_SCOPE_BASE,
+ NULL, schema_attrs,
+ &schema_res);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ talloc_free(tmp_ctx);
+ return ret;
+ } else if (ret != LDB_SUCCESS) {
+ *error_string_out = talloc_asprintf(mem_ctx,
+ "dsdb_schema: failed to search the schema head: %s",
+ ldb_errstring(ldb));
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ talloc_steal(tmp_ctx, schema_res);
+ if (schema_res->count != 1) {
+ *error_string_out = talloc_asprintf(mem_ctx,
+ "dsdb_schema: [%u] schema heads found on a base search",
+ schema_res->count);
+ talloc_free(tmp_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ /*
+ * load the attribute definitions
+ */
+ ret = ldb_search(ldb, schema_dn,
+ LDB_SCOPE_ONELEVEL,
+ "(objectClass=attributeSchema)", NULL,
+ &a_res);
+ if (ret != LDB_SUCCESS) {
+ *error_string_out = talloc_asprintf(mem_ctx,
+ "dsdb_schema: failed to search attributeSchema objects: %s",
+ ldb_errstring(ldb));
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ talloc_steal(tmp_ctx, a_res);
+
+ /*
+ * load the objectClass definitions
+ */
+ ret = fetch_objectclass_schema(ldb, schema_dn, tmp_ctx, &c_res);
+ if (ret != LDB_SUCCESS) {
+ *error_string_out = talloc_asprintf(mem_ctx,
+ "Failed to fetch objectClass schema elements: %s\n", ldb_errstring(ldb));
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
+ lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
+ schema_res, a_res, c_res, schema, &error_string);
+ if (ret != LDB_SUCCESS) {
+ *error_string_out = talloc_asprintf(mem_ctx,
+ "dsdb_schema load failed: %s",
+ error_string);
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ talloc_steal(mem_ctx, *schema);
+ talloc_free(tmp_ctx);
+
+ return LDB_SUCCESS;
+}
+
static const struct {
const char *name;
@@ -1167,6 +1352,13 @@ const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
return NULL;
}
+/**
+ Return a list of linked attributes, in lDAPDisplayName format.
+
+ This may be used to determine if a modification would require
+ backlinks to be updated, for example
+*/
+
WERROR dsdb_linked_attribute_lDAPDisplayName_list(const struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, const char ***attr_list_ret)
{
const char **attr_list = NULL;
@@ -1187,6 +1379,114 @@ WERROR dsdb_linked_attribute_lDAPDisplayName_list(const struct dsdb_schema *sche
return WERR_OK;
}
+static char **merge_attr_list(TALLOC_CTX *mem_ctx,
+ char **attrs, const char **new_attrs)
+{
+ char **ret_attrs;
+ int i;
+ size_t new_len, orig_len = str_list_length((const char **)attrs);
+ if (!new_attrs) {
+ return attrs;
+ }
+
+ ret_attrs = talloc_realloc(mem_ctx,
+ attrs, char *, orig_len + str_list_length(new_attrs) + 1);
+ if (ret_attrs) {
+ for (i=0; i < str_list_length(new_attrs); i++) {
+ ret_attrs[orig_len + i] = new_attrs[i];
+ }
+ new_len = orig_len + str_list_length(new_attrs);
+
+ ret_attrs[new_len] = NULL;
+
+ }
+
+ return ret_attrs;
+}
+
+char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx, struct dsdb_schema *schema,
+ const char **class_list,
+ enum dsdb_attr_list_query query)
+{
+ int i;
+ const struct dsdb_class *class;
+
+ char **attr_list = NULL;
+ char **recursive_list;
+
+ for (i=0; class_list && class_list[i]; i++) {
+ class = dsdb_class_by_lDAPDisplayName(schema, class_list[i]);
+
+ switch (query) {
+ case DSDB_SCHEMA_ALL_MAY:
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->mayContain);
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMayContain);
+ break;
+
+ case DSDB_SCHEMA_ALL_MUST:
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->mustContain);
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMustContain);
+ break;
+
+ case DSDB_SCHEMA_SYS_MAY:
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMayContain);
+ break;
+
+ case DSDB_SCHEMA_SYS_MUST:
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMustContain);
+ break;
+
+ case DSDB_SCHEMA_MAY:
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->mayContain);
+ break;
+
+ case DSDB_SCHEMA_MUST:
+ attr_list = merge_attr_list(mem_ctx, attr_list, class->mustContain);
+ break;
+ }
+
+ recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema,
+ class->systemAuxiliaryClass,
+ query);
+
+ attr_list = merge_attr_list(mem_ctx, attr_list, (const char **)recursive_list);
+
+ recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema,
+ class->auxiliaryClass,
+ query);
+
+ attr_list = merge_attr_list(mem_ctx, attr_list, (const char **)recursive_list);
+
+ }
+ return attr_list;
+}
+
+char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx, struct dsdb_schema *schema,
+ const char **class_list,
+ enum dsdb_attr_list_query query)
+{
+ char **attr_list = dsdb_full_attribute_list_internal(mem_ctx, schema, class_list, query);
+ size_t new_len = str_list_length((const char **)attr_list);
+
+ /* Remove duplicates */
+ if (new_len > 1) {
+ int i;
+ qsort(attr_list, new_len,
+ sizeof(*attr_list),
+ (comparison_fn_t)strcasecmp);
+
+ for (i=1 ; i < new_len; i++) {
+ char **val1 = &attr_list[i-1];
+ char **val2 = &attr_list[i];
+ if (ldb_attr_cmp(*val1, *val2) == 0) {
+ memmove(val1, val2, (new_len - i) * sizeof( *attr_list));
+ new_len--;
+ i--;
+ }
+ }
+ }
+ return attr_list;
+}
/**
* Attach the schema to an opaque pointer on the ldb, so ldb modules
* can find it
diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c
index 879b1a7213..51b03b8e8f 100644
--- a/source4/utils/ad2oLschema.c
+++ b/source4/utils/ad2oLschema.c
@@ -67,114 +67,13 @@ static void usage(void)
exit(1);
}
-static int fetch_attrs_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
- TALLOC_CTX *mem_ctx,
- struct ldb_result **attrs_res)
-{
- int ret;
-
- /* Downlaod schema */
- ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
- "objectClass=attributeSchema",
- NULL, attrs_res);
- if (ret != LDB_SUCCESS) {
- printf("Search failed: %s\n", ldb_errstring(ldb));
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return ret;
-}
-
-static int fetch_oc_recursive(struct ldb_context *ldb, struct ldb_dn *schemadn,
- TALLOC_CTX *mem_ctx,
- struct ldb_result *search_from,
- struct ldb_result *res_list)
-{
- int i;
- int ret = 0;
- for (i=0; i < search_from->count; i++) {
- struct ldb_result *res;
- const char *name = ldb_msg_find_attr_as_string(search_from->msgs[i],
- "lDAPDisplayname", NULL);
-
- ret = ldb_search_exp_fmt(ldb, mem_ctx, &res,
- schemadn, LDB_SCOPE_SUBTREE, NULL,
- "(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))",
- name, name);
- if (ret != LDB_SUCCESS) {
- printf("Search failed: %s\n", ldb_errstring(ldb));
- return ret;
- }
-
- res_list->msgs = talloc_realloc(res_list, res_list->msgs,
- struct ldb_message *, res_list->count + 2);
- if (!res_list->msgs) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- res_list->msgs[res_list->count] = talloc_move(res_list,
- &search_from->msgs[i]);
- res_list->count++;
- res_list->msgs[res_list->count] = NULL;
-
- if (res->count > 0) {
- ret = fetch_oc_recursive(ldb, schemadn, mem_ctx, res, res_list);
- }
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- }
- return ret;
-}
-
-static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
- TALLOC_CTX *mem_ctx,
- struct ldb_result **objectclasses_res)
-{
- TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
- struct ldb_result *top_res, *ret_res;
- int ret;
- if (!local_ctx) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* Downlaod 'top' */
- ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
- "(&(objectClass=classSchema)(lDAPDisplayName=top))",
- NULL, &top_res);
- if (ret != LDB_SUCCESS) {
- printf("Search failed: %s\n", ldb_errstring(ldb));
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- talloc_steal(local_ctx, top_res);
-
- if (top_res->count != 1) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret_res = talloc_zero(local_ctx, struct ldb_result);
- if (!ret_res) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = fetch_oc_recursive(ldb, schemadn, local_ctx, top_res, ret_res);
-
- if (ret != LDB_SUCCESS) {
- printf("Search failed: %s\n", ldb_errstring(ldb));
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- *objectclasses_res = talloc_move(mem_ctx, &ret_res);
- return ret;
-}
-
-static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
- struct ldb_result **schema_res)
+static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
{
const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
struct ldb_dn *schemadn;
struct ldb_dn *basedn = ldb_dn_new(mem_ctx, ldb, NULL);
struct ldb_result *rootdse_res;
+ struct ldb_result *schema_res;
int ldb_ret;
if (!basedn) {
@@ -186,126 +85,42 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
if (ldb_ret != LDB_SUCCESS) {
ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE,
"(&(objectClass=dMD)(cn=Schema))",
- NULL, schema_res);
+ NULL, &schema_res);
if (ldb_ret) {
printf("cn=Schema Search failed: %s\n", ldb_errstring(ldb));
return NULL;
}
- talloc_steal(mem_ctx, *schema_res);
+ talloc_steal(mem_ctx, schema_res);
- if ((*schema_res)->count != 1) {
+ if (schema_res->count != 1) {
+ talloc_free(schema_res);
printf("Failed to find rootDSE");
return NULL;
}
- schemadn = talloc_steal(mem_ctx, (*schema_res)->msgs[0]->dn);
+ schemadn = talloc_steal(mem_ctx, schema_res->msgs[0]->dn);
+ talloc_free(schema_res);
return schemadn;
-
}
- talloc_steal(mem_ctx, rootdse_res);
-
if (rootdse_res->count != 1) {
printf("Failed to find rootDSE");
+ talloc_free(rootdse_res);
return NULL;
}
/* Locate schema */
schemadn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
- if (!schemadn) {
- return NULL;
- }
+ talloc_free(rootdse_res);
- ldb_ret = ldb_search(ldb, schemadn, LDB_SCOPE_BASE,
- "(&(objectClass=dMD)(cn=Schema))",
- NULL, schema_res);
- if (ldb_ret) {
- printf("cn=Schema Search failed: %s\n", ldb_errstring(ldb));
+ if (!schemadn) {
return NULL;
}
-
- talloc_steal(mem_ctx, *schema_res);
- if ((*schema_res)->count != 1) {
- printf("Failed to find rootDSE");
- return NULL;
- }
- talloc_free(rootdse_res);
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, NULL,
- "(&(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) { \
@@ -332,13 +147,14 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
char *new_attr;
} *attr_map = NULL;
int num_attr_maps = 0;
- struct ldb_result *schema_res, *attrs_res, *objectclasses_res;
+ struct dsdb_class *objectclass;
+ struct dsdb_attribute *attribute;
struct ldb_dn *schemadn;
struct schema_conv ret;
struct dsdb_schema *schema;
char *error_string;
- int ldb_ret, i;
+ int ldb_ret;
ret.count = 0;
ret.skipped = 0;
@@ -389,31 +205,16 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
}
}
- schemadn = find_schema_dn(ldb, mem_ctx, &schema_res);
+ schemadn = find_schema_dn(ldb, mem_ctx);
if (!schemadn) {
printf("Failed to find schema DN: %s\n", ldb_errstring(ldb));
ret.failures = 1;
return ret;
}
- ldb_ret = fetch_attrs_schema(ldb, schemadn, mem_ctx, &attrs_res);
- if (ldb_ret != LDB_SUCCESS) {
- printf("Failed to fetch attribute schema: %s\n", ldb_errstring(ldb));
- ret.failures = 1;
- return ret;
- }
-
-
- ldb_ret = fetch_objectclass_schema(ldb, schemadn, mem_ctx, &objectclasses_res);
- if (ldb_ret != LDB_SUCCESS) {
- printf("Failed to fetch objectClass schema elements: %s\n", ldb_errstring(ldb));
- ret.failures = 1;
- return ret;
- }
-
- ldb_ret = dsdb_schema_from_ldb_results(mem_ctx, ldb,
- lp_iconv_convenience(cmdline_lp_ctx),
- schema_res, attrs_res, objectclasses_res, &schema, &error_string);
+ ldb_ret = dsdb_schema_from_schema_dn(mem_ctx, ldb,
+ lp_iconv_convenience(cmdline_lp_ctx),
+ schemadn, &schema, &error_string);
if (ldb_ret != LDB_SUCCESS) {
printf("Failed to load schema: %s\n", error_string);
ret.failures = 1;
@@ -428,24 +229,17 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
break;
}
- for (i=0; i < attrs_res->count; i++) {
- struct ldb_message *msg = attrs_res->msgs[i];
+ for (attribute=schema->attributes; attribute; attribute = attribute->next) {
+ const char *name = attribute->lDAPDisplayName;
+ const char *description = attribute->adminDescription;
+ const char *oid = attribute->attributeID_oid;
+ const char *syntax = attribute->attributeSyntax_oid;
+ bool single_value = attribute->isSingleValued;
- 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;
- if (!name) {
- printf("Failed to find lDAPDisplayName for schema DN: %s\n", ldb_dn_get_linearized(msg->dn));
- ret.failures++;
- continue;
- }
-
/* We have been asked to skip some attributes/objectClasses */
if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
ret.skipped++;
@@ -487,9 +281,11 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
IF_NULL_FAIL_RET(schema_entry);
if (description) {
+#if 0 /* If you want to re-enable this, you must first figure out a sane escaping of ' in the description */
schema_entry = talloc_asprintf_append(schema_entry,
- " DESC %s\n", description);
+ " DESC '%s'\n", description);
IF_NULL_FAIL_RET(schema_entry);
+#endif
}
if (map) {
@@ -539,59 +335,31 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
ret.count++;
}
- for (i=0; i < objectclasses_res->count; i++) {
- struct ldb_message *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");
- 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");
+ /* 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 *description = objectclass->adminDescription;
+ const char *oid = objectclass->governsID_oid;
+ const char *subClassOf = objectclass->subClassOf;
+ int objectClassCategory = objectclass->objectClassCategory;
+ char **must;
+ char **may;
char *schema_entry = NULL;
+ const char *objectclass_name_as_list[] = {
+ objectclass->lDAPDisplayName,
+ NULL
+ };
int j;
-
- if (!name) {
- printf("Failed to find lDAPDisplayName for schema DN: %s\n", ldb_dn_get_linearized(msg->dn));
- ret.failures++;
- continue;
- }
-
+
/* We have been asked to skip some attributes/objectClasses */
if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
ret.skipped++;
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);
- }
+ may = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MAY);
- 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;
- }
+ must = dsdb_full_attribute_list(mem_ctx, schema, objectclass_name_as_list, DSDB_SCHEMA_ALL_MUST);
/* We might have been asked to remap this oid, due to a conflict */
for (j=0; oid_map && oid_map[j].old_oid; j++) {
@@ -635,7 +403,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
if (description) {
schema_entry = talloc_asprintf_append(schema_entry,
- " DESC %s\n", description);
+ " DESC '%s'\n", description);
IF_NULL_FAIL_RET(schema_entry);
}
@@ -666,9 +434,9 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
#define APPEND_ATTRS(attributes) \
do { \
int k; \
- for (k=0; attributes && k < attributes->num_values; k++) { \
+ for (k=0; attributes && attributes[k]; k++) { \
int attr_idx; \
- const char *attr_name = (const char *)attributes->values[k].data; \
+ const char *attr_name = attributes[k]; \
/* We might have been asked to remap this name, due to a conflict */ \
for (attr_idx=0; attr_name && attr_map && attr_map[attr_idx].old_attr; attr_idx++) { \
if (strcasecmp(attr_name, attr_map[attr_idx].old_attr) == 0) { \
@@ -681,7 +449,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
" %s", \
attr_name); \
IF_NULL_FAIL_RET(schema_entry); \
- if (k != (attributes->num_values - 1)) { \
+ if (attributes[k+1]) { \
schema_entry = talloc_asprintf_append(schema_entry, \
" $"); \
IF_NULL_FAIL_RET(schema_entry); \
@@ -694,35 +462,25 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
} \
} while (0)
- if ((must && must->values) || (sys_must && sys_must->values)) {
+ if (must) {
schema_entry = talloc_asprintf_append(schema_entry,
" MUST (");
IF_NULL_FAIL_RET(schema_entry);
APPEND_ATTRS(must);
- if (must && must->values && sys_must && sys_must->values) {
- 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 && may->values) || (sys_may && sys_may->values)) {
+ if (may) {
schema_entry = talloc_asprintf_append(schema_entry,
" MAY (");
IF_NULL_FAIL_RET(schema_entry);
APPEND_ATTRS(may);
- if (may && may->values && sys_may && sys_may->values) {
- 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);