summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packaging/Fedora/samba4.spec4
-rw-r--r--source4/Makefile4
-rw-r--r--source4/VERSION4
-rw-r--r--source4/dsdb/repl/drepl_out_helpers.c12
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c5
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c172
-rw-r--r--source4/dsdb/samdb/samdb.h5
-rw-r--r--source4/dsdb/schema/schema.h5
-rw-r--r--source4/dsdb/schema/schema_init.c142
-rw-r--r--source4/ldap_server/ldap_backend.c2
-rw-r--r--source4/lib/ldb/config.mk27
-rw-r--r--source4/libnet/libnet_become_dc.c12
-rw-r--r--source4/librpc/idl/drsuapi.idl30
-rw-r--r--source4/torture/rpc/drsuapi.c12
-rw-r--r--source4/torture/rpc/dssync.c12
-rw-r--r--source4/utils/ad2oLschema.1.xml87
-rw-r--r--source4/utils/ad2oLschema.c (renamed from source4/lib/ldb/tools/ad2oLschema.c)204
-rw-r--r--source4/utils/config.mk28
-rw-r--r--source4/utils/oLschema2ldif.1.xml79
-rw-r--r--source4/utils/oLschema2ldif.c (renamed from source4/lib/ldb/tools/oLschema2ldif.c)2
-rw-r--r--source4/utils/schema_convert.c (renamed from source4/lib/ldb/tools/convert.c)2
-rw-r--r--source4/utils/schema_convert.h (renamed from source4/lib/ldb/tools/convert.h)0
22 files changed, 616 insertions, 234 deletions
diff --git a/packaging/Fedora/samba4.spec b/packaging/Fedora/samba4.spec
index 567d89bd5d..4e86050dcf 100644
--- a/packaging/Fedora/samba4.spec
+++ b/packaging/Fedora/samba4.spec
@@ -61,6 +61,8 @@ Summary: Samba libraries
Group: Applications/System
Requires: libtdb >= 0:%{tdb_version}
Requires: libtalloc >= 0:%{talloc_version}
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
%description libs
The %{name}-libs package contains the libraries needed by programs
@@ -76,7 +78,7 @@ The %{name}-python package contains the python libraries needed by programs
that use SMB, RPC and other Samba provided protocols in python programs/
%package devel
-Summary: Developor tools for Samba libraries
+Summary: Developer tools for Samba libraries
Group: Development/Libraries
Requires: %{name}-libs = %{epoch}:%{version}-%{release}
diff --git a/source4/Makefile b/source4/Makefile
index 93c6f4575d..fba06ccfa9 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -199,6 +199,8 @@ installdirs::
$(DESTDIR)$(modulesdir) \
$(DESTDIR)$(mandir) \
$(DESTDIR)$(localstatedir) \
+ $(DESTDIR)$(localstatedir)/lib \
+ $(DESTDIR)$(localstatedir)/run \
$(DESTDIR)$(privatedir) \
$(DESTDIR)$(datadir) \
$(DESTDIR)$(piddir) \
@@ -207,7 +209,7 @@ installdirs::
$(DESTDIR)$(privatedir)/tls \
$(DESTDIR)$(includedir) \
$(DESTDIR)$(PKGCONFIGDIR) \
- $(DESTDIR)$(sysconfdir) \
+ $(DESTDIR)$(sysconfdir)
installbin:: $(SBIN_PROGS) $(BIN_PROGS) $(TORTURE_PROGS) installdirs
@$(SHELL) $(srcdir)/script/installtorture.sh \
diff --git a/source4/VERSION b/source4/VERSION
index cd9968a4ef..272086492c 100644
--- a/source4/VERSION
+++ b/source4/VERSION
@@ -57,7 +57,7 @@ SAMBA_VERSION_TP_RELEASE=
# e.g. SAMBA_VERSION_ALPHA_RELEASE=1 #
# -> "4.0.0alpha1" #
########################################################
-SAMBA_VERSION_ALPHA_RELEASE=5
+SAMBA_VERSION_ALPHA_RELEASE=6
########################################################
# For 'pre' releases the version will be #
@@ -89,7 +89,7 @@ SAMBA_VERSION_RC_RELEASE=
# e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes #
# -> "3.0.0-SVN-build-199" #
########################################################
-SAMBA_VERSION_IS_GIT_SNAPSHOT=no
+SAMBA_VERSION_IS_GIT_SNAPSHOT=yes
########################################################
# This is for specifying a release nickname #
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index aede6e6595..d79d94fc12 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -253,10 +253,10 @@ static void dreplsrv_op_pull_source_get_changes_send(struct dreplsrv_op_pull_sou
r->in.req.req8.replica_flags = rf1->replica_flags;
r->in.req.req8.max_object_count = 133;
r->in.req.req8.max_ndr_size = 1336811;
- r->in.req.req8.unknown4 = 0;
- r->in.req.req8.h1 = 0;
- r->in.req.req8.unique_ptr1 = 0;
- r->in.req.req8.unique_ptr2 = 0;
+ r->in.req.req8.extended_op = DRSUAPI_EXOP_NONE;
+ r->in.req.req8.fsmo_info = 0;
+ r->in.req.req8.partial_attribute_set = NULL;
+ r->in.req.req8.partial_attribute_set_ex = NULL;
r->in.req.req8.mapping_ctr.num_mappings = 0;
r->in.req.req8.mapping_ctr.mappings = NULL;
} else {
@@ -269,8 +269,8 @@ static void dreplsrv_op_pull_source_get_changes_send(struct dreplsrv_op_pull_sou
r->in.req.req5.replica_flags = rf1->replica_flags;
r->in.req.req5.max_object_count = 133;
r->in.req.req5.max_ndr_size = 1336770;
- r->in.req.req5.unknown4 = 0;
- r->in.req.req5.h1 = 0;
+ r->in.req.req5.extended_op = DRSUAPI_EXOP_NONE;
+ r->in.req.req5.fsmo_info = 0;
}
req = dcerpc_drsuapi_DsGetNCChanges_send(drsuapi->pipe, r, r);
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 50f333d095..75f99a139d 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -164,14 +164,11 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
}
if (do_attribute_explicit(attrs, "validFSMOs")) {
- const struct dsdb_schema_fsmo *schema_fsmo;
const struct dsdb_naming_fsmo *naming_fsmo;
const struct dsdb_pdc_fsmo *pdc_fsmo;
const char *dn_str;
- schema_fsmo = talloc_get_type(ldb_get_opaque(module->ldb, "dsdb_schema_fsmo"),
- struct dsdb_schema_fsmo);
- if (schema_fsmo && schema_fsmo->we_are_master) {
+ if (schema && schema->fsmo.we_are_master) {
dn_str = ldb_dn_get_linearized(samdb_schema_dn(module->ldb));
if (dn_str && dn_str[0]) {
if (ldb_msg_add_fmt(msg, "validFSMOs", "%s", dn_str) != 0) {
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index 8ceeba9804..6f65c199ba 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -34,18 +34,13 @@
static int schema_fsmo_init(struct ldb_module *module)
{
- WERROR status;
TALLOC_CTX *mem_ctx;
struct ldb_dn *schema_dn;
struct dsdb_schema *schema;
- struct dsdb_schema_fsmo *schema_fsmo;
struct ldb_result *schema_res;
- const struct ldb_val *prefix_val;
- const struct ldb_val *info_val;
- struct ldb_val info_val_default;
struct ldb_result *a_res;
struct ldb_result *c_res;
- uint32_t i;
+ char *error_string = NULL;
int ret;
static const char *schema_attrs[] = {
"prefixMap",
@@ -72,19 +67,6 @@ static int schema_fsmo_init(struct ldb_module *module)
return LDB_ERR_OPERATIONS_ERROR;
}
- schema_fsmo = talloc_zero(mem_ctx, struct dsdb_schema_fsmo);
- if (!schema_fsmo) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- module->private_data = schema_fsmo;
-
- schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(module->ldb, "loadparm")));
- if (!schema) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
/*
* setup the prefix mappings and schema info
*/
@@ -119,33 +101,6 @@ static int schema_fsmo_init(struct ldb_module *module)
return LDB_ERR_CONSTRAINT_VIOLATION;
}
- prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap");
- if (!prefix_val) {
- ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
- "schema_fsmo_init: no prefixMap attribute found");
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
- info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo");
- if (!info_val) {
- info_val_default = strhex_to_data_blob("FF0000000000000000000000000000000000000000");
- if (!info_val_default.data) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- talloc_steal(mem_ctx, info_val_default.data);
- info_val = &info_val_default;
- }
-
- status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val);
- if (!W_ERROR_IS_OK(status)) {
- ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
- "schema_fsmo_init: failed to load oid mappings: %s",
- win_errstr(status));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
/*
* load the attribute definitions
*/
@@ -162,29 +117,6 @@ static int schema_fsmo_init(struct ldb_module *module)
}
talloc_steal(mem_ctx, a_res);
- for (i=0; i < a_res->count; i++) {
- struct dsdb_attribute *sa;
-
- sa = talloc_zero(schema, struct dsdb_attribute);
- if (!sa) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- status = dsdb_attribute_from_ldb(schema, a_res->msgs[i], sa, sa);
- if (!W_ERROR_IS_OK(status)) {
- ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
- "schema_fsmo_init: failed to load attriute definition: %s:%s",
- ldb_dn_get_linearized(a_res->msgs[i]->dn),
- win_errstr(status));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
- }
- talloc_free(a_res);
-
/*
* load the objectClass definitions
*/
@@ -201,29 +133,17 @@ static int schema_fsmo_init(struct ldb_module *module)
}
talloc_steal(mem_ctx, c_res);
- for (i=0; i < c_res->count; i++) {
- struct dsdb_class *sc;
-
- sc = talloc_zero(schema, struct dsdb_class);
- if (!sc) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- status = dsdb_class_from_ldb(schema, c_res->msgs[i], sc, sc);
- if (!W_ERROR_IS_OK(status)) {
- ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
- "schema_fsmo_init: failed to load class definition: %s:%s",
- ldb_dn_get_linearized(c_res->msgs[i]->dn),
- win_errstr(status));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
-
- DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+ 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;
}
- talloc_free(c_res);
-
+
/* dsdb_set_schema() steal schema into the ldb_context */
ret = dsdb_set_schema(module->ldb, schema);
if (ret != LDB_SUCCESS) {
@@ -234,29 +154,69 @@ static int schema_fsmo_init(struct ldb_module *module)
return ret;
}
- schema_fsmo->master_dn = ldb_msg_find_attr_as_dn(module->ldb, schema_fsmo, schema_res->msgs[0], "fSMORoleOwner");
- if (ldb_dn_compare(samdb_ntds_settings_dn(module->ldb), schema_fsmo->master_dn) == 0) {
- schema_fsmo->we_are_master = true;
- } else {
- schema_fsmo->we_are_master = false;
+ talloc_free(mem_ctx);
+ return ldb_next_init(module);
+}
+
+static int schema_fsmo_add(struct ldb_module *module, struct ldb_request *req)
+{
+ struct dsdb_schema *schema;
+ const char *attributeID = NULL;
+ const char *governsID = NULL;
+ const char *oid_attr = NULL;
+ const char *oid = NULL;
+ uint32_t id32;
+ WERROR status;
+
+ schema = dsdb_get_schema(module->ldb);
+ if (!schema) {
+ return ldb_next_request(module, req);
+ }
+
+ if (!schema->fsmo.we_are_master) {
+ ldb_debug_set(module->ldb, LDB_DEBUG_ERROR,
+ "schema_fsmo_add: we are not master: reject request\n");
+ return LDB_ERR_UNWILLING_TO_PERFORM;
}
- if (ldb_set_opaque(module->ldb, "dsdb_schema_fsmo", schema_fsmo) != LDB_SUCCESS) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ attributeID = samdb_result_string(req->op.add.message, "attributeID", NULL);
+ governsID = samdb_result_string(req->op.add.message, "governsID", NULL);
+
+ if (attributeID) {
+ oid_attr = "attributeID";
+ oid = attributeID;
+ } else if (governsID) {
+ oid_attr = "governsID";
+ oid = governsID;
}
- talloc_steal(module, schema_fsmo);
+ if (!oid) {
+ return ldb_next_request(module, req);
+ }
- ldb_debug(module->ldb, LDB_DEBUG_TRACE,
- "schema_fsmo_init: we are master: %s\n",
- (schema_fsmo->we_are_master?"yes":"no"));
+ status = dsdb_map_oid2int(schema, oid, &id32);
+ if (W_ERROR_IS_OK(status)) {
+ return ldb_next_request(module, req);
+ } else if (!W_ERROR_EQUAL(WERR_DS_NO_MSDS_INTID, status)) {
+ ldb_debug_set(module->ldb, LDB_DEBUG_ERROR,
+ "schema_fsmo_add: failed to map %s[%s]: %s\n",
+ oid_attr, oid, win_errstr(status));
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
- talloc_free(mem_ctx);
- return ldb_next_init(module);
+ status = dsdb_create_prefix_mapping(module->ldb, schema, oid);
+ if (!W_ERROR_IS_OK(status)) {
+ ldb_debug_set(module->ldb, LDB_DEBUG_ERROR,
+ "schema_fsmo_add: failed to create prefix mapping for %s[%s]: %s\n",
+ oid_attr, oid, win_errstr(status));
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
+
+ return ldb_next_request(module, req);
}
_PUBLIC_ const struct ldb_module_ops ldb_schema_fsmo_module_ops = {
.name = "schema_fsmo",
- .init_context = schema_fsmo_init
+ .init_context = schema_fsmo_init,
+ .add = schema_fsmo_add
};
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 8370857aba..75aa819ccd 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -80,11 +80,6 @@ struct dsdb_extended_replicated_objects {
struct dsdb_extended_replicated_object *objects;
};
-struct dsdb_schema_fsmo {
- bool we_are_master;
- struct ldb_dn *master_dn;
-};
-
struct dsdb_naming_fsmo {
bool we_are_master;
struct ldb_dn *master_dn;
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index bb34235465..6fce354f7c 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -150,6 +150,11 @@ struct dsdb_schema {
struct dsdb_attribute *attributes;
struct dsdb_class *classes;
+ struct {
+ bool we_are_master;
+ struct ldb_dn *master_dn;
+ } fsmo;
+
struct smb_iconv_convenience *iconv_convenience;
};
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index c046cb597f..826f91b5f0 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -334,6 +334,29 @@ WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CT
return WERR_DS_NO_MSDS_INTID;
}
+/*
+ * this function is called from within a ldb transaction from the schema_fsmo module
+ */
+WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *schema, const char *full_oid)
+{
+ /*
+ * TODO:
+ * - (maybe) read the old prefixMap attribute and parse it
+ *
+ * - recheck the prefix doesn't exist (because the ldb
+ * has maybe a more uptodate value than schem->prefixes
+ *
+ * - calculate a new mapping for the oid prefix of full_oid
+ * - store the new prefixMap attribute
+ *
+ * - (maybe) update schema->prefixes
+ * or
+ * - better find a way to indicate a schema reload,
+ * so that other processes also notice the schema change
+ */
+ return WERR_NOT_SUPPORTED;
+}
+
#define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
(p)->elem = samdb_result_string(msg, attr, NULL);\
if (strict && (p)->elem == NULL) { \
@@ -512,9 +535,8 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, true);
- obj->systemAuxiliaryClass = NULL;
-
- obj->auxiliaryClass = NULL;
+ GET_STRING_LIST_LDB(msg, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass, false);
+ GET_STRING_LIST_LDB(msg, "auxiliaryClass", mem_ctx, obj, auxiliaryClass, false);
GET_STRING_LIST_LDB(msg, "systemMustContain", mem_ctx, obj, systemMustContain, false);
GET_STRING_LIST_LDB(msg, "systemMayContain", mem_ctx, obj, systemMayContain, false);
@@ -541,6 +563,114 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
return WERR_OK;
}
+#define dsdb_oom(error_string, mem_ctx) *error_string = talloc_asprintf(mem_ctx, "dsdb out of memory at %s:%d\n", __FILE__, __LINE__)
+
+int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct ldb_result *schema_res,
+ struct ldb_result *attrs_res, struct ldb_result *objectclass_res,
+ struct dsdb_schema **schema_out,
+ char **error_string)
+{
+ WERROR status;
+ uint32_t i;
+ const struct ldb_val *prefix_val;
+ const struct ldb_val *info_val;
+ struct ldb_val info_val_default;
+ struct dsdb_schema *schema;
+
+ schema = dsdb_new_schema(mem_ctx, iconv_convenience);
+ if (!schema) {
+ dsdb_oom(error_string, mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap");
+ if (!prefix_val) {
+ *error_string = talloc_asprintf(mem_ctx,
+ "schema_fsmo_init: no prefixMap attribute found");
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+ info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo");
+ if (!info_val) {
+ info_val_default = strhex_to_data_blob("FF0000000000000000000000000000000000000000");
+ if (!info_val_default.data) {
+ dsdb_oom(error_string, mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ talloc_steal(mem_ctx, info_val_default.data);
+ info_val = &info_val_default;
+ }
+
+ status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val);
+ if (!W_ERROR_IS_OK(status)) {
+ *error_string = talloc_asprintf(mem_ctx,
+ "schema_fsmo_init: failed to load oid mappings: %s",
+ win_errstr(status));
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ for (i=0; i < attrs_res->count; i++) {
+ struct dsdb_attribute *sa;
+
+ sa = talloc_zero(schema, struct dsdb_attribute);
+ if (!sa) {
+ dsdb_oom(error_string, mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ 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",
+ ldb_dn_get_linearized(attrs_res->msgs[i]->dn),
+ win_errstr(status));
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
+ }
+
+ for (i=0; i < objectclass_res->count; i++) {
+ struct dsdb_class *sc;
+
+ sc = talloc_zero(schema, struct dsdb_class);
+ if (!sc) {
+ dsdb_oom(error_string, mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i], sc, sc);
+ if (!W_ERROR_IS_OK(status)) {
+ *error_string = talloc_asprintf(mem_ctx,
+ "schema_fsmo_init: failed to load class definition: %s:%s",
+ ldb_dn_get_linearized(objectclass_res->msgs[i]->dn),
+ win_errstr(status));
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
+ DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+ }
+
+ schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner");
+ if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), schema->fsmo.master_dn) == 0) {
+ schema->fsmo.we_are_master = true;
+ } else {
+ schema->fsmo.we_are_master = false;
+ }
+
+ DEBUG(5, ("schema_fsmo_init: we are master: %s\n",
+ (schema->fsmo.we_are_master?"yes":"no")));
+
+ *schema_out = schema;
+ return LDB_SUCCESS;
+}
+
+
static const struct {
const char *name;
const char *oid;
@@ -1164,6 +1294,12 @@ WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf
schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")));
+ schema->fsmo.we_are_master = true;
+ schema->fsmo.master_dn = ldb_dn_new_fmt(schema, ldb, "@PROVISION_SCHEMA_MASTER");
+ if (!schema->fsmo.master_dn) {
+ goto nomem;
+ }
+
/*
* load the prefixMap attribute from pf
*/
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 9047773529..2193c989cf 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -348,7 +348,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn, 1);
+ VALID_DN_SYNTAX(dn, 0);
DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk
index 6821c058f2..fe3b71d1d5 100644
--- a/source4/lib/ldb/config.mk
+++ b/source4/lib/ldb/config.mk
@@ -147,32 +147,5 @@ PRIVATE_DEPENDENCIES = \
ldbtest_OBJ_FILES = $(ldbsrcdir)/tools/ldbtest.o
-################################################
-# Start BINARY oLschema2ldif
-[BINARY::oLschema2ldif]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY oLschema2ldif
-################################################
-
-
-oLschema2ldif_OBJ_FILES = $(addprefix $(ldbsrcdir)/tools/, convert.o oLschema2ldif.o)
-
-MANPAGES += $(ldbsrcdir)/man/oLschema2ldif.1
-
-################################################
-# Start BINARY ad2oLschema
-[BINARY::ad2oLschema]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBLDB_CMDLINE
-# End BINARY ad2oLschema
-################################################
-
-ad2oLschema_OBJ_FILES = $(addprefix $(ldbsrcdir)/tools/, convert.o ad2oLschema.o)
-
-MANPAGES += $(ldbsrcdir)/man/ad2oLschema.1
-
mkinclude tools/config.mk
mkinclude ldb_ildap/config.mk
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index 1c4c1d0732..d3eeebe214 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -2392,10 +2392,10 @@ static void becomeDC_drsuapi_pull_partition_send(struct libnet_BecomeDC_state *s
r->in.req.req8.replica_flags = partition->replica_flags;
r->in.req.req8.max_object_count = 133;
r->in.req.req8.max_ndr_size = 1336811;
- r->in.req.req8.unknown4 = 0;
- r->in.req.req8.h1 = 0;
- r->in.req.req8.unique_ptr1 = 0;
- r->in.req.req8.unique_ptr2 = 0;
+ r->in.req.req8.extended_op = DRSUAPI_EXOP_NONE;
+ r->in.req.req8.fsmo_info = 0;
+ r->in.req.req8.partial_attribute_set = NULL;
+ r->in.req.req8.partial_attribute_set_ex = NULL;
r->in.req.req8.mapping_ctr.num_mappings = 0;
r->in.req.req8.mapping_ctr.mappings = NULL;
} else {
@@ -2408,8 +2408,8 @@ static void becomeDC_drsuapi_pull_partition_send(struct libnet_BecomeDC_state *s
r->in.req.req5.replica_flags = partition->replica_flags;
r->in.req.req5.max_object_count = 133;
r->in.req.req5.max_ndr_size = 1336770;
- r->in.req.req5.unknown4 = 0;
- r->in.req.req5.h1 = 0;
+ r->in.req.req5.extended_op = DRSUAPI_EXOP_NONE;
+ r->in.req.req5.fsmo_info = 0;
}
/*
diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl
index 2f48287233..6701d22a63 100644
--- a/source4/librpc/idl/drsuapi.idl
+++ b/source4/librpc/idl/drsuapi.idl
@@ -230,6 +230,17 @@ interface drsuapi
DRSUAPI_DS_REPLICA_NEIGHBOUR_PARTIAL_ATTRIBUTE_SET = 0x40000000
} drsuapi_DsReplicaNeighbourFlags;
+ typedef [flag(NDR_PAHEX),v1_enum] enum {
+ DRSUAPI_EXOP_NONE = 0x00000000,
+ DRSUAPI_EXOP_FSMO_REQ_ROLE = 0x00000001,
+ DRSUAPI_EXOP_FSMO_RID_ALLOC = 0x00000002,
+ DRSUAPI_EXOP_FSMO_RID_REQ_ROLE = 0x00000003,
+ DRSUAPI_EXOP_FSMO_REQ_PDC = 0x00000004,
+ DRSUAPI_EXOP_FSMO_ABANDON_ROLE = 0x00000005,
+ DRSUAPI_EXOP_REPL_OBJ = 0x00000006,
+ DRSUAPI_EXOP_REPL_SECRET = 0x00000007
+ } drsuapi_DsExtendedOperation;
+
typedef struct {
GUID destination_dsa_guid;
GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */
@@ -239,8 +250,8 @@ interface drsuapi
drsuapi_DsReplicaNeighbourFlags replica_flags;
uint32 max_object_count; /* w2k3 uses min(133,max(100,max_object_count)) */
uint32 max_ndr_size; /* w2k3 seems to ignore this */
- uint32 unknown4;
- hyper h1;
+ drsuapi_DsExtendedOperation extended_op;
+ hyper fsmo_info;
} drsuapi_DsGetNCChangesRequest5;
/*
@@ -401,6 +412,13 @@ interface drsuapi
} drsuapi_DsAttributeId;
typedef struct {
+ [value(1)] uint32 version;
+ [value(0)] uint32 reserved1;
+ [range(1,0x100000)] uint32 num_attids;
+ [size_is(num_attids)] drsuapi_DsAttributeId attids[];
+ } drsuapi_DsPartialAttributeSet;
+
+ typedef struct {
GUID destination_dsa_guid;
GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */
[ref] drsuapi_DsReplicaObjectIdentifier *naming_context;
@@ -409,10 +427,10 @@ interface drsuapi
drsuapi_DsReplicaNeighbourFlags replica_flags;
uint32 max_object_count; /* w2k3 uses min(133,max(100,max_object_count)) */
uint32 max_ndr_size; /* w2k3 seems to ignore this */
- uint32 unknown4;
- hyper h1;
- uint32 unique_ptr1;
- uint32 unique_ptr2;
+ drsuapi_DsExtendedOperation extended_op;
+ hyper fsmo_info;
+ drsuapi_DsPartialAttributeSet *partial_attribute_set;
+ drsuapi_DsPartialAttributeSet *partial_attribute_set_ex;
drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr;
} drsuapi_DsGetNCChangesRequest8;
diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c
index bbdb73ed55..e5cb3d7ddf 100644
--- a/source4/torture/rpc/drsuapi.c
+++ b/source4/torture/rpc/drsuapi.c
@@ -549,8 +549,8 @@ static bool test_DsGetNCChanges(struct dcerpc_pipe *p, struct torture_context *t
}
r.in.req.req5.max_object_count = 0;
r.in.req.req5.max_ndr_size = 0;
- r.in.req.req5.unknown4 = 0;
- r.in.req.req5.h1 = 0;
+ r.in.req.req5.extended_op = DRSUAPI_EXOP_NONE;
+ r.in.req.req5.fsmo_info = 0;
break;
case 8:
@@ -579,10 +579,10 @@ static bool test_DsGetNCChanges(struct dcerpc_pipe *p, struct torture_context *t
;
r.in.req.req8.max_object_count = 402;
r.in.req.req8.max_ndr_size = 402116;
- r.in.req.req8.unknown4 = 0;
- r.in.req.req8.h1 = 0;
- r.in.req.req8.unique_ptr1 = 0;
- r.in.req.req8.unique_ptr2 = 0;
+ r.in.req.req8.extended_op = DRSUAPI_EXOP_NONE;
+ r.in.req.req8.fsmo_info = 0;
+ r.in.req.req8.partial_attribute_set = NULL;
+ r.in.req.req8.partial_attribute_set_ex = NULL;
r.in.req.req8.mapping_ctr.num_mappings = 0;
r.in.req.req8.mapping_ctr.mappings = NULL;
diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c
index 989a1faf27..ec527687c0 100644
--- a/source4/torture/rpc/dssync.c
+++ b/source4/torture/rpc/dssync.c
@@ -623,8 +623,8 @@ static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx)
;
r.in.req.req5.max_object_count = 133;
r.in.req.req5.max_ndr_size = 1336770;
- r.in.req.req5.unknown4 = 0;
- r.in.req.req5.h1 = 0;
+ r.in.req.req5.extended_op = DRSUAPI_EXOP_NONE;
+ r.in.req.req5.fsmo_info = 0;
break;
case 8:
@@ -655,10 +655,10 @@ static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx)
r.in.req.req8.max_object_count = 402;
r.in.req.req8.max_ndr_size = 402116;
- r.in.req.req8.unknown4 = 0;
- r.in.req.req8.h1 = 0;
- r.in.req.req8.unique_ptr1 = 0;
- r.in.req.req8.unique_ptr2 = 0;
+ r.in.req.req8.extended_op = DRSUAPI_EXOP_NONE;
+ r.in.req.req8.fsmo_info = 0;
+ r.in.req.req8.partial_attribute_set = NULL;
+ r.in.req.req8.partial_attribute_set_ex = NULL;
r.in.req.req8.mapping_ctr.num_mappings = 0;
r.in.req.req8.mapping_ctr.mappings = NULL;
diff --git a/source4/utils/ad2oLschema.1.xml b/source4/utils/ad2oLschema.1.xml
new file mode 100644
index 0000000000..6ae8996477
--- /dev/null
+++ b/source4/utils/ad2oLschema.1.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<refentry id="ad2oLschema.1">
+
+<refmeta>
+ <refentrytitle>ad2oLschema</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>ad2oLschema</refname>
+ <refpurpose>Converts AC-like LDAP schemas to OpenLDAP
+ compatible schema files</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ad2oLschema</command>
+ <arg choice="opt">-I INPUT-FILE</arg>
+ <arg choice="opt">-O OUTPUT-FILE</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>ad2oLschema is a simple tool that converts AD-like LDIF
+ schema files into OpenLDAP schema files.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-H url</term>
+ <listitem><para>URL to an LDB or LDAP server with an AD schema to read. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I input-file</term> <listitem><para>AD schema
+ to read. If neither this nor -H is specified, the
+ schema file will be read from standard input.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-O output-file</term>
+ <listitem><para>File to write OpenLDAP version of schema to.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 4.0 of the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+
+ <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
+
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para> ldb was written by
+ <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
+ ad2oLschema was written by <ulink
+ url="http://samba.org/~abartlet/">Andrew Bartlett</ulink>.
+ </para>
+
+ <para>
+If you wish to report a problem or make a suggestion then please see
+the <ulink url="http://ldb.samba.org/"/> web site for
+current contact and maintainer information.
+ </para>
+
+</refsect1>
+
+</refentry>
diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/utils/ad2oLschema.c
index ac343c783f..879b1a7213 100644
--- a/source4/lib/ldb/tools/ad2oLschema.c
+++ b/source4/utils/ad2oLschema.c
@@ -34,10 +34,11 @@
#include "includes.h"
#include "ldb_includes.h"
#include "system/locale.h"
-#include "tools/cmdline.h"
-#include "tools/convert.h"
+#include "lib/ldb/tools/cmdline.h"
+#include "utils/schema_convert.h"
#include "param/param.h"
#include "lib/cmdline/popt_common.h"
+#include "dsdb/samdb/samdb.h"
struct schema_conv {
int count;
@@ -70,25 +71,12 @@ 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);
int ret;
- const char *attrs[] = {
- "lDAPDisplayName",
- "isSingleValued",
- "attributeID",
- "attributeSyntax",
- "description",
- NULL
- };
- if (!local_ctx) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
/* Downlaod schema */
ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
"objectClass=attributeSchema",
- attrs, attrs_res);
+ NULL, attrs_res);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
@@ -97,19 +85,6 @@ static int fetch_attrs_schema(struct ldb_context *ldb, struct ldb_dn *schemadn,
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,
@@ -123,7 +98,7 @@ static int fetch_oc_recursive(struct ldb_context *ldb, struct ldb_dn *schemadn,
"lDAPDisplayname", NULL);
ret = ldb_search_exp_fmt(ldb, mem_ctx, &res,
- schemadn, LDB_SCOPE_SUBTREE, oc_attrs,
+ schemadn, LDB_SCOPE_SUBTREE, NULL,
"(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))",
name, name);
if (ret != LDB_SUCCESS) {
@@ -165,7 +140,7 @@ static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *sche
/* Downlaod 'top' */
ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE,
"(&(objectClass=classSchema)(lDAPDisplayName=top))",
- oc_attrs, &top_res);
+ NULL, &top_res);
if (ret != LDB_SUCCESS) {
printf("Search failed: %s\n", ldb_errstring(ldb));
return LDB_ERR_OPERATIONS_ERROR;
@@ -193,15 +168,15 @@ static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *sche
return ret;
}
-static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
+static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
+ struct ldb_result **schema_res)
{
const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
- const char *no_attrs[] = { 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;
}
@@ -211,21 +186,20 @@ 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))",
- no_attrs, &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) {
printf("Failed to find rootDSE");
return NULL;
}
- schemadn = talloc_steal(mem_ctx, schema_res->msgs[0]->dn);
- talloc_free(schema_res);
+ schemadn = talloc_steal(mem_ctx, (*schema_res)->msgs[0]->dn);
return schemadn;
}
@@ -243,10 +217,96 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
return NULL;
}
+ 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));
+ 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) { \
ret.failures++; \
@@ -272,9 +332,11 @@ 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 *attrs_res, *objectclasses_res;
+ struct ldb_result *schema_res, *attrs_res, *objectclasses_res;
struct ldb_dn *schemadn;
struct schema_conv ret;
+ struct dsdb_schema *schema;
+ char *error_string;
int ldb_ret, i;
@@ -327,7 +389,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
}
}
- schemadn = find_schema_dn(ldb, mem_ctx);
+ schemadn = find_schema_dn(ldb, mem_ctx, &schema_res);
if (!schemadn) {
printf("Failed to find schema DN: %s\n", ldb_errstring(ldb));
ret.failures = 1;
@@ -340,7 +402,24 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
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);
+ if (ldb_ret != LDB_SUCCESS) {
+ printf("Failed to load schema: %s\n", error_string);
+ ret.failures = 1;
+ return ret;
+ }
+
switch (target) {
case TARGET_OPENLDAP:
break;
@@ -460,13 +539,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
ret.count++;
}
- 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++) {
struct ldb_message *msg = objectclasses_res->msgs[i];
const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL);
@@ -478,6 +550,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
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");
char *schema_entry = NULL;
int j;
@@ -493,6 +567,32 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
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);
+ }
+
+ 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;
+ }
+
/* 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) {
@@ -594,13 +694,13 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
} \
} while (0)
- if (must || sys_must) {
+ if ((must && must->values) || (sys_must && sys_must->values)) {
schema_entry = talloc_asprintf_append(schema_entry,
" MUST (");
IF_NULL_FAIL_RET(schema_entry);
APPEND_ATTRS(must);
- if (must && sys_must) {
+ if (must && must->values && sys_must && sys_must->values) {
schema_entry = talloc_asprintf_append(schema_entry, \
" $"); \
}
@@ -611,13 +711,13 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_
IF_NULL_FAIL_RET(schema_entry);
}
- if (may || sys_may) {
+ if ((may && may->values) || (sys_may && sys_may->values)) {
schema_entry = talloc_asprintf_append(schema_entry,
" MAY (");
IF_NULL_FAIL_RET(schema_entry);
APPEND_ATTRS(may);
- if (may && sys_may) {
+ if (may && may->values && sys_may && sys_may->values) {
schema_entry = talloc_asprintf_append(schema_entry, \
" $"); \
}
diff --git a/source4/utils/config.mk b/source4/utils/config.mk
index d47b36ea7c..61565807d2 100644
--- a/source4/utils/config.mk
+++ b/source4/utils/config.mk
@@ -94,3 +94,31 @@ PRIVATE_DEPENDENCIES = \
#################################
testparm_OBJ_FILES = $(utilssrcdir)/testparm.o
+
+################################################
+# Start BINARY oLschema2ldif
+[BINARY::oLschema2ldif]
+INSTALLDIR = BINDIR
+PRIVATE_DEPENDENCIES = \
+ LIBLDB_CMDLINE
+# End BINARY oLschema2ldif
+################################################
+
+
+oLschema2ldif_OBJ_FILES = $(addprefix $(utilssrcdir)/, schema_convert.o 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)/, schema_convert.o ad2oLschema.o)
+
+MANPAGES += $(utilssrcdir)/man/ad2oLschema.1
+
diff --git a/source4/utils/oLschema2ldif.1.xml b/source4/utils/oLschema2ldif.1.xml
new file mode 100644
index 0000000000..b1e681be4e
--- /dev/null
+++ b/source4/utils/oLschema2ldif.1.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<refentry id="oLschema2ldif.1">
+
+<refmeta>
+ <refentrytitle>oLschema2ldif</refentrytitle>
+ <manvolnum>1</manvolnum>
+</refmeta>
+
+
+<refnamediv>
+ <refname>oLschema2ldif</refname>
+ <refpurpose>Converts LDAP schema's to LDB-compatible LDIF</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>oLschema2ldif</command>
+ <arg choice="opt">-I INPUT-FILE</arg>
+ <arg choice="opt">-O OUTPUT-FILE</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>oLschema2ldif is a simple tool that converts standard OpenLDAP schema files to a LDIF format that is understood by LDB.</para>
+</refsect1>
+
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-I input-file</term>
+ <listitem><para>OpenLDAP schema to read. If none are specified,
+the schema file will be read from standard input.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-O output-file</term>
+ <listitem><para>File to write ldif version of schema to.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 4.0 of the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+ <title>SEE ALSO</title>
+
+ <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
+
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para> ldb was written by
+ <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
+ oLschema2ldif was written by <ulink url="mailto:idra@samba.org">Simo Sorce</ulink>.
+ </para>
+
+ <para>
+If you wish to report a problem or make a suggestion then please see
+the <ulink url="http://ldb.samba.org/"/> web site for
+current contact and maintainer information.
+ </para>
+
+</refsect1>
+
+</refentry>
diff --git a/source4/lib/ldb/tools/oLschema2ldif.c b/source4/utils/oLschema2ldif.c
index 3c31f37c55..b501b75529 100644
--- a/source4/lib/ldb/tools/oLschema2ldif.c
+++ b/source4/utils/oLschema2ldif.c
@@ -33,7 +33,7 @@
#include "ldb_includes.h"
#include "tools/cmdline.h"
-#include "tools/convert.h"
+#include "utils/schema_convert.h"
#define SCHEMA_UNKNOWN 0
#define SCHEMA_NAME 1
diff --git a/source4/lib/ldb/tools/convert.c b/source4/utils/schema_convert.c
index 5a5cf2a94c..a5d38451d4 100644
--- a/source4/lib/ldb/tools/convert.c
+++ b/source4/utils/schema_convert.c
@@ -21,7 +21,7 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "convert.h"
+#include "schema_convert.h"
#include "ldb_includes.h"
/* Shared map for converting syntax between formats */
diff --git a/source4/lib/ldb/tools/convert.h b/source4/utils/schema_convert.h
index de379343a6..de379343a6 100644
--- a/source4/lib/ldb/tools/convert.h
+++ b/source4/utils/schema_convert.h