[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Tue Nov 15 05:01:04 MST 2011


The branch, master has been updated
       via  c1fd56f s4:dsdb/schema_data: reject schema update unless they're allowed
       via  0be0da9 selftest/Samba4: allow schema updates
       via  e7e9f1e s4:dsdb/schema: add "dsdb:schema update allowed" option to enable schema updates
       via  be091ed s4:dsdb/schema_data: reject changes to schemaInfo, msDs-Schema-Extensions, msDS-IntId
       via  38868c8 s4:dsdb/schema_data: make sure we reject schema changes if we're not the schema master
       via  76b99bb s4:dsdb/schema_data: make sure we only allow objects one level below the schema base
       via  6d3558a s4:libnet_vampire: setup base_dn on the self_made_schema
       via  b33c711 s4:libnet_vampire: use dsdb_modify(..., DSDB_FLAG_AS_SYSTEM) to store prefixMap
       via  28d5731 s4:param/provision: pass schema_dn to provision_get_schema()
       via  75ae194 s4:dsdb/schema: pass and remember the schema_dn in dsdb_set_schema_from_ldif()
       via  e6a9e1d s4:dsdb/pydsdb: pass down schema_dn to _dsdb_set_schema_from_ldif()
       via  18eba02 s4:python/samba/schema: pass down the schema_dn to set_from_ldif()
       via  54a9a47 s4:dsdb/samldb: use DSDB_FLAG_AS_SYSTEM in samldb_schema_info_update()
       via  236e6fe s4:libnet: initialize forest structure in py_net_replicate_init()
      from  2611003 samba-tool: Don't set UF_PASSWD_NOTREQD flag on "user disable"

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c1fd56fdd408c814158e9d4eaed58da08db8efc7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 16:55:37 2011 +0100

    s4:dsdb/schema_data: reject schema update unless they're allowed
    
    "dsdb:schema update allowed = yes" is now needed in smb.conf
    to enable schema updates, as schema updates are a currenty a good
    way to prevent samba from startup again, because of errors in
    the schema definition.
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Tue Nov 15 13:00:07 CET 2011 on sn-devel-104

commit 0be0da9650fd3eb6f094854b61e60c35349edb26
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Nov 12 11:03:05 2011 +0100

    selftest/Samba4: allow schema updates
    
    metze

commit e7e9f1e2dd279beaaf9d94b39378d24548a531cd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 12:12:17 2011 +0100

    s4:dsdb/schema: add "dsdb:schema update allowed" option to enable schema updates
    
    By default schema updates are not allowed anymore, as we don't have
    complete validation code to prevent database corruption.
    
    metze

commit be091eddec3715c5807f03fdc3d83ffc5a857433
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 16:43:18 2011 +0100

    s4:dsdb/schema_data: reject changes to schemaInfo, msDs-Schema-Extensions, msDS-IntId
    
    As windows we return CONSTRAINT_VIOLATION now.
    
    metze

commit 38868c8b7f9c099158c62f8c653e10d5ca1c91ac
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 15:54:11 2011 +0100

    s4:dsdb/schema_data: make sure we reject schema changes if we're not the schema master
    
    metze

commit 76b99bb379f2372903288c680e9b9abf85b02e09
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 14:51:32 2011 +0100

    s4:dsdb/schema_data: make sure we only allow objects one level below the schema base
    
    The objectclass module should also check for this, but make sure
    we also reject it on things like provision.
    
    metze

commit 6d3558a8f6f157f5b4232388d675d9353a115632
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 14 09:16:58 2011 +0100

    s4:libnet_vampire: setup base_dn on the self_made_schema
    
    metze

commit b33c711851c4d2b47af5782ed4d58ec2e7d9039c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 14 08:54:18 2011 +0100

    s4:libnet_vampire: use dsdb_modify(..., DSDB_FLAG_AS_SYSTEM) to store prefixMap
    
    metze

commit 28d573168cb869a7c4cf85ad094eba3805676cbd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 14 08:52:51 2011 +0100

    s4:param/provision: pass schema_dn to provision_get_schema()
    
    metze

commit 75ae19422b2b405cabe269c29afb61a1b50636d1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 16:35:59 2011 +0100

    s4:dsdb/schema: pass and remember the schema_dn in dsdb_set_schema_from_ldif()
    
    metze

commit e6a9e1dda920d83c2926061e331d52aa9e9d0871
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 16:34:48 2011 +0100

    s4:dsdb/pydsdb: pass down schema_dn to _dsdb_set_schema_from_ldif()
    
    metze

commit 18eba021e7b7e0b9a6fb228c80bee639965dab33
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 16:32:05 2011 +0100

    s4:python/samba/schema: pass down the schema_dn to set_from_ldif()
    
    metze

commit 54a9a47a9100ffbe185b35f4067b08fc3374205a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 11 15:56:01 2011 +0100

    s4:dsdb/samldb: use DSDB_FLAG_AS_SYSTEM in samldb_schema_info_update()
    
    We should only be able to update the schemaInfo internaly.
    
    metze

commit 236e6fecdad7d224a86b6c4bf789214e31018da1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 15 09:45:46 2011 +0100

    s4:libnet: initialize forest structure in py_net_replicate_init()
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 selftest/target/Samba4.pm                    |    1 +
 source4/dsdb/pydsdb.c                        |    6 +-
 source4/dsdb/samdb/ldb_modules/samldb.c      |    4 +-
 source4/dsdb/samdb/ldb_modules/schema_data.c |  175 +++++++++++++++++++++++++-
 source4/dsdb/schema/schema.h                 |    1 +
 source4/dsdb/schema/schema_init.c            |   17 +++-
 source4/dsdb/schema/schema_set.c             |   15 ++-
 source4/dsdb/schema/tests/schema_syntax.c    |    2 +-
 source4/libnet/libnet_vampire.c              |   11 ++-
 source4/libnet/py_net.c                      |    3 +
 source4/param/provision.c                    |    9 ++-
 source4/param/provision.h                    |    4 +-
 source4/scripting/bin/upgradeprovision       |    7 +-
 source4/scripting/python/samba/schema.py     |    8 +-
 14 files changed, 241 insertions(+), 22 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 017a277..684f68d 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -614,6 +614,7 @@ sub provision_raw_step1($$)
         spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate
         resolv:host file = $ctx->{dns_host_file}
 	dreplsrv:periodic_startup_interval = 0
+	dsdb:schema update allowed = yes
 
         passdb backend = samba4
 
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 57e08cc..3c7c8bf 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -829,16 +829,16 @@ static PyObject *py_dsdb_set_am_rodc(PyObject *self, PyObject *args)
 static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
 {
 	WERROR result;
-	char *pf, *df;
+	char *pf, *df, *dn;
 	PyObject *py_ldb;
 	struct ldb_context *ldb;
 
-	if (!PyArg_ParseTuple(args, "Oss", &py_ldb, &pf, &df))
+	if (!PyArg_ParseTuple(args, "Osss", &py_ldb, &pf, &df, &dn))
 		return NULL;
 
 	PyErr_LDB_OR_RAISE(py_ldb, ldb);
 
-	result = dsdb_set_schema_from_ldif(ldb, pf, df);
+	result = dsdb_set_schema_from_ldif(ldb, pf, df, dn);
 	PyErr_WERROR_IS_ERR_RAISE(result);
 
 	Py_RETURN_NONE;
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 6c14520..d8f68c8 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -803,7 +803,9 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
 	}
 
 	ret = dsdb_module_schema_info_update(ac->module, schema,
-					     DSDB_FLAG_NEXT_MODULE, ac->req);
+					     DSDB_FLAG_NEXT_MODULE|
+					     DSDB_FLAG_AS_SYSTEM,
+					     ac->req);
 	if (ret != LDB_SUCCESS) {
 		ldb_asprintf_errstring(ldb,
 				       "samldb_schema_info_update: dsdb_module_schema_info_update failed with %s",
diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c
index eeb7c46..3e0bb9c 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_data.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_data.c
@@ -139,8 +139,10 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
 	const struct ldb_val *governsID = NULL;
 	const char *oid_attr = NULL;
 	const char *oid = NULL;
+	struct ldb_dn *parent_dn = NULL;
+	int cmp;
 	WERROR status;
-	bool rodc;
+	bool rodc = false;
 	int ret;
 
 	ldb = ldb_module_get_ctx(module);
@@ -160,6 +162,12 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
 		return ldb_next_request(module, req);
 	}
 
+	if (schema->base_dn == NULL) {
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			  "schema_data_add: base_dn NULL\n");
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
 	ret = samdb_rodc(ldb, &rodc);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(4, (__location__ ": unable to tell if we are an RODC \n"));
@@ -171,6 +179,36 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
+	if (!schema->fsmo.update_allowed && !rodc) {
+		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+			  "schema_data_add: updates are not allowed: reject request\n");
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
+	if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID)) {
+		/*
+		 * the provision code needs to create
+		 * the schema root object.
+		 */
+		cmp = ldb_dn_compare(req->op.add.message->dn, schema->base_dn);
+		if (cmp == 0) {
+			return ldb_next_request(module, req);
+		}
+	}
+
+	parent_dn = ldb_dn_get_parent(req, req->op.add.message->dn);
+	if (!parent_dn) {
+		return ldb_oom(ldb);
+	}
+
+	cmp = ldb_dn_compare(parent_dn, schema->base_dn);
+	if (cmp != 0) {
+		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+			  "schema_data_add: no direct child :%s\n",
+			  ldb_dn_get_linearized(req->op.add.message->dn));
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
 	attributeID = ldb_msg_find_ldb_val(req->op.add.message, "attributeID");
 	governsID = ldb_msg_find_ldb_val(req->op.add.message, "governsID");
 
