[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Jul 15 16:02:09 MDT 2010


The branch, master has been updated
       via  0e212ac... s4:testprogs Operate the blackbox kinit and net tests using the :local config
       via  8769e75... s4:testprogs Show that we no longer delete the old keytab entries
       via  299057d... s4:provision Handle machine account password changes while keeping keytab
       via  3e8dba1... s4:pyldb whitespace fix
       via  fcdf619... s4:pyldb Fix memory handling for ldb_message_element
       via  5d61b47... s4:testprogs Prove kerberos still works after a password change
       via  36b5fec... s4 upgradeprovision: Adapt the list of attribute modified
       via  a748402... s4 ldb modules: relax some tests about attributes that should not be here
       via  7478224... s4 upgradeprovision: Synchronize the calculated keyversionnumber with the one previously stored
       via  0a1b112... s4 upgradeprovision: do not copy RID Set it's automaticaly created by the RID manager
       via  2afc2f2... s4 upgradeprovision: add function to backup the provision before updating
       via  6c51b3a... s4 upgradeprovision: fix whitespaces
       via  62a3297... s4: Add unit test for increment_calculated_keyversion_number
       via  9323901... s4 upgradeprovision: introduce a new function to update the field use for calculating msds-keyversionnumber
       via  f97c90c... s4 python: Add functions to samdb to manipulate version of replPropertyMetaData attribute
       via  6a0856d... s4 dsdb: Use the changereplmetadata control
       via  d861ebb... s4 dsdb: create a new control: changereplmetadata
       via  b67a71f... ldb: allow ldb_sequence_number to be called in python
       via  0496af8... s4: Unit test update_machine_account_password through kinit
       via  7ea70f8... s4: Add a simple script to change dc password
       via  fd2eb0d... s4 provision: move update_machine_account_password to helpers
      from  ff93d58... s3: Fix crashes in the printing code

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


- Log -----------------------------------------------------------------
commit 0e212acd32b0378e9d7ea912f0eee5afa230d898
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 15 16:45:13 2010 +1000

    s4:testprogs Operate the blackbox kinit and net tests using the :local config
    
    This :local tells selftest.pl to use the local smb.conf for the test
    environment, not the generic client smb.conf
    
    This then makes the rest work properly - otherwise, it may attempt to
    connect to the wrong KDC for example.
    
    The only problem is that we can't test the 'net join' with this set,
    so this is removed from the test.  The member server test environment
    checks this anyway.
    
    Andrew Bartlett

commit 8769e75a616a3f4b7cc1a2b5f7ea261262ad75d2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 15 14:05:23 2010 +1000

    s4:testprogs Show that we no longer delete the old keytab entries
    
    By using a CCACHE obtained while the old password was still valid, we
    can tell if the server still accepts incoming Kerberos connections
    with the old password.
    
    Andrew Bartlett

commit 299057d8d97cce349af2ff931396fae1f09493a5
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 15 14:03:11 2010 +1000

    s4:provision Handle machine account password changes while keeping keytab
    
    The challenge here is to update the existing record if it already
    exists, rather than deleting the old record.  This ensures that the
    secrets.keytab handling code keeps the previous password in the
    keytab.
    
    Andrew Bartlett

commit 3e8dba17030544a389611814e47521ceafa1ae8a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 15 14:01:56 2010 +1000

    s4:pyldb whitespace fix

commit fcdf619b361b9c30b59f65ba38f69f344b4c95ae
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 15 14:00:48 2010 +1000

    s4:pyldb Fix memory handling for ldb_message_element
    
    The problem here is that we need to use the array, not the individual
    message element as the memory context.
    
    Andrew Bartlett

commit 5d61b477c66dce60d8ea37081f0c7394c77e1867
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 15 10:54:08 2010 +1000

    s4:testprogs Prove kerberos still works after a password change
    
    Changing the machine account password should not prevent connections
    with a current, valid CCACHE.  This is because when the password is
    changed, the server-side keytab keeps one old password around.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 36b5feceee2ea23d6da757999f238e28ab7de485
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jul 11 17:27:13 2010 +0400

    s4 upgradeprovision: Adapt the list of attribute modified
    
    * isMemberOfPartialAttributeSet is now allowed to be deleted (on schema
     objects)
    * attributeDisplayNames is now allowed to be added and modified (used on
      display specifiers)
    * spnMapping is now allowed to be altered on Directory Service objects
    * minPwdAge is now modified if the previous value was 0
    
    We issue a clear information about the userControl attribute for
    administrator to invite the user to modify himself the value.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit a748402f61b4b3ea0df6666f4ec90f42fb45eaf8
Author: Matthieu Patou <mat at matws.net>
Date:   Sat Jul 10 14:48:40 2010 +0400

    s4 ldb modules: relax some tests about attributes that should not be here
    
    For attributes that we know that are harmless and that used to be stored
    in the ldb we relax the tests on the existance in a given objectclass.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 7478224189598f192065b91d57080f1dd1719a99
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jul 5 01:00:13 2010 +0400

    s4 upgradeprovision: Synchronize the calculated keyversionnumber with the one previously stored
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 0a1b1121c48e26c5218e2ccc0c8a8cc724b96624
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jul 5 23:46:46 2010 +0400

    s4 upgradeprovision: do not copy RID Set it's automaticaly created by the RID manager
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 2afc2f20b65b28140274828249160f1483090b5e
Author: Matthieu Patou <mat at matws.net>
Date:   Sat Jul 3 16:26:24 2010 +0400

    s4 upgradeprovision: add function to backup the provision before updating
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 6c51b3a43298e43332893f52d6951bf475bae6af
Author: Matthieu Patou <mat at matws.net>
Date:   Sat Jul 3 16:53:44 2010 +0400

    s4 upgradeprovision: fix whitespaces
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 62a32975c86e71eb1c5efeec0a4dee9d1ac20c10
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 15 12:54:05 2010 +0400

    s4: Add unit test for increment_calculated_keyversion_number
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 93239016443c1ba40ec69c025a91d60c09833c20
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 15 12:49:19 2010 +0400

    s4 upgradeprovision: introduce a new function to update the field use for calculating msds-keyversionnumber
    
    This function change the version field of the unicodePwd in the
    replPropertyMetaData so that the version is equal or
    superior to the reference value passed.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit f97c90c9cd124314b4a0862e702dd021bd2df9a0
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 22 20:03:15 2010 +0400

    s4 python: Add functions to samdb to manipulate version of replPropertyMetaData attribute
    
    This change contains also helpers for attribute id to attribute oid
    conversion and from attribute id to attribute name.
    It brings also unit tests
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 6a0856da9cc075acaa7fcb6bad614f8f403df9c7
Author: Matthieu Patou <mat at matws.net>
Date:   Wed Jun 16 18:47:18 2010 +0400

    s4 dsdb: Use the changereplmetadata control
    
    This control allow to specify the replPropertyMetaData attribute to
    be specified on modify request. It can be used for very specific needs
    to tweak the content of the replication data.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit d861ebbd8167cf6da6d7565799dbc5267adf6bae
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 22 19:56:37 2010 +0400

    s4 dsdb: create a new control: changereplmetadata
    
    This control is designed to allow replmetadata to be specified
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit b67a71f00bb84f14f7568d0afe143843d31a0a45
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 21 10:55:18 2010 +0400

    ldb: allow ldb_sequence_number to be called in python
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 0496af8341b08ad2b8ceb42892ddde06af279c52
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jul 4 16:39:17 2010 +0400

    s4: Unit test update_machine_account_password through kinit
    
    This patch is for testing the chgdcpass script which is mostly a call to
    update_machine_account_password.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 7ea70f86ac3a34d84082fed8b5f80ec1b46893bf
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 28 13:49:08 2010 +0400

    s4: Add a simple script to change dc password
    
    This script will mostly be used by unit test (blackbox type) to test the
    change of the dc password
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit fd2eb0dfd092e00408f206e6fe7ff302ccd27a10
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jul 4 16:38:54 2010 +0400

    s4 provision: move update_machine_account_password to helpers
    
    This is to allow reuse of this function and also unit tests
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/objectclass_attrs.c |    9 +
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |  205 +++++--
 source4/dsdb/samdb/samdb.h                         |    6 +
 source4/lib/ldb/pyldb.c                            |   43 ++-
 source4/scripting/bin/upgradeprovision             |  583 ++++++++++++--------
 source4/scripting/devel/chgtdcpass                 |   63 +++
 source4/scripting/python/samba/provision.py        |   38 +-
 source4/scripting/python/samba/samdb.py            |  103 ++++
 source4/scripting/python/samba/tests/dsdb.py       |  113 ++++-
 .../python/samba/tests/upgradeprovisionneeddc.py   |   26 +-
 source4/scripting/python/samba/upgradehelpers.py   |   85 +++-
 source4/selftest/tests.sh                          |   11 +-
 source4/setup/schema_samba4.ldif                   |    1 +
 source4/utils/tests/test_net.sh                    |    2 -
 testprogs/blackbox/test_chgdcpass.sh               |   66 +++
 testprogs/blackbox/test_kinit.sh                   |    1 -
 16 files changed, 1021 insertions(+), 334 deletions(-)
 create mode 100755 source4/scripting/devel/chgtdcpass
 create mode 100755 testprogs/blackbox/test_chgdcpass.sh


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
index 6cfecc0..b9436e3 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
@@ -153,6 +153,12 @@ static int attr_handler(struct oc_context *ac)
 	return ldb_next_request(ac->module, child_req);
 }
 
