summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-03-05 16:52:11 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-03-05 16:52:11 +1100
commit17aac8cad2b3fe4b23eaebd869b1538735a1954a (patch)
treeb9fbe27b174e626c0791ae08f55cd475789598f1
parent41760c18bdab20d526d32568531bdf7c88272879 (diff)
downloadsamba-17aac8cad2b3fe4b23eaebd869b1538735a1954a.tar.gz
samba-17aac8cad2b3fe4b23eaebd869b1538735a1954a.tar.bz2
samba-17aac8cad2b3fe4b23eaebd869b1538735a1954a.zip
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
-rw-r--r--source4/dsdb/config.mk3
-rw-r--r--source4/dsdb/schema/schema_convert_to_ol.c (renamed from source4/utils/ad2oLschema.c)262
-rw-r--r--source4/dsdb/schema/schema_set.c2
-rw-r--r--source4/scripting/python/pyglue.c31
-rw-r--r--source4/scripting/python/samba/provision.py22
-rw-r--r--source4/scripting/python/samba/samdb.py5
-rw-r--r--source4/utils/config.mk13
7 files changed, 113 insertions, 225 deletions
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/utils/ad2oLschema.c b/source4/dsdb/schema/schema_convert_to_ol.c
index 236b1fa350..375e4e3810 100644
--- a/source4/utils/ad2oLschema.c
+++ b/source4/dsdb/schema/schema_convert_to_ol.c
@@ -1,124 +1,50 @@
/*
- ldb database library
+ schema conversion routines
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 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 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,
+ 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
- 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 <http://www.gnu.org/licenses/>.
+ 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 <http://www.gnu.org/licenses/>.
+
*/
-/*
- * 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"
+#include "system/locale.h"
-struct schema_conv {
- int count;
- int skipped;
- int failures;
-};
-
+/* Routine to linearise our internal schema into the format that
+ OpenLDAP and Fedora DS use for their backend.
-static void usage(void)
-{
- printf("Usage: ad2oLschema <options>\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);
-}
+ The 'mappings' are of a format like:
-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;
- }
+#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
- 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)
+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 {
@@ -133,19 +59,31 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
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;
+ enum dsdb_schema_convert_target target;
+
+ char *next_line = talloc_strdup(mem_ctx, mappings);
- int ldb_ret;
+ 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;
+ }
- ret.count = 0;
- ret.skipped = 0;
- ret.failures = 0;
+ /* 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++;
- while ((line = afdgets(fileno(in), mem_ctx, 0))) {
/* Blank Line */
if (line[0] == '\0') {
continue;
@@ -154,17 +92,18 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
if (line[0] == '#') {
continue;
}
+
if (isdigit(line[0])) {
char *p = strchr(line, ':');
if (!p) {
- ret.failures++;
- return ret;
+ 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_move(oid_map, &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++;
@@ -177,7 +116,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
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);
+ 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++;
@@ -186,36 +125,26 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
/* 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);
+ attrs_skip[num_skip] = talloc_strdup(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;
+ 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 ";
- fprintf(out, "dn: cn=schema\n");
+ out = talloc_strdup(mem_ctx, "dn: cn=schema\n");
break;
}
@@ -231,7 +160,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
/* We have been asked to skip some attributes/objectClasses */
if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
- ret.skipped++;
continue;
}
@@ -283,19 +211,18 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
false, false);
if (schema_entry == NULL) {
- ret.failures++;
- return ret;
+ DEBUG(0, ("failed to generate attribute description for %s\n", name));
+ return NULL;
}
switch (target) {
case TARGET_OPENLDAP:
- fprintf(out, "attributetype %s\n\n", schema_entry);
+ out = talloc_asprintf_append(out, "attributetype %s\n\n", schema_entry);
break;
case TARGET_FEDORA_DS:
- fprintf(out, "attributeTypes: %s\n", schema_entry);
+ out = talloc_asprintf_append(out, "attributeTypes: %s\n", schema_entry);
break;
}
- ret.count++;
}
/* This is already sorted to have 'top' and similar classes first */
@@ -316,7 +243,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
/* We have been asked to skip some attributes/objectClasses */
if (attrs_skip && str_list_check_ci(attrs_skip, name)) {
- ret.skipped++;
continue;
}
@@ -371,72 +297,20 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
may,
NULL);
if (schema_entry == NULL) {
- ret.failures++;
- return ret;
+ DEBUG(0, ("failed to generate schema description for %s\n", name));
+ return NULL;
}
switch (target) {
case TARGET_OPENLDAP:
- fprintf(out, "objectclass %s\n\n", schema_entry);
+ out = talloc_asprintf_append(out, "objectclass %s\n\n", schema_entry);
break;
case TARGET_FEDORA_DS:
- fprintf(out, "objectClasses: %s\n", schema_entry);
+ out = talloc_asprintf_append(out, "objectClasses: %s\n", schema_entry);
break;
}
- ret.count++;
}
- return ret;
+ return out;
}
- 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/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/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
-