@@ -211,6 +249,139 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req)
 	return ldb_next_request(module, req);
 }
 
+static int schema_data_modify(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb;
+	struct dsdb_schema *schema;
+	int cmp;
+	bool rodc = false;
+	int ret;
+
+	ldb = ldb_module_get_ctx(module);
+
+	/* special objects should always go through */
+	if (ldb_dn_is_special(req->op.mod.message->dn)) {
+		return ldb_next_request(module, req);
+	}
+
+	/* replicated update should always go through */
+	if (ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
+		return ldb_next_request(module, req);
+	}
+
+	/* dbcheck should be able to fix things */
+	if (ldb_request_get_control(req, DSDB_CONTROL_DBCHECK)) {
+		return ldb_next_request(module, req);
+	}
+
+	schema = dsdb_get_schema(ldb, req);
+	if (!schema) {
+		return ldb_next_request(module, req);
+	}
+
+	cmp = ldb_dn_compare(req->op.mod.message->dn, schema->base_dn);
+	if (cmp == 0) {
+		static const char * const constrained_attrs[] = {
+			"schemaInfo",
+			"prefixMap",
+			"msDs-Schema-Extensions",
+			"msDS-IntId",
+			NULL
+		};
+		size_t i;
+		struct ldb_message_element *el;
+
+		if (ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID)) {
+			return ldb_next_request(module, req);
+		}
+
+		for (i=0; constrained_attrs[i]; i++) {
+			el = ldb_msg_find_element(req->op.mod.message,
+						  constrained_attrs[i]);
+			if (el == NULL) {
+				continue;
+			}
+
+			ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+				      "schema_data_modify: reject update "
+				      "of attribute[%s]\n",
+				      constrained_attrs[i]);
+			return LDB_ERR_CONSTRAINT_VIOLATION;
+		}
+
+		return ldb_next_request(module, req);
+	}
+
+	ret = samdb_rodc(ldb, &rodc);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(4, (__location__ ": unable to tell if we are an RODC \n"));
+	}
+
+	if (!schema->fsmo.we_are_master && !rodc) {
+		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+			  "schema_data_modify: we are not master: reject request\n");
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
+	if (!schema->fsmo.update_allowed && !rodc) {
+		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+			  "schema_data_add: updates are not allowed: reject request\n");
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
+	return ldb_next_request(module, req);
+}
+
+static int schema_data_del(struct ldb_module *module, struct ldb_request *req)
+{
+	struct ldb_context *ldb;
+	struct dsdb_schema *schema;
+	bool rodc = false;
+	int ret;
+
+	ldb = ldb_module_get_ctx(module);
+
+	/* special objects should always go through */
+	if (ldb_dn_is_special(req->op.del.dn)) {
+		return ldb_next_request(module, req);
+	}
+
+	/* replicated update should always go through */
+	if (ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
+		return ldb_next_request(module, req);
+	}
+
+	/* dbcheck should be able to fix things */
+	if (ldb_request_get_control(req, DSDB_CONTROL_DBCHECK)) {
+		return ldb_next_request(module, req);
+	}
+
+	schema = dsdb_get_schema(ldb, req);
+	if (!schema) {
+		return ldb_next_request(module, req);
+	}
+
+	ret = samdb_rodc(ldb, &rodc);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(4, (__location__ ": unable to tell if we are an RODC \n"));
+	}
+
+	if (!schema->fsmo.we_are_master && !rodc) {
+		ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+			  "schema_data_modify: we are not master: reject request\n");
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
+
+	/*
+	 * normaly the DACL will prevent delete
+	 * with LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS
+	 * above us.
+	 */
+	ldb_debug_set(ldb, LDB_DEBUG_ERROR,
+		      "schema_data_del: delete is not allowed in the schema\n");
+	return LDB_ERR_UNWILLING_TO_PERFORM;
+}
+
 static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg,
 				  const struct dsdb_schema *schema) 
 {
@@ -480,6 +651,8 @@ static const struct ldb_module_ops ldb_schema_data_module_ops = {
 	.name		= "schema_data",
 	.init_context	= schema_data_init,
 	.add		= schema_data_add,
+	.modify		= schema_data_modify,
+	.del		= schema_data_del,
 	.search         = schema_data_search
 };
 
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 58cf82b..b1ae768 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -237,6 +237,7 @@ struct dsdb_schema {
 
 	struct {
 		bool we_are_master;
+		bool update_allowed;
 		struct ldb_dn *master_dn;
 	} fsmo;
 
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 0a9dedf..a4c29f1 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -818,6 +818,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
 	const struct ldb_val *info_val;
 	struct ldb_val info_val_default;
 	struct dsdb_schema *schema;
+	struct loadparm_context *lp_ctx = NULL;
 	int ret;
 
 	schema = dsdb_new_schema(mem_ctx);
@@ -869,8 +870,20 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
 		schema->fsmo.we_are_master = false;
 	}
 
-	DEBUG(5, ("schema_fsmo_init: we are master: %s\n",
-		  (schema->fsmo.we_are_master?"yes":"no")));
+	lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+						struct loadparm_context);
+	if (lp_ctx) {
+		bool allowed = lpcfg_parm_bool(lp_ctx, NULL,
+						"dsdb", "schema update allowed",
+						false);
+		schema->fsmo.update_allowed = allowed;
+	} else {
+		schema->fsmo.update_allowed = false;
+	}
+
+	DEBUG(5, ("schema_fsmo_init: we are master[%s] updates allowed[%s]\n",
+		  (schema->fsmo.we_are_master?"yes":"no"),
+		  (schema->fsmo.update_allowed?"yes":"no")));
 
 	*schema_out = schema;
 	return LDB_SUCCESS;
diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c
index 18f3ab7..4142842 100644
--- a/source4/dsdb/schema/schema_set.c
+++ b/source4/dsdb/schema/schema_set.c
@@ -683,7 +683,9 @@ WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_sche
  * schema itself to the directory.
  */
 
-WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df)
+WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb,
+				 const char *pf, const char *df,
+				 const char *dn)
 {
 	struct ldb_ldif *ldif;
 	struct ldb_message *msg;
@@ -702,9 +704,16 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
 	}
 
 	schema = dsdb_new_schema(mem_ctx);
-
+	if (!schema) {
+		goto nomem;
+	}
+	schema->base_dn = ldb_dn_new(schema, ldb, dn);
+	if (!schema->base_dn) {
+		goto nomem;
+	}
 	schema->fsmo.we_are_master = true;
-	schema->fsmo.master_dn = ldb_dn_new_fmt(schema, ldb, "@PROVISION_SCHEMA_MASTER");
+	schema->fsmo.update_allowed = true;
+	schema->fsmo.master_dn = ldb_dn_new(schema, ldb, "@PROVISION_SCHEMA_MASTER");
 	if (!schema->fsmo.master_dn) {
 		goto nomem;
 	}
diff --git a/source4/dsdb/schema/tests/schema_syntax.c b/source4/dsdb/schema/tests/schema_syntax.c
index fed7063..9127d08 100644
--- a/source4/dsdb/schema/tests/schema_syntax.c
+++ b/source4/dsdb/schema/tests/schema_syntax.c
@@ -205,7 +205,7 @@ static bool torture_dsdb_syntax_tcase_setup(struct torture_context *tctx, void *
 	priv = talloc_zero(tctx, struct torture_dsdb_syntax);
 	torture_assert(tctx, priv, "No memory");
 
-	priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL);
+	priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL, NULL);
 	torture_assert(tctx, priv->ldb, "Failed to load schema from disk");
 
 	priv->schema = dsdb_get_schema(priv->ldb, NULL);
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
index a11c9cb..fad80ec 100644
--- a/source4/libnet/libnet_vampire.c
+++ b/source4/libnet/libnet_vampire.c
@@ -308,7 +308,9 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
 	NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
 	s_dsa->other_info->dns_name = tmp_dns_name;
 
-	schema_ldb = provision_get_schema(s, s->lp_ctx, &s->prefixmap_blob);
+	schema_ldb = provision_get_schema(s, s->lp_ctx,
+					  c->forest->schema_dn_str,
+					  &s->prefixmap_blob);
 	if (!schema_ldb) {
 		DEBUG(0,("Failed to re-load from local provision using remote prefixMap. "
 			 "Will continue with local prefixMap\n"));
@@ -481,7 +483,7 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
 	 * somehow updated the prefixMap during this transaction */
 	prefixMap_el->flags = LDB_FLAG_MOD_ADD;
 
-	ret = ldb_modify(s->ldb, msg);
+	ret = dsdb_modify(s->ldb, msg, DSDB_FLAG_AS_SYSTEM);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,("Failed to add prefixMap: %s\n", ldb_errstring(s->ldb)));
 		return NT_STATUS_FOOBAR;
@@ -590,6 +592,11 @@ NTSTATUS libnet_vampire_cb_schema_chunk(void *private_data,
 		s->self_made_schema = dsdb_new_schema(s);
 		NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema);
 
+		s->self_made_schema->base_dn = ldb_dn_new(s->self_made_schema,
+						s->ldb,
+						c->forest->schema_dn_str);
+		NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema->base_dn);
+
 		status = dsdb_load_prefixmap_from_drsuapi(s->self_made_schema, mapping_ctr);
 		if (!W_ERROR_IS_OK(status)) {
 			return werror_to_ntstatus(status);
diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c
index 86ee8ca..ebfb2ba 100644
--- a/source4/libnet/py_net.c
+++ b/source4/libnet/py_net.c
@@ -448,6 +448,9 @@ static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyOb
 	}
 
 	s->forest.dns_name = samdb_dn_to_dns_domain(s, ldb_get_root_basedn(samdb));
+	s->forest.root_dn_str = ldb_dn_get_linearized(ldb_get_root_basedn(samdb));
+	s->forest.config_dn_str = ldb_dn_get_linearized(ldb_get_config_basedn(samdb));
+	s->forest.schema_dn_str = ldb_dn_get_linearized(ldb_get_schema_basedn(samdb));
 
 	s->chunk.gensec_skey = &s->gensec_skey;
 	s->chunk.partition = &s->partition;
diff --git a/source4/param/provision.c b/source4/param/provision.c
index 55540d4..766babe 100644
--- a/source4/param/provision.c
+++ b/source4/param/provision.c
@@ -330,7 +330,9 @@ failure:
 }
 
 
-struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
+struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx,
+					 struct loadparm_context *lp_ctx,
+					 const char *schema_dn,
 					 DATA_BLOB *override_prefixmap)
 {
 	PyObject *schema_mod, *schema_dict, *schema_fn, *py_result, *parameters;
@@ -362,6 +364,11 @@ struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_co
 	
 	parameters = PyDict_New();
 
+	if (schema_dn) {
+		PyDict_SetItemString(parameters, "schemadn",
+				     PyString_FromString(schema_dn));
+	}
+
 	if (override_prefixmap) {
 		PyDict_SetItemString(parameters, "override_prefixmap",
 				     PyString_FromStringAndSize((const char *)override_prefixmap->data,
diff --git a/source4/param/provision.h b/source4/param/provision.h
index 36758b9..fc02878 100644
--- a/source4/param/provision.h
+++ b/source4/param/provision.h
@@ -63,7 +63,9 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context
 				   struct provision_store_self_join_settings *settings,
 				   const char **error_string);
 
-struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
+struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx,
+					 struct loadparm_context *lp_ctx,
+					 const char *schema_dn,
 					 DATA_BLOB *override_prefixmap);
 
 #endif /* _PROVISION_H_ */
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 0a3df32..f403120 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -1101,7 +1101,8 @@ def reload_full_schema(samdb, names):
     :param names: List of key provision parameters
     """
 
-    current = samdb.search(expression="objectClass=*", base=str(names.schemadn),
+    schemadn = str(names.schemadn)
+    current = samdb.search(expression="objectClass=*", base=schemadn,
                                 scope=SCOPE_SUBTREE)
     schema_ldif = ""
     prefixmap_data = ""
@@ -1113,9 +1114,9 @@ def reload_full_schema(samdb, names):
     prefixmap_data = b64encode(prefixmap_data)
 
     # We don't actually add this ldif, just parse it
-    prefixmap_ldif = "dn: cn=schema\nprefixMap:: %s\n\n" % prefixmap_data
+    prefixmap_ldif = "dn: %s\nprefixMap:: %s\n\n" % (schemadn, prefixmap_data)
 
-    dsdb._dsdb_set_schema_from_ldif(samdb, prefixmap_ldif, schema_ldif)
+    dsdb._dsdb_set_schema_from_ldif(samdb, prefixmap_ldif, schema_ldif, schemadn)
 
 
 def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs, prereloadfunc):
diff --git a/source4/scripting/python/samba/schema.py b/source4/scripting/python/samba/schema.py
index 8bac26e..9cbfa3a 100644
--- a/source4/scripting/python/samba/schema.py
+++ b/source4/scripting/python/samba/schema.py
@@ -116,11 +116,11 @@ class Schema(object):
         self.prefixmap_data = b64encode(self.prefixmap_data)
 
         # We don't actually add this ldif, just parse it
-        prefixmap_ldif = "dn: cn=schema\nprefixMap:: %s\n\n" % self.prefixmap_data
-        self.set_from_ldif(prefixmap_ldif, self.schema_data)
+        prefixmap_ldif = "dn: %s\nprefixMap:: %s\n\n" % (self.schemadn, self.prefixmap_data)
+        self.set_from_ldif(prefixmap_ldif, self.schema_data, self.schemadn)
 
-    def set_from_ldif(self, pf, df):
-        dsdb._dsdb_set_schema_from_ldif(self.ldb, pf, df)
+    def set_from_ldif(self, pf, df, dn):
+        dsdb._dsdb_set_schema_from_ldif(self.ldb, pf, df, dn)
 
     def write_to_tmp_ldb(self, schemadb_path):
         self.ldb.connect(url=schemadb_path)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list