+/*
+  these are attributes which are left over from old ways of doing
+  things in ldb, and are harmless
+ */
+static const char *harmless_attrs[] = { "parentGUID", NULL };
+
 static int attr_handler2(struct oc_context *ac)
 {
 	struct ldb_context *ldb;
@@ -219,6 +225,9 @@ static int attr_handler2(struct oc_context *ac)
 			found = str_list_check(may_contain, attr->lDAPDisplayName);
 		}
 		if (!found) {
+			found = str_list_check(harmless_attrs, attr->lDAPDisplayName);
+		}
+		if (!found) {
 			ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' does not exist in the specified objectclasses!",
 					       msg->elements[i].name,
 					       ldb_dn_get_linearized(msg->dn));
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 90af17f..2205be0 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -5,6 +5,7 @@
    Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005
    Copyright (C) Andrew Tridgell 2005
    Copyright (C) Stefan Metzmacher <metze at samba.org> 2007
+   Copyright (C) Matthieu Patou <mat at samba.org> 2010
 
    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
@@ -1073,6 +1074,20 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
 	return LDB_SUCCESS;
 }
 
+static uint64_t find_max_local_usn(struct replPropertyMetaDataBlob omd)
+{
+	uint32_t count = omd.ctr.ctr1.count;
+	uint64_t max = 0;
+	uint32_t i;
+	for (i=0; i < count; i++) {
+		struct replPropertyMetaData1 m = omd.ctr.ctr1.array[i];
+		if (max < m.local_usn) {
+			max = m.local_usn;
+		}
+	}
+	return max;
+}
+
 /*
  * update the replPropertyMetaData object each time we modify an
  * object. This is needed for DRS replication, as the merge on the
@@ -1093,11 +1108,12 @@ static int replmd_update_rpmd(struct ldb_module *module,
 	const struct GUID *our_invocation_id;
 	int ret;
 	const char *attrs[] = { "replPropertyMetaData", "*", NULL };
+	const char *attrs2[] = { "uSNChanged", "objectClass", NULL };
 	struct ldb_result *res;
 	struct ldb_context *ldb;
 	struct ldb_message_element *objectclass_el;
 	enum urgent_situation situation;
-	bool rodc;
+	bool rodc, rmd_is_provided;
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -1111,21 +1127,10 @@ static int replmd_update_rpmd(struct ldb_module *module,
 
 	unix_to_nt_time(&now, t);
 
-	/* search for the existing replPropertyMetaDataBlob. We need
-	 * to use REVEAL and ask for DNs in storage format to support
-	 * the check for values being the same in
-	 * replmd_update_rpmd_element()
-	 */
-	ret = dsdb_module_search_dn(module, msg, &res, msg->dn, attrs,
-	                            DSDB_FLAG_NEXT_MODULE |
-	                            DSDB_SEARCH_SHOW_DELETED |
-				    DSDB_SEARCH_SHOW_EXTENDED_DN |
-				    DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT |
-				    DSDB_SEARCH_REVEAL_INTERNALS);
-	if (ret != LDB_SUCCESS || res->count != 1) {
-		DEBUG(0,(__location__ ": Object %s failed to find replPropertyMetaData\n",
-			 ldb_dn_get_linearized(msg->dn)));
-		return LDB_ERR_OPERATIONS_ERROR;
+	if (ldb_request_get_control(req, DSDB_CONTROL_CHANGEREPLMETADATA_OID)) {
+		rmd_is_provided = true;
+	} else {
+		rmd_is_provided = false;
 	}
 
 	/* if isDeleted is present and is TRUE, then we consider we are deleting,
@@ -1136,62 +1141,140 @@ static int replmd_update_rpmd(struct ldb_module *module,
 		situation = REPL_URGENT_ON_UPDATE;
 	}
 
-	objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
-	if (is_urgent && replmd_check_urgent_objectclass(objectclass_el,
-							situation)) {
-		*is_urgent = true;
-	}
+	if (rmd_is_provided) {
+		/* In this case the change_replmetadata control was supplied */
+		/* We check that it's the only attribute that is provided
+		 * (it's a rare case so it's better to keep the code simplier)
+		 * We also check that the highest local_usn is bigger than
+		 * uSNChanged. */
+		uint64_t db_seq;
+		if( msg->num_elements != 1 ||
+			strncmp(msg->elements[0].name,
+				"replPropertyMetaData", 20) ) {
+			DEBUG(0,(__location__ ": changereplmetada control called without "\
+				"a specified replPropertyMetaData attribute or with others\n"));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		if (situation == REPL_URGENT_ON_DELETE) {
+			DEBUG(0,(__location__ ": changereplmetada control can't be called when deleting an object\n"));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		omd_value = ldb_msg_find_ldb_val(msg, "replPropertyMetaData");
+		if (!omd_value) {
+			DEBUG(0,(__location__ ": replPropertyMetaData was not specified for Object %s\n",
+				 ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		ndr_err = ndr_pull_struct_blob(omd_value, msg, &omd,
+					       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+			DEBUG(0,(__location__ ": Failed to parse replPropertyMetaData for %s\n",
+				 ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+		*seq_num = find_max_local_usn(omd);
 
-	omd_value = ldb_msg_find_ldb_val(res->msgs[0], "replPropertyMetaData");
-	if (!omd_value) {
-		DEBUG(0,(__location__ ": Object %s does not have a replPropertyMetaData attribute\n",
-			 ldb_dn_get_linearized(msg->dn)));
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
+		ret = dsdb_module_search_dn(module, msg, &res, msg->dn, attrs2,
+					    DSDB_FLAG_NEXT_MODULE |
+					    DSDB_SEARCH_SHOW_DELETED |
+					    DSDB_SEARCH_SHOW_EXTENDED_DN |
+					    DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT |
+					    DSDB_SEARCH_REVEAL_INTERNALS);
 
-	ndr_err = ndr_pull_struct_blob(omd_value, msg, &omd,
-				       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		DEBUG(0,(__location__ ": Failed to parse replPropertyMetaData for %s\n",
-			 ldb_dn_get_linearized(msg->dn)));
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
+		if (ret != LDB_SUCCESS || res->count != 1) {
+			DEBUG(0,(__location__ ": Object %s failed to find uSNChanged\n",
+				 ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 
-	if (omd.version != 1) {
-		DEBUG(0,(__location__ ": bad version %u in replPropertyMetaData for %s\n",
-			 omd.version, ldb_dn_get_linearized(msg->dn)));
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
+		objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
+		if (is_urgent && replmd_check_urgent_objectclass(objectclass_el,
+								situation)) {
+			*is_urgent = true;
+		}
 
-	/*we have elements that will be modified*/
-	if (msg->num_elements > 0) {
-		/*if we are RODC and this is a DRSR update then its ok*/
-		if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
-			ret = samdb_rodc(ldb, &rodc);
-			if (ret != LDB_SUCCESS) {
-				DEBUG(4, (__location__ ": unable to tell if we are an RODC\n"));
-			} else if (rodc) {
-				ldb_asprintf_errstring(ldb, "RODC modify is forbidden\n");
-				return LDB_ERR_REFERRAL;
-			}
+		db_seq = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNChanged", 0);
+		if (*seq_num <= db_seq) {
+			DEBUG(0,(__location__ ": changereplmetada control provided but max(local_usn)"\
+					      " is less or equal to uSNChanged (max = %lld uSNChanged = %lld)\n",
+					      *seq_num, db_seq));
+			return LDB_ERR_OPERATIONS_ERROR;
 		}
-	}
 
-	for (i=0; i<msg->num_elements; i++) {
-		struct ldb_message_element *old_el;
-		old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name);
-		ret = replmd_update_rpmd_element(ldb, msg, &msg->elements[i], old_el, &omd, schema, seq_num,
-						 our_invocation_id, now);
-		if (ret != LDB_SUCCESS) {
-			return ret;
+	} else {
+		/* search for the existing replPropertyMetaDataBlob. We need
+		 * to use REVEAL and ask for DNs in storage format to support
+		 * the check for values being the same in
+		 * replmd_update_rpmd_element()
+		 */
+		ret = dsdb_module_search_dn(module, msg, &res, msg->dn, attrs,
+					    DSDB_FLAG_NEXT_MODULE |
+					    DSDB_SEARCH_SHOW_DELETED |
+					    DSDB_SEARCH_SHOW_EXTENDED_DN |
+					    DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT |
+					    DSDB_SEARCH_REVEAL_INTERNALS);
+		if (ret != LDB_SUCCESS || res->count != 1) {
+			DEBUG(0,(__location__ ": Object %s failed to find replPropertyMetaData\n",
+				 ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
-		if (is_urgent && !*is_urgent && (situation == REPL_URGENT_ON_UPDATE)) {
-			*is_urgent = replmd_check_urgent_attribute(&msg->elements[i]);
+		objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
+		if (is_urgent && replmd_check_urgent_objectclass(objectclass_el,
+								situation)) {
+			*is_urgent = true;
 		}
 
-	}
+		omd_value = ldb_msg_find_ldb_val(res->msgs[0], "replPropertyMetaData");
+		if (!omd_value) {
+			DEBUG(0,(__location__ ": Object %s does not have a replPropertyMetaData attribute\n",
+				 ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 
+		ndr_err = ndr_pull_struct_blob(omd_value, msg, &omd,
+					       (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+			DEBUG(0,(__location__ ": Failed to parse replPropertyMetaData for %s\n",
+				 ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+
+		if (omd.version != 1) {
+			DEBUG(0,(__location__ ": bad version %u in replPropertyMetaData for %s\n",
+				 omd.version, ldb_dn_get_linearized(msg->dn)));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+
+		/*we have elements that will be modified*/
+		if (msg->num_elements > 0) {
+			/*if we are RODC and this is a DRSR update then its ok*/
+			if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) {
+				ret = samdb_rodc(ldb, &rodc);
+				if (ret != LDB_SUCCESS) {
+					DEBUG(4, (__location__ ": unable to tell if we are an RODC\n"));
+				} else if (rodc) {
+					ldb_asprintf_errstring(ldb, "RODC modify is forbidden\n");
+					return LDB_ERR_REFERRAL;
+				}
+			}
+		}
+
+		for (i=0; i<msg->num_elements; i++) {
+			struct ldb_message_element *old_el;
+			old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name);
+			ret = replmd_update_rpmd_element(ldb, msg, &msg->elements[i], old_el, &omd, schema, seq_num,
+							 our_invocation_id, now);
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+
+			if (is_urgent && !*is_urgent && (situation == REPL_URGENT_ON_UPDATE)) {
+				*is_urgent = replmd_check_urgent_attribute(&msg->elements[i]);
+			}
+
+		}
+	}
 	/*
 	 * replmd_update_rpmd_element has done an update if the
 	 * seq_num is set
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 8b45cd0..75aae7f 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -92,6 +92,12 @@ struct dsdb_control_password_change_status {
  */
 #define DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID "1.3.6.1.4.1.7165.4.3.12"
 
+/**
+  OID used to allow the replacement of replPropertyMetaData.
+  It is used when the current replmetadata needs to be edited.
+*/
+#define DSDB_CONTROL_CHANGEREPLMETADATA_OID "1.3.6.1.4.1.7165.4.3.14"
+
 #define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1"
 struct dsdb_extended_replicated_object {
 	struct ldb_message *msg;
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index b886a4b..f27ab3d 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -1249,6 +1249,26 @@ static PyObject *py_ldb_modules(PyLdbObject *self)
 	return ret;
 }
 
+static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
+{
+	struct ldb_context *ldb = PyLdb_AsLdbContext(self);
+	int type, ret;
+	uint64_t value;
+
+	/* type "int" rather than "enum" for "scope" is intentional */
+	if (!PyArg_ParseTuple(args, "i", &type))
+		return NULL;
+
+	/* FIXME: More interpretation */
+
+	ret = ldb_sequence_number(ldb, type, &value);
+
+	if (ret != LDB_SUCCESS) {
+		PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
+		return NULL;
+	}
+	return PyLong_FromLongLong(value);
+}
 static PyMethodDef py_ldb_methods[] = {
 	{ "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
 		"S.set_debug(callback) -> None\n"
@@ -1335,6 +1355,9 @@ static PyMethodDef py_ldb_methods[] = {
 	{ "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
 		"S.modules() -> list\n"
 		"Return the list of modules on this LDB connection " },
+	{ "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
+		"S.sequence_number(type) -> value\n"
+		"Return the value of the sequence according to the requested type" },
 	{ NULL },
 };
 
@@ -1635,9 +1658,14 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
 {
 	struct ldb_message_element *me;
 
-	if (PyLdbMessageElement_Check(set_obj))
-		return talloc_reference(mem_ctx, 
-								PyLdbMessageElement_AsMessageElement(set_obj));
+	if (PyLdbMessageElement_Check(set_obj)) {
+		PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
+		/* We have to talloc_reference() the memory context, not the pointer which may not actually be it's own context */
+		if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
+			return PyLdbMessageElement_AsMessageElement(set_obj);
+		}
+		return NULL;
+	}
 
 	me = talloc(mem_ctx, struct ldb_message_element);
 
@@ -1941,7 +1969,7 @@ static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *p
 	if (el == NULL) {
 		return NULL;
 	}
-	return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
+	return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
 }
 
 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
@@ -1980,7 +2008,7 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
 		j++;
 	}
 	for (i = 0; i < msg->num_elements; i++, j++) {
-		PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
+		PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)));
 	}
 	return l;
 }
@@ -2018,7 +2046,7 @@ static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject
 		ldb_msg_remove_attr(self->msg, attr_name);
 	} else {
 		struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
-											value, 0, attr_name);
+									   value, 0, attr_name);
 		if (el == NULL)
 			return -1;
 		ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
@@ -2594,6 +2622,9 @@ void initldb(void)
 	if (m == NULL)
 		return;
 
+	PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
+	PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
+	PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
 	PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
 	PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
 	PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 48c4ce6..deb50e3 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -43,20 +43,22 @@ from ldb import (SCOPE_SUBTREE, SCOPE_BASE,
                 MessageElement, Message, Dn)
 from samba import param
 from samba.provision import (find_setup_dir, get_domain_descriptor,
-                            get_config_descriptor, secretsdb_self_join,
+                            get_config_descriptor,
                             ProvisioningError, get_last_provision_usn,
                             get_max_usn, update_provision_usn)
 from samba.schema import get_linked_attributes, Schema, get_schema_descriptor
-from samba.dcerpc import security, drsblobs
+from samba.dcerpc import security, drsblobs, xattr
 from samba.ndr import ndr_unpack
-from samba.dcerpc.misc import SEC_CHAN_BDC
 from samba.upgradehelpers import (dn_sort, get_paths, newprovision,
                                  find_provision_key_parameters, get_ldbs,
                                  usn_in_range, identic_rename, get_diff_sddls,
                                  update_secrets, CHANGE, ERROR, SIMPLE,
                                  CHANGEALL, GUESS, CHANGESD, PROVISION,
                                  updateOEMInfo, getOEMInfo, update_gpo,
-                                 delta_update_basesamdb, update_policyids)
+                                 delta_update_basesamdb, update_policyids,
+                                 update_machine_account_password,
+                                 search_constructed_attrs_stored,
+                                 increment_calculated_keyversion_number)
 
 replace=2**FLAG_MOD_REPLACE
 add=2**FLAG_MOD_ADD
@@ -103,7 +105,9 @@ hashOverwrittenAtt = {  "prefixMap": replace, "systemMayContain": replace,
                         "wellKnownObjects":replace, "privilege":never,
                         "defaultSecurityDescriptor": replace,
                         "rIDAvailablePool": never,
-                        "defaultSecurityDescriptor": replace + add }
+                        "defaultSecurityDescriptor": replace + add,
+                        "isMemberOfPartialAttributeSet": delete,
+                        "attributeDisplayNames": replace + add}
 
 
 backlinked = []
@@ -285,7 +289,7 @@ def print_provision_key_parameters(names):
     message(GUESS, "domainlevel :" + str(names.domainlevel))
 
 
-def handle_special_case(att, delta, new, old, usn):
+def handle_special_case(att, delta, new, old, usn, basedn, aldb):
     """Define more complicate update rules for some attributes
 
     :param att: The attribute to be updated
@@ -294,6 +298,8 @@ def handle_special_case(att, delta, new, old, usn):
     :param new: The reference object
     :param old: The Updated object
     :param usn: The highest usn modified by a previous (upgrade)provision
+    :param basedn: The base DN of the provision
+    :param aldb: An ldb object used to build DN
     :return: True to indicate that the attribute should be kept, False for
              discarding it"""
 
@@ -302,6 +308,23 @@ def handle_special_case(att, delta, new, old, usn):
     # highest usn as otherwise the replPropertyMetaData will guide us more
     # correctly
     if usn is None:
+        if (att == "sPNMappings" and flag == FLAG_MOD_REPLACE and
+            ldb.Dn(aldb, "CN=Directory Service,CN=Windows NT,"
+                        "CN=Services,CN=Configuration,%s" % basedn)
+                        == old[0].dn):
+            return True
+        if (att == "userAccountControl" and flag == FLAG_MOD_REPLACE and
+            ldb.Dn(aldb, "CN=Administrator,CN=Users,%s" % basedn)
+                        == old[0].dn):
+            message(SIMPLE, "We suggest that you change the userAccountControl"
+                            " for user Administrator from value %d to %d" %
+                            (int(str(old[0][att])), int(str(new[0][att]))))
+            return False
+        if (att == "minPwdAge" and flag == FLAG_MOD_REPLACE):
+            if (long(str(old[0][att])) == 0):
+                delta[att] = MessageElement(new[0][att], FLAG_MOD_REPLACE, att)
+            return True
+
         if (att == "member" and flag == FLAG_MOD_REPLACE):
             hash = {}
             newval = []
@@ -320,7 +343,7 @@ def handle_special_case(att, delta, new, old, usn):
                 delta.remove(att)
             return True
 
-        if (att in ("gPLink", "gPCFileSysPath") and 
+        if (att in ("gPLink", "gPCFileSysPath") and
             flag == FLAG_MOD_REPLACE and
             str(new[0].dn).lower() == str(old[0].dn).lower()):
             delta.remove(att)
@@ -516,30 +539,40 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index):
     empty = Message()
     delta = samdb.msg_diff(empty, reference[0])
     delta.dn
-    if delta.get("objectSid"):
-        sid = str(ndr_unpack(security.dom_sid, str(reference[0]["objectSid"])))
-        m = re.match(r".*-(\d+)$", sid)
-        if m and int(m.group(1))>999:


-- 
Samba Shared Repository


More information about the samba-cvs mailing list