From 17aac8cad2b3fe4b23eaebd869b1538735a1954a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 5 Mar 2009 16:52:11 +1100 Subject: Remove ad2oLschema, insted call it directly from provision-backend This removes a level of indirection via external binaries in the provision-backend code, and also makes better use of our internal code for loading schema from an LDIF file. Remaining to do: Sort the output again, as the load from LDIF is unsorted (also needed because the normal LDB load from sorted input is too slow anyway, and is only needed here). Andrew Bartlett --- source4/dsdb/config.mk | 3 +- source4/dsdb/schema/schema_convert_to_ol.c | 316 ++++++++++++++++++++ source4/dsdb/schema/schema_set.c | 2 +- source4/scripting/python/pyglue.c | 31 +- source4/scripting/python/samba/provision.py | 22 +- source4/scripting/python/samba/samdb.py | 5 +- source4/utils/ad2oLschema.c | 442 ---------------------------- source4/utils/config.mk | 13 - 8 files changed, 361 insertions(+), 473 deletions(-) create mode 100644 source4/dsdb/schema/schema_convert_to_ol.c delete mode 100644 source4/utils/ad2oLschema.c (limited to 'source4') diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index 2ca4e4ca6d..6db2890738 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -37,7 +37,8 @@ SAMDB_SCHEMA_OBJ_FILES = $(addprefix $(dsdbsrcdir)/schema/, \ schema_set.o \ schema_query.o \ schema_syntax.o \ - schema_description.o) + schema_description.o \ + schema_convert_to_ol.o) $(eval $(call proto_header_template,$(dsdbsrcdir)/schema/proto.h,$(SAMDB_SCHEMA_OBJ_FILES:.o=.c))) # PUBLIC_HEADERS += dsdb/schema/schema.h diff --git a/source4/dsdb/schema/schema_convert_to_ol.c b/source4/dsdb/schema/schema_convert_to_ol.c new file mode 100644 index 0000000000..375e4e3810 --- /dev/null +++ b/source4/dsdb/schema/schema_convert_to_ol.c @@ -0,0 +1,316 @@ +/* + schema conversion routines + + Copyright (C) Andrew Bartlett 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#include "includes.h" +#include "ldb.h" +#include "dsdb/samdb/samdb.h" +#include "system/locale.h" + +/* Routine to linearise our internal schema into the format that + OpenLDAP and Fedora DS use for their backend. + + The 'mappings' are of a format like: + +#Standard OpenLDAP attributes +labeledURI +#The memberOf plugin provides this attribute +memberOf +#These conflict with OpenLDAP builtins +attributeTypes:samba4AttributeTypes +2.5.21.5:1.3.6.1.4.1.7165.4.255.7 + +*/ + + +char *dsdb_convert_schema_to_openldap(struct ldb_context *ldb, char *target_str, const char *mappings) +{ + /* Read list of attributes to skip, OIDs to map */ + TALLOC_CTX *mem_ctx = talloc_new(ldb); + char *line; + char *out; + const char **attrs_skip = NULL; + int num_skip = 0; + struct oid_map { + char *old_oid; + char *new_oid; + } *oid_map = NULL; + int num_oid_maps = 0; + struct attr_map { + char *old_attr; + char *new_attr; + } *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); + + if (!target_str || strcasecmp(target_str, "openldap") == 0) { + target = TARGET_OPENLDAP; + } else if (strcasecmp(target_str, "fedora-ds") == 0) { + target = TARGET_FEDORA_DS; + } else { + DEBUG(0, ("Invalid target type for schema conversion %s\n", target_str)); + return NULL; + } + + /* The mappings are line-seperated, and specify details such as OIDs to skip etc */ + while (1) { + line = next_line; + next_line = strchr(line, '\n'); + if (!next_line) { + break; + } + next_line[0] = '\0'; + next_line++; + + /* Blank Line */ + if (line[0] == '\0') { + continue; + } + /* Comment */ + if (line[0] == '#') { + continue; + } + + if (isdigit(line[0])) { + char *p = strchr(line, ':'); + if (!p) { + DEBUG(0, ("schema mapping file line has OID but no OID to map to: %s\n", line)); + return NULL; + } + p[0] = '\0'; + p++; + oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_oid_maps + 2); + trim_string(line, " ", " "); + oid_map[num_oid_maps].old_oid = talloc_strdup(oid_map, line); + trim_string(p, " ", " "); + oid_map[num_oid_maps].new_oid = p; + num_oid_maps++; + oid_map[num_oid_maps].old_oid = NULL; + } else { + char *p = strchr(line, ':'); + if (p) { + /* remap attribute/objectClass */ + p[0] = '\0'; + p++; + attr_map = talloc_realloc(mem_ctx, attr_map, struct attr_map, num_attr_maps + 2); + trim_string(line, " ", " "); + attr_map[num_attr_maps].old_attr = talloc_strdup(attr_map, line); + trim_string(p, " ", " "); + attr_map[num_attr_maps].new_attr = p; + num_attr_maps++; + attr_map[num_attr_maps].old_attr = NULL; + } else { + /* skip attribute/objectClass */ + attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2); + trim_string(line, " ", " "); + attrs_skip[num_skip] = talloc_strdup(attrs_skip, line); + num_skip++; + attrs_skip[num_skip] = NULL; + } + } + } + + schema = dsdb_get_schema(ldb); + if (!schema) { + 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; + } + + for (attribute=schema->attributes; attribute; attribute = attribute->next) { + const char *name = attribute->lDAPDisplayName; + const char *oid = attribute->attributeID_oid; + const char *syntax = attribute->attributeSyntax_oid; + const char *equality = NULL, *substring = NULL; + bool single_value = attribute->isSingleValued; + + char *schema_entry = NULL; + int j; + + /* 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 && oid_map && oid_map[j].old_oid; j++) { + if (strcasecmp(oid, oid_map[j].old_oid) == 0) { + oid = oid_map[j].new_oid; + break; + } + } + + if (attribute->syntax) { + /* We might have been asked to remap this oid, + * due to a conflict, or lack of + * implementation */ + syntax = attribute->syntax->ldap_oid; + /* We might have been asked to remap this oid, due to a conflict */ + for (j=0; syntax && oid_map && oid_map[j].old_oid; j++) { + if (strcasecmp(syntax, oid_map[j].old_oid) == 0) { + syntax = oid_map[j].new_oid; + break; + } + } + + equality = attribute->syntax->equality; + substring = attribute->syntax->substring; + } + + /* 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; + } + } + + schema_entry = schema_attribute_description(mem_ctx, + target, + seperator, + oid, + name, + equality, + substring, + syntax, + single_value, + false, + NULL, NULL, + NULL, NULL, + false, false); + + if (schema_entry == NULL) { + DEBUG(0, ("failed to generate attribute description for %s\n", name)); + return NULL; + } + + switch (target) { + case TARGET_OPENLDAP: + out = talloc_asprintf_append(out, "attributetype %s\n\n", schema_entry); + break; + case TARGET_FEDORA_DS: + out = talloc_asprintf_append(out, "attributeTypes: %s\n", schema_entry); + break; + } + } + + /* 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; + } + } + + return out; +} + diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 6abd8a8f88..d52976958d 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -277,7 +277,7 @@ void dsdb_make_schema_global(struct ldb_context *ldb) * schema itself to the directory. */ -WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df) +WERROR dsdb_attach_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df) { struct ldb_ldif *ldif; struct ldb_message *msg; diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index a2c4790611..1480e54403 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -212,7 +212,7 @@ static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject *py_dsdb_attach_schema_from_ldif_file(PyObject *self, PyObject *args) +static PyObject *py_dsdb_attach_schema_from_ldif(PyObject *self, PyObject *args) { WERROR result; char *pf, *df; @@ -224,12 +224,35 @@ static PyObject *py_dsdb_attach_schema_from_ldif_file(PyObject *self, PyObject * PyErr_LDB_OR_RAISE(py_ldb, ldb); - result = dsdb_attach_schema_from_ldif_file(ldb, pf, df); + result = dsdb_attach_schema_from_ldif(ldb, pf, df); PyErr_WERROR_IS_ERR_RAISE(result); Py_RETURN_NONE; } +static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self, PyObject *args) +{ + char *target_str, *mapping; + PyObject *py_ldb; + struct ldb_context *ldb; + PyObject *ret; + char *retstr; + + if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &target_str, &mapping)) + return NULL; + + PyErr_LDB_OR_RAISE(py_ldb, ldb); + + retstr = dsdb_convert_schema_to_openldap(ldb, target_str, mapping); + if (!retstr) { + PyErr_SetString(PyExc_RuntimeError, "dsdb_convert_schema_to_openldap failed"); + return NULL; + } + ret = PyString_FromString(retstr); + talloc_free(retstr); + return ret; +} + static PyMethodDef py_misc_methods[] = { { "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS, "random_password(len) -> string\n" @@ -255,7 +278,9 @@ static PyMethodDef py_misc_methods[] = { NULL }, { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS, NULL }, - { "dsdb_attach_schema_from_ldif_file", (PyCFunction)py_dsdb_attach_schema_from_ldif_file, METH_VARARGS, + { "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS, + NULL }, + { "dsdb_convert_schema_to_openldap", (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS, NULL }, { NULL } }; diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8029565399..ed6548b13b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1245,7 +1245,7 @@ def provision_backend(setup_dir=None, message=None, except OSError: pass - schemadb = Ldb(schemadb_path, lp=lp) + schemadb = SamDB(schemadb_path, lp=lp) prefixmap = open(setup_path("prefixMap.txt"), 'r').read() @@ -1263,10 +1263,8 @@ def provision_backend(setup_dir=None, message=None, "PREFIXMAP_B64": b64encode(prefixmap) }) - setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), - {"SCHEMADN": names.schemadn }) - - data = get_schema_data(setup_path, {"SCHEMADN": names.schemadn}) + data = load_schema(setup_path, schemadb, names.schemadn, names.netbiosname, + names.configdn, DEFAULTSITE, names.serverdn) schemadb.add_ldif(data) if ldap_backend_type == "fedora-ds": @@ -1480,10 +1478,10 @@ def provision_backend(setup_dir=None, message=None, ldapuser = "--username=samba-admin" - - schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) - - os.system(schema_command) + + backend_schema_data = schemadb.convert_schema_to_openldap(ldap_backend_type, open(setup_path(mapping), 'r').read()) + assert backend_schema_data is not None + open(os.path.join(paths.ldapdir, backend_schema), 'w').write(backend_schema_data) message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ldap_backend_type) message("Server Role: %s" % serverrole) @@ -1646,7 +1644,7 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename, - serverdn, servername): + serverdn): """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. @@ -1655,7 +1653,6 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename, :param netbiosname: NetBIOS name of the host. :param configdn: DN of the configuration :param serverdn: DN of the server - :param servername: Host name of the server Returns the schema data loaded, to avoid double-parsing when then needing to add it to the db """ @@ -1674,7 +1671,6 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename, "DEFAULTSITE": sitename, "PREFIXMAP_B64": prefixmap, "SERVERDN": serverdn, - "SERVERNAME": servername, }) check_all_substituted(head_data) samdb.attach_schema_from_ldif(head_data, schema_data) @@ -1685,6 +1681,8 @@ def get_schema_data(setup_path, subst_vars = None): :param setup_path: Setup path function. :param subst_vars: Optional variables to substitute in the file. + + Returns the schema data after substitution """ # this data used to be read from schema.ldif diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 614970d3ec..881f5912fb 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -198,7 +198,10 @@ userAccountControl: %u glue.samdb_set_domain_sid(self, sid) def attach_schema_from_ldif(self, pf, df): - glue.dsdb_attach_schema_from_ldif_file(self, pf, df) + glue.dsdb_attach_schema_from_ldif(self, pf, df) + + def convert_schema_to_openldap(self, target, mapping): + return glue.dsdb_convert_schema_to_openldap(self, target, mapping) def set_invocation_id(self, invocation_id): """Set the invocation id for this SamDB handle. diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c deleted file mode 100644 index 236b1fa350..0000000000 --- a/source4/utils/ad2oLschema.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlett 2006-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ad2oLschema - * - * Description: utility to convert an AD schema into the format required by OpenLDAP - * - * Author: Andrew Bartlett - */ - -#include "includes.h" -#include "ldb.h" -#include "system/locale.h" -#include "lib/ldb/tools/cmdline.h" -#include "param/param.h" -#include "lib/cmdline/popt_common.h" -#include "dsdb/samdb/samdb.h" - -struct schema_conv { - int count; - int skipped; - int failures; -}; - - -static void usage(void) -{ - printf("Usage: ad2oLschema \n"); - printf("\nConvert AD-like LDIF to OpenLDAP schema format\n\n"); - printf("Options:\n"); - printf(" -I inputfile inputfile of mapped OIDs and skipped attributes/ObjectClasses"); - printf(" -H url LDB or LDAP server to read schmea from\n"); - printf(" -O outputfile outputfile otherwise STDOUT\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Converts records from an AD-like LDIF schema into an openLdap formatted schema\n\n"); - exit(1); -} - -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) { - return NULL; - } - - /* Search for rootdse */ - ldb_ret = ldb_search(ldb, mem_ctx, &rootdse_res, - basedn, LDB_SCOPE_BASE, rootdse_attrs, NULL); - if (ldb_ret != LDB_SUCCESS) { - ldb_ret = ldb_search(ldb, mem_ctx, &schema_res, basedn, LDB_SCOPE_SUBTREE, - NULL, "(&(objectClass=dMD)(cn=Schema))"); - if (ldb_ret) { - printf("cn=Schema Search failed: %s\n", ldb_errstring(ldb)); - return NULL; - } - - 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); - talloc_free(schema_res); - return schemadn; - } - - 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"); - talloc_free(rootdse_res); - - if (!schemadn) { - return NULL; - } - - return schemadn; -} - - -static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_schema_convert_target target, FILE *in, FILE *out) -{ - /* Read list of attributes to skip, OIDs to map */ - TALLOC_CTX *mem_ctx = talloc_new(ldb); - char *line; - const char **attrs_skip = NULL; - int num_skip = 0; - struct oid_map { - char *old_oid; - char *new_oid; - } *oid_map = NULL; - int num_oid_maps = 0; - struct attr_map { - char *old_attr; - char *new_attr; - } *attr_map = NULL; - int num_attr_maps = 0; - struct dsdb_class *objectclass; - struct dsdb_attribute *attribute; - struct ldb_dn *schemadn; - struct schema_conv ret; - struct dsdb_schema *schema; - const char *seperator; - char *error_string; - - int ldb_ret; - - ret.count = 0; - ret.skipped = 0; - ret.failures = 0; - - while ((line = afdgets(fileno(in), mem_ctx, 0))) { - /* Blank Line */ - if (line[0] == '\0') { - continue; - } - /* Comment */ - if (line[0] == '#') { - continue; - } - if (isdigit(line[0])) { - char *p = strchr(line, ':'); - if (!p) { - ret.failures++; - return ret; - } - p[0] = '\0'; - p++; - oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_oid_maps + 2); - trim_string(line, " ", " "); - oid_map[num_oid_maps].old_oid = talloc_move(oid_map, &line); - trim_string(p, " ", " "); - oid_map[num_oid_maps].new_oid = p; - num_oid_maps++; - oid_map[num_oid_maps].old_oid = NULL; - } else { - char *p = strchr(line, ':'); - if (p) { - /* remap attribute/objectClass */ - p[0] = '\0'; - p++; - attr_map = talloc_realloc(mem_ctx, attr_map, struct attr_map, num_attr_maps + 2); - trim_string(line, " ", " "); - attr_map[num_attr_maps].old_attr = talloc_move(attr_map, &line); - trim_string(p, " ", " "); - attr_map[num_attr_maps].new_attr = p; - num_attr_maps++; - attr_map[num_attr_maps].old_attr = NULL; - } else { - /* skip attribute/objectClass */ - attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2); - trim_string(line, " ", " "); - attrs_skip[num_skip] = talloc_move(attrs_skip, &line); - num_skip++; - attrs_skip[num_skip] = NULL; - } - } - } - - 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 = 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; - return ret; - } - - switch (target) { - case TARGET_OPENLDAP: - seperator = "\n "; - break; - case TARGET_FEDORA_DS: - seperator = "\n "; - fprintf(out, "dn: cn=schema\n"); - break; - } - - for (attribute=schema->attributes; attribute; attribute = attribute->next) { - const char *name = attribute->lDAPDisplayName; - const char *oid = attribute->attributeID_oid; - const char *syntax = attribute->attributeSyntax_oid; - const char *equality = NULL, *substring = NULL; - bool single_value = attribute->isSingleValued; - - char *schema_entry = NULL; - int j; - - /* We have been asked to skip some attributes/objectClasses */ - if (attrs_skip && str_list_check_ci(attrs_skip, name)) { - ret.skipped++; - continue; - } - - /* We might have been asked to remap this oid, due to a conflict */ - for (j=0; oid && oid_map && oid_map[j].old_oid; j++) { - if (strcasecmp(oid, oid_map[j].old_oid) == 0) { - oid = oid_map[j].new_oid; - break; - } - } - - if (attribute->syntax) { - /* We might have been asked to remap this oid, - * due to a conflict, or lack of - * implementation */ - syntax = attribute->syntax->ldap_oid; - /* We might have been asked to remap this oid, due to a conflict */ - for (j=0; syntax && oid_map && oid_map[j].old_oid; j++) { - if (strcasecmp(syntax, oid_map[j].old_oid) == 0) { - syntax = oid_map[j].new_oid; - break; - } - } - - equality = attribute->syntax->equality; - substring = attribute->syntax->substring; - } - - /* 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; - } - } - - schema_entry = schema_attribute_description(mem_ctx, - target, - seperator, - oid, - name, - equality, - substring, - syntax, - single_value, - false, - NULL, NULL, - NULL, NULL, - false, false); - - if (schema_entry == NULL) { - ret.failures++; - return ret; - } - - switch (target) { - case TARGET_OPENLDAP: - fprintf(out, "attributetype %s\n\n", schema_entry); - break; - case TARGET_FEDORA_DS: - fprintf(out, "attributeTypes: %s\n", schema_entry); - break; - } - ret.count++; - } - - /* 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)) { - ret.skipped++; - 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) { - ret.failures++; - return ret; - } - - switch (target) { - case TARGET_OPENLDAP: - fprintf(out, "objectclass %s\n\n", schema_entry); - break; - case TARGET_FEDORA_DS: - fprintf(out, "objectClasses: %s\n", schema_entry); - break; - } - ret.count++; - } - - return ret; -} - - int main(int argc, const char **argv) -{ - TALLOC_CTX *ctx; - struct ldb_cmdline *options; - FILE *in = stdin; - FILE *out = stdout; - struct ldb_context *ldb; - struct schema_conv ret; - const char *target_str; - enum dsdb_schema_convert_target target; - - ctx = talloc_new(NULL); - ldb = ldb_init(ctx, NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->input) { - in = fopen(options->input, "r"); - if (!in) { - perror(options->input); - exit(1); - } - } - if (options->output) { - out = fopen(options->output, "w"); - if (!out) { - perror(options->output); - exit(1); - } - } - - target_str = lp_parm_string(cmdline_lp_ctx, NULL, "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); - - printf("Converted %d records (skipped %d) with %d failures\n", ret.count, ret.skipped, ret.failures); - - return 0; -} diff --git a/source4/utils/config.mk b/source4/utils/config.mk index ea8e00ff8a..5fa7e200f0 100644 --- a/source4/utils/config.mk +++ b/source4/utils/config.mk @@ -92,16 +92,3 @@ oLschema2ldif_OBJ_FILES = $(addprefix $(utilssrcdir)/, oLschema2ldif.o) MANPAGES += $(utilssrcdir)/man/oLschema2ldif.1 -################################################ -# Start BINARY ad2oLschema -[BINARY::ad2oLschema] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE SAMDB -# End BINARY ad2oLschema -################################################ - -ad2oLschema_OBJ_FILES = $(addprefix $(utilssrcdir)/, ad2oLschema.o) - -MANPAGES += $(utilssrcdir)/man/ad2oLschema.1 - -- cgit