summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/ldb/tools/ad2oLschema.c305
1 files changed, 252 insertions, 53 deletions
diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c
index 03adf195db..75b03dd3b0 100644
--- a/source4/lib/ldb/tools/ad2oLschema.c
+++ b/source4/lib/ldb/tools/ad2oLschema.c
@@ -43,6 +43,12 @@ struct schema_conv {
int failures;
};
+enum convert_target {
+ TARGET_OPENLDAP,
+ TARGET_FEDORA_DS
+};
+
+
static void usage(void)
{
printf("Usage: ad2oLschema <options>\n");
@@ -58,25 +64,18 @@ static void usage(void)
exit(1);
};
-static int fetch_schema(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **attrs_res, struct ldb_result **objectclasses_res)
+static int fetch_attrs_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result **attrs_res)
{
TALLOC_CTX *local_ctx = talloc_new(mem_ctx);
- struct ldb_dn *basedn, *schemadn;
- struct ldb_result *res;
int ret;
- const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
const char *attrs[] = {
"lDAPDisplayName",
- "mayContain",
- "mustContain",
- "systemMayContain",
- "systemMustContain",
- "objectClassCategory",
"isSingleValued",
"attributeID",
"attributeSyntax",
"description",
- "subClassOf",
NULL
};
@@ -84,53 +83,153 @@ static int fetch_schema(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb
return LDB_ERR_OPERATIONS_ERROR;
}
- basedn = ldb_dn_explode(mem_ctx, "");
- if (!basedn) {
+ /* Downlaod schema */
+ ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
+ "objectClass=attributeSchema",
+ attrs, attrs_res);
+ if (ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
}
- /* Search for rootdse */
- ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, rootdse_attrs, &res);
+ return ret;
+}
+
+static const char *oc_attrs[] = {
+ "lDAPDisplayName",
+ "mayContain",
+ "mustContain",
+ "systemMayContain",
+ "systemMustContain",
+ "objectClassCategory",
+ "governsID",
+ "description",
+ "subClassOf",
+ NULL
+};
+
+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);
+ char *filter = talloc_asprintf(mem_ctx, "(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))",
+ name, name);
+
+ ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
+ filter,
+ oc_attrs, &res);
+ talloc_free(filter);
+ if (ret != LDB_SUCCESS) {
+ printf("Search failed: %s\n", ldb_errstring(ldb));
+ return ret;
+ }
+
+ talloc_steal(mem_ctx, res);
+
+ 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_steal(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))",
+ oc_attrs, &top_res);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
}
-
- if (res->count != 1) {
+
+ talloc_steal(local_ctx, top_res);
+
+ if (top_res->count != 1) {
return LDB_ERR_OPERATIONS_ERROR;
}
-
- /* Locate schema */
- schemadn = ldb_msg_find_attr_as_dn(mem_ctx, res->msgs[0], "schemaNamingContext");
- if (!schemadn) {
+
+ ret_res = talloc_zero(local_ctx, struct ldb_result);
+ if (!ret_res) {
return LDB_ERR_OPERATIONS_ERROR;
}
- /* Downlaod schema */
- ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
- "objectClass=attributeSchema",
- attrs, attrs_res);
+ 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;
}
- ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
- "objectClass=classSchema",
- attrs, objectclasses_res);
- if (ret != LDB_SUCCESS) {
+ *objectclasses_res = talloc_steal(mem_ctx, ret_res);
+ return ret;
+}
+
+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_explode(mem_ctx, "");
+ struct ldb_result *rootdse_res;
+ int ldb_ret;
+ if (!basedn) {
+ return NULL;
+ }
+
+ /* Search for rootdse */
+ ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, rootdse_attrs, &rootdse_res);
+ if (ldb_ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
- return ret;
+ return NULL;
}
+
+ talloc_steal(mem_ctx, rootdse_res);
- talloc_steal(mem_ctx, *attrs_res);
- talloc_steal(mem_ctx, *objectclasses_res);
- talloc_free(local_ctx);
+ if (rootdse_res->count != 1) {
+ printf("Failed to find rootDSE");
+ return NULL;
+ }
- return LDB_SUCCESS;
+ /* Locate schema */
+ schemadn = ldb_msg_find_attr_as_dn(mem_ctx, rootdse_res->msgs[0], "schemaNamingContext");
+ if (!schemadn) {
+ return NULL;
+ }
+
+ talloc_free(rootdse_res);
+ return schemadn;
}
-static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FILE *out)
+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 */
TALLOC_CTX *mem_ctx = talloc_new(ldb);
@@ -143,7 +242,9 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
} *oid_map = NULL;
int num_maps = 0;
struct ldb_result *attrs_res, *objectclasses_res;
+ struct ldb_dn *schemadn;
struct schema_conv ret;
+
int ldb_ret, i;
ret.count = 0;
@@ -172,8 +273,16 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
}
}
- ldb_ret = fetch_schema(ldb, mem_ctx, &attrs_res, &objectclasses_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;
}
@@ -182,7 +291,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
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 *subClassOf = ldb_msg_find_attr_as_string(attrs_res->msgs[i], "subClassOf", 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);
const struct syntax_map *map = find_syntax_map_by_ad_oid(syntax);
@@ -196,16 +304,25 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
}
/* We might have been asked to remap this oid, due to a conflict */
- for (j=0; oid_map[j].old_oid; j++) {
+ for (j=0; oid && oid_map[j].old_oid; j++) {
if (strcmp(oid, oid_map[j].old_oid) == 0) {
oid = oid_map[j].new_oid;
break;
}
}
- schema_entry = talloc_asprintf(mem_ctx,
- "attributetype (\n"
- " %s\n", oid);
+ switch (target) {
+ case TARGET_OPENLDAP:
+ schema_entry = talloc_asprintf(mem_ctx,
+ "attributetype (\n"
+ " %s\n", oid);
+ break;
+ case TARGET_FEDORA_DS:
+ schema_entry = talloc_asprintf(mem_ctx,
+ "attributeTypes: (\n"
+ " %s\n", oid);
+ break;
+ }
if (!schema_entry) {
ret.failures++;
break;
@@ -229,15 +346,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
}
}
- if (subClassOf) {
- schema_entry = talloc_asprintf_append(schema_entry,
- " SUP %s\n", subClassOf);
- if (!schema_entry) {
- ret.failures++;
- return ret;
- }
- }
-
if (map) {
if (map->equality) {
schema_entry = talloc_asprintf_append(schema_entry,
@@ -273,13 +381,91 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
}
schema_entry = talloc_asprintf_append(schema_entry,
- ")\n\n");
+ " )\n\n");
fprintf(out, "%s", schema_entry);
}
- /* Read each element */
- /* Replace OID if required */
+ 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;
+ }
+
+ 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);
+ char *schema_entry = NULL;
+ int j;
+
+ /* We have been asked to skip some attributes/objectClasses */
+ if (in_list(attrs_skip, name, False)) {
+ ret.skipped++;
+ continue;
+ }
+
+ /* We might have been asked to remap this oid, due to a conflict */
+ for (j=0; oid_map[j].old_oid; j++) {
+ if (strcmp(oid, oid_map[j].old_oid) == 0) {
+ oid = oid_map[j].new_oid;
+ break;
+ }
+ }
+
+ switch (target) {
+ case TARGET_OPENLDAP:
+ schema_entry = talloc_asprintf(mem_ctx,
+ "objectClass (\n"
+ " %s\n", oid);
+ break;
+ case TARGET_FEDORA_DS:
+ schema_entry = talloc_asprintf(mem_ctx,
+ "objectClasses: (\n"
+ " %s\n", oid);
+ break;
+ }
+ if (!schema_entry) {
+ ret.failures++;
+ break;
+ }
+
+ schema_entry = talloc_asprintf_append(schema_entry,
+ " NAME '%s'\n", name);
+ if (!schema_entry) {
+ ret.failures++;
+ return ret;
+ }
+
+ 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 (subClassOf) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ " SUP %s\n", subClassOf);
+ if (!schema_entry) {
+ ret.failures++;
+ return ret;
+ }
+ }
+
+ schema_entry = talloc_asprintf_append(schema_entry,
+ " )\n\n");
+
+ fprintf(out, "%s", schema_entry);
+ }
+
+ return ret;
}
int main(int argc, const char **argv)
@@ -290,6 +476,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
FILE *out = stdout;
struct ldb_context *ldb;
struct schema_conv ret;
+ const char *target_str;
+ enum convert_target target;
ldb_global_init();
@@ -313,7 +501,18 @@ static struct schema_conv process_convert(struct ldb_context *ldb, FILE *in, FIL
}
}
- ret = process_convert(ldb, in, out);
+ target_str = lp_parm_string(-1, "convert", "target");
+
+ if (!target_str || strcasecmp(target_str, "openldap") == 0) {
+ target = TARGET_OPENLDAP;
+ } else if (strcasecmp(target_str, "fedora-ds") == 0) {
+ target = TARGET_FEDORA_DS;
+ } else {
+ printf("Unsupported target: %s\n", target_str);
+ exit(1);
+ }
+
+ ret = process_convert(ldb, target, in, out);
fclose(in);
fclose(out);