[SCM] Samba Shared Repository - branch master updated

Matthieu Patou mat at samba.org
Sun Jun 19 16:32:02 MDT 2011


The branch, master has been updated
       via  01ce078 s4-upgradeprovision: propose the use of findprovisionranges if no ranges are present
       via  957b1ff s4: create script to find provision ranges for old provision without this information
       via  9c94943 s4-sambatool: extract the confirm function in a separte module for reuse
       via  bc54957 s4-samba-tool: remove unused imports
       via  db03091 s4-samba-tool: use correct object notation ie. obj.method rather than method(obj, ...)
       via  8a04863 s4-sambatool: use correct way to call class methods
       via  8968489 s4-upgradeprovision: improve message output
       via  8a19e1e s4-upgradeprovision: skip versionNumber, it's used by GPO
       via  1563720 s4-provision: Remove hard coded SD for CN=Sites container
       via  05b2d41 s4-upgradeprovision: deltaattr can be empty or none too
       via  12b379e s4-upgradeprovision: handle the fact that oEMInformation might not be present
       via  5e81ee8 s4-upgradeprovision: Rework completly how SDs are recalculated
       via  7128345 s4-python: make checks of sacl in get_diff_sddls optionnal
       via  c0eb403 s4-upgradeprovision: remove useless comment
       via  bc7b8fa s4-upgradeprovision: ignore objectSid
       via  f7a903e s4-upgradeprovision: add a list of attribute that are not DSDB attribute that we don't want to copy
       via  245b277 s4: fix wrong index usage PRIMARY_USER_SID_INDEX when it should have been PRIMARY_GROUP_SID_INDEX
       via  930d2f2 s4-upgradeprovision: if there is nothing to really modify then skip it
       via  0e72914 s4-upgradeprovision: dn must be skipped as delta.remove("dn") do not remove this attribute
       via  f76c206 s4-upgradeprovision: change hashAttrNotCopied to be an array
       via  4305f54 s4-upgradeprovision: fix inverted logic and wrong flags on sd_flags control
       via  0175859 s4-upgradeprovision: remove useless code
       via  44c5406 s4-upgradeprovision: don't print dn in the list of modified attributes
       via  9a18e07 s4-upgradeprovision: clean up, reformating and update docs
       via  20233cd s4-upgradeprovision: introduce invocation id in lastprovisionUSNs
       via  71ab462 s4-upgradeprovision: add function to know if attribute is replicated or not
       via  d9abcc9 s4-upgradeprovision: split update_present in two functions depending on the method used
       via  0065742 s4-upgradeprovision: handle_special_attributes don't really need ranges of USNs, just the information if we are using replPropertyMetadata for attribute selection
       via  45df4d8 s4-python: fix wrong discovery of the site name in find_key_provision_parameters
       via  5db07d2 s4-upgradeprovisision: fix bug 8063, old SD can miss some componenent (group, owner, ...)
       via  b14bdf4 s4-upgradeprovision: Fix an error, so that cursddl and refsddl are not the same
       via  02970f4 py-ldb: allow dictionnary like usage (ie. e.get("myattribute", defVal)
      from  5290fac s3: Fix Coverity ID 2582: FORWARD_NULL

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


- Log -----------------------------------------------------------------
commit 01ce078ed166635c29e89bd012c82e3612393f28
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 20 01:05:04 2011 +0400

    s4-upgradeprovision: propose the use of findprovisionranges if no ranges are present
    
    Autobuild-User: Matthieu Patou <mat at samba.org>
    Autobuild-Date: Mon Jun 20 00:30:59 CEST 2011 on sn-devel-104

commit 957b1ff183cf713bebc4cc9a32cabacc1e86b13e
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 20 01:00:48 2011 +0400

    s4: create script to find provision ranges for old provision without this information

commit 9c94943d26d1076b0ef196698d7d0d2e3b0b80e4
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 23:09:59 2011 +0400

    s4-sambatool: extract the confirm function in a separte module for reuse

commit bc549575dd0f80089dcaefcefeb4211c3771b8c6
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 21:27:32 2011 +0400

    s4-samba-tool: remove unused imports

commit db0309160740afcdfb192cb55d15f906b15e0481
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 21:26:48 2011 +0400

    s4-samba-tool: use correct object notation ie. obj.method rather than method(obj, ...)

commit 8a04863f0d630119c5f02b2708f50dd37dd37955
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 20:43:11 2011 +0400

    s4-sambatool: use correct way to call class methods

commit 89684895ee96741cdf2f88dc812496714df70fbb
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 01:17:44 2011 +0400

    s4-upgradeprovision: improve message output

commit 8a19e1ecfb716579e662d2d6b6bceeccbf7e7741
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 01:17:27 2011 +0400

    s4-upgradeprovision: skip versionNumber, it's used by GPO

commit 15637206b9b51fea31aa267244aeb386c1ba7676
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 00:16:54 2011 +0400

    s4-provision: Remove hard coded SD for CN=Sites container
    
    With the fix introduced by Nadya in changeset
    622ef6aed82a2f2f7748c2a88535486af77487de we are now able to generate
    correct SD (at least the same as W2k3R2 with a Forest Level of 2003), so
    there is no need for this fix anymore as it makes SDs for Forest Level
    2003 and lower incorrect.

commit 05b2d4147a75a652f8f773d353b62a4c10821155
Author: Matthieu Patou <mat at matws.net>
Date:   Wed Jun 15 15:20:46 2011 +0400

    s4-upgradeprovision: deltaattr can be empty or none too

commit 12b379e9831131c251fde3ebebb76b00323f6bf0
Author: Matthieu Patou <mat at matws.net>
Date:   Wed Jun 15 15:20:06 2011 +0400

    s4-upgradeprovision: handle the fact that oEMInformation might not be present

commit 5e81ee8b341c3c6a6f9a321ec6ddf9b29932b683
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 14 01:42:59 2011 +0400

    s4-upgradeprovision: Rework completly how SDs are recalculated

commit 7128345969927461ec281583abec3ea51bf98586
Author: Matthieu Patou <mat at matws.net>
Date:   Sat Jun 18 23:21:18 2011 +0400

    s4-python: make checks of sacl in get_diff_sddls optionnal

commit c0eb4037585e1feb609d7acef196c4dc8872960b
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 14 01:42:28 2011 +0400

    s4-upgradeprovision: remove useless comment

commit bc7b8fa108bf27f78c69f5aec3e408e59555c232
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 14 01:41:56 2011 +0400

    s4-upgradeprovision: ignore objectSid

commit f7a903ee8085bb041cae8fdf603997e66245f35f
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 14 01:39:41 2011 +0400

    s4-upgradeprovision: add a list of attribute that are not DSDB attribute that we don't want to copy

commit 245b27774995b6ee8aef4b14bb3dc5518fc733d1
Author: Matthieu Patou <mat at matws.net>
Date:   Tue Jun 14 00:27:07 2011 +0400

    s4: fix wrong index usage PRIMARY_USER_SID_INDEX when it should have been PRIMARY_GROUP_SID_INDEX
    
    The system account was instanciated with wrong user an group SIDs, group
    sid resulted being just the domain SID.
    Bug seems to date from fbe6d155bf177c610ee549cc534650b0f0700e8a.
    
    Andrew (B.) please check.

commit 930d2f28c99d5cf8823ca0837a632e13cead9fce
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 23:23:05 2011 +0400

    s4-upgradeprovision: if there is nothing to really modify then skip it

commit 0e729149259055e9310c1dee78fce71a744006ab
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 22:59:35 2011 +0400

    s4-upgradeprovision: dn must be skipped as delta.remove("dn") do not remove this attribute

commit f76c206e2fd9af47767816e6b284e3742672b21a
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 18:49:23 2011 +0400

    s4-upgradeprovision: change hashAttrNotCopied to be an array

commit 4305f54b8ef9fdcc1ca075b991e9dadab4b485c7
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 19 00:02:03 2011 +0400

    s4-upgradeprovision: fix inverted logic and wrong flags on sd_flags control

commit 01758595e3c01751f259e5b2edaf07beb982ed76
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 18:37:51 2011 +0400

    s4-upgradeprovision: remove useless code

commit 44c540625216b7f9754f7e9461bbd5d026a1e9cf
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 17:15:37 2011 +0400

    s4-upgradeprovision: don't print dn in the list of modified attributes

commit 9a18e07b4f186751cb25dfc0f947e6e5ca8f2fee
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 17:56:17 2011 +0400

    s4-upgradeprovision: clean up, reformating and update docs

commit 20233cdf535b55ee3832d4844eb2109cccab5837
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 17:39:06 2011 +0400

    s4-upgradeprovision: introduce invocation id in lastprovisionUSNs

commit 71ab462c81b48169b34d60dd2bbeca137a15b702
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 18:34:49 2011 +0400

    s4-upgradeprovision: add function to know if attribute is replicated or not

commit d9abcc93847fedf3ca272fe69cde0a92e76c85d0
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 17:50:00 2011 +0400

    s4-upgradeprovision: split update_present in two functions depending on the method used
    
    In order to make the function a bit more clearer and with less depth,
    the selection of attribute that are not updated is split in two
    functions depending on the fact that we are using mainly
    replPropertyMetadata to make our choice or if we are using the list of
    attributes that should, could or shouldn't be updated/created/deleted.

commit 0065742909453f85709635aa44787b6998cccfc3
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 17:13:26 2011 +0400

    s4-upgradeprovision: handle_special_attributes don't really need ranges of USNs, just the information if we are using replPropertyMetadata for attribute selection

commit 45df4d81ed37f6d470e3f42a310a6e5f0afa06bf
Author: Matthieu Patou <mat at matws.net>
Date:   Mon Jun 13 16:09:14 2011 +0400

    s4-python: fix wrong discovery of the site name in find_key_provision_parameters

commit 5db07d2f42e6bbc0023a504f30b9dcc8fd31b230
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 5 17:39:32 2011 +0400

    s4-upgradeprovisision: fix bug 8063, old SD can miss some componenent (group, owner, ...)
    
    Don't make the assumption that SD are correct, they can be wrong and
    misformed.
    
    Fix this bug: https://bugzilla.samba.org/show_bug.cgi?id=8063

commit b14bdf431b49a674bceab7f8f81ae98d938b92f6
Author: Matthieu Patou <mat at matws.net>
Date:   Sun Jun 5 17:26:07 2011 +0400

    s4-upgradeprovision: Fix an error, so that cursddl and refsddl are not the same
    
    Thanks to Dirk Paulli for pointing it with his bug report.

commit 02970f41a27bd4614d6aedf0fe337619b34310db
Author: Matthieu Patou <mat at matws.net>
Date:   Sat Jun 11 16:57:02 2011 +0400

    py-ldb: allow dictionnary like usage (ie. e.get("myattribute", defVal)

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

Summary of changes:
 source4/auth/system_session.c                      |    2 +-
 source4/lib/ldb/pyldb.c                            |   11 +-
 source4/scripting/bin/findprovisionusnranges       |  174 ++++++
 source4/scripting/bin/upgradeprovision             |  614 ++++++++++++--------
 .../scripting/python/samba/{netcmd => }/common.py  |   21 +-
 source4/scripting/python/samba/netcmd/dbcheck.py   |  183 +++----
 .../scripting/python/samba/provision/__init__.py   |   73 ++-
 source4/scripting/python/samba/upgradehelpers.py   |   53 +-
 source4/setup/provision_configuration.ldif         |    1 -
 9 files changed, 730 insertions(+), 402 deletions(-)
 create mode 100755 source4/scripting/bin/findprovisionusnranges
 copy source4/scripting/python/samba/{netcmd => }/common.py (63%)


Changeset truncated at 500 lines:

diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c
index 54b8f51..3b9edd7 100644
--- a/source4/auth/system_session.c
+++ b/source4/auth/system_session.c
@@ -190,7 +190,7 @@ static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx,
 	sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR);
 
 	user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
-	sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS);
+	sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS);
 
 	user_info_dc->sids[2] = global_sid_Builtin_Administrators;
 
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index 61662f6..b568bc2 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -2442,15 +2442,20 @@ static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
 
 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
 {
-	PyObject *name, *ret;
-	if (!PyArg_ParseTuple(args, "O", &name))
+	PyObject *name, *ret, *retobj;
+	retobj = NULL;
+	if (!PyArg_ParseTuple(args, "O|O", &name, &retobj))
 		return NULL;
 
 	ret = py_ldb_msg_getitem_helper(self, name);
 	if (ret == NULL) {
 		if (PyErr_Occurred())
 			return NULL;
-		Py_RETURN_NONE;
+		if (retobj != NULL) {
+			return retobj;
+		} else {
+			Py_RETURN_NONE;
+		}
 	}
 	return ret;
 }
diff --git a/source4/scripting/bin/findprovisionusnranges b/source4/scripting/bin/findprovisionusnranges
new file mode 100755
index 0000000..c91e42e
--- /dev/null
+++ b/source4/scripting/bin/findprovisionusnranges
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+#
+# Helper for determining USN ranges created of modified by provision and
+# upgradeprovision.
+# Copyright (C) Matthieu Patou <mat at matws.net> 2009-2011
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys
+import optparse
+import tempfile
+sys.path.insert(0, "bin/python")
+
+from samba.credentials import DONT_USE_KERBEROS
+from samba.auth import system_session
+from samba import Ldb
+import ldb
+                
+import samba.getopt as options
+from samba import param
+from samba import _glue
+from samba.upgradehelpers import get_paths
+from samba.ndr import ndr_unpack
+from samba.dcerpc import drsblobs, misc
+
+parser = optparse.OptionParser("provision [options]")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--storedir", type="string", help="Directory where to store result files")
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+opts = parser.parse_args()[0]
+lp = sambaopts.get_loadparm()
+smbconf = lp.configfile
+
+creds = credopts.get_credentials(lp)
+creds.set_kerberos_state(DONT_USE_KERBEROS)
+session = system_session()
+paths = get_paths(param, smbconf=smbconf)
+basedn="DC=" + lp.get("realm").replace(".",",DC=")
+samdb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp)
+
+hash_id = {}
+ldif = ""
+nb_obj = 0
+
+res = samdb.search(base="", scope=ldb.SCOPE_BASE, attrs=["dsServiceName"])
+
+invocation = None
+if res and len(res) == 1 and res[0]["dsServiceName"] != None:
+    dn = ldb.Dn(samdb, str(res[0]["dsServiceName"]))
+    res = samdb.search(base=str(dn), scope=ldb.SCOPE_BASE, attrs=["invocationId"],
+                        controls=["search_options:1:2"])
+
+    if res and len(res) == 1 and res[0]["invocationId"]:
+        invocation = str(ndr_unpack(misc.GUID, res[0]["invocationId"][0]))   
+    else:
+        print "Unable to find invocation ID"
+        sys.exit(1)
+else:
+    print "Unable to find attribute dsServiceName in rootDSE"
+    sys.exit(1)
+
+res = samdb.search(base=basedn, expression="objectClass=*",
+                                scope=ldb.SCOPE_SUBTREE,
+                                attrs=["replPropertyMetaData"],
+                                controls=["search_options:1:2"])
+
+for e in res:
+    nb_obj = nb_obj + 1
+    obj = ndr_unpack(drsblobs.replPropertyMetaDataBlob,
+                        str(e["replPropertyMetaData"])).ctr
+
+    for o in obj.array:
+        # like a timestamp but with the resolution of 1 minute
+        minutestamp =_glue.nttime2unix(o.originating_change_time)/60
+        hash_ts = hash_id.get(str(o.originating_invocation_id))
+        if hash_ts == None:
+            ob = {}
+            ob["min"] = o.originating_usn
+            ob["max"] = o.originating_usn
+            ob["num"] = 1
+            ob["list"] = [str(e.dn)]
+            hash_ts = {}
+        else:
+            ob = hash_ts.get(minutestamp)
+            if ob == None:
+                ob = {}
+                ob["min"] = o.originating_usn
+                ob["max"] = o.originating_usn
+                ob["num"] = 1
+                ob["list"] = [str(e.dn)]
+            else:
+                if ob["min"] > o.originating_usn:
+                    ob["min"] = o.originating_usn
+                if ob["max"] < o.originating_usn:
+                    ob["max"] = o.originating_usn
+                if not (str(e.dn) in ob["list"]):
+                    ob["num"] = ob["num"] + 1
+                    ob["list"].append(str(e.dn))
+        hash_ts[minutestamp] = ob
+        hash_id[str(o.originating_invocation_id)] = hash_ts
+
+minobj = 5
+print "Here is a list of changes that modified more than %d objects in 1 minute." % minobj
+print "Usually changes made by provision and upgradeprovision are those who affect a couple"\
+        " of hundred of objects or more"
+print "Total number of objects: %d" % nb_obj
+print 
+
+for id in hash_id:
+    hash_ts = hash_id[id]
+    sorted_keys = []
+    sorted_keys.extend(hash_ts.keys())
+    sorted_keys.sort()
+
+    kept_record = []
+    for k in sorted_keys:
+        obj = hash_ts[k]
+        if obj["num"] > minobj:
+            dt = _glue.nttime2string(_glue.unix2nttime(k*60))
+            print "%s # of modification: %d  \tmin: %d max: %d" % (dt , obj["num"],
+                                                                obj["min"],
+                                                                obj["max"])
+        if hash_ts[k]["num"] > 600:
+            kept_record.append(k)
+
+    # Let's try to concatenate consecutive block if they are in the almost same minutestamp
+    for i in range(0, len(kept_record)):
+        if i != 0:
+            key1 = kept_record[i]
+            key2 = kept_record[i-1]
+            if key1 - key2 == 1:
+                # previous record is just 1 minute away from current
+                if int(hash_ts[key1]["min"]) == int(hash_ts[key2]["max"]) + 1:
+                    # Copy the highest USN in the previous record
+                    # and mark the current as skipped
+                    hash_ts[key2]["max"] = hash_ts[key1]["max"]
+                    hash_ts[key1]["skipped"] = True
+
+    for k in kept_record:
+            obj = hash_ts[k]
+            if obj.get("skipped") == None:
+                ldif = "%slastProvisionUSN: %d-%d;%s\n" % (ldif, obj["min"],
+                            obj["max"], id) 
+
+if ldif != "":
+    dest = opts.storedir
+    if dest == None:
+        dest = "/tmp"
+
+    file = tempfile.mktemp(dir=dest, prefix="usnprov", suffix=".ldif")        
+    print 
+    print "To track the USNs modified/created by provision and upgrade proivsion,"
+    print " the following ranges are proposed to be added to your provision sam.ldb: \n%s" % ldif
+    print "We recommend to review them, and if it's correct to integrate the following ldif: %s in your sam.ldb" % file
+    print "You can load this file like this: ldbadd -H %s %s\n"%(str(paths.samdb),file)
+    ldif = "dn: @PROVISION\nprovisionnerID: %s\n%s" % (invocation, ldif)
+    open(file,'w').write(ldif)
+
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index e58a264..f10a9fc 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -42,8 +42,9 @@ from samba.credentials import DONT_USE_KERBEROS
 from samba.auth import system_session, admin_session
 from ldb import (SCOPE_SUBTREE, SCOPE_BASE,
                 FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE,
-                MessageElement, Message, Dn)
+                MessageElement, Message, Dn, LdbError)
 from samba import param, dsdb, Ldb
+from samba.common import confirm
 from samba.provision import (get_domain_descriptor, find_provision_key_parameters,
                             get_config_descriptor,
                             ProvisioningError, get_last_provision_usn,
@@ -81,20 +82,25 @@ __docformat__ = "restructuredText"
 # This is most probably because they are populated automatcally when object is
 # created
 # This also apply to imported object from reference provision
-hashAttrNotCopied = {   "dn": 1, "whenCreated": 1, "whenChanged": 1,
-                        "objectGUID": 1, "uSNCreated": 1,
-                        "replPropertyMetaData": 1, "uSNChanged": 1,
-                        "parentGUID": 1, "objectCategory": 1,
-                        "distinguishedName": 1, "nTMixedDomain": 1,
-                        "showInAdvancedViewOnly": 1, "instanceType": 1,
-                        "msDS-Behavior-Version":1, "nextRid":1, "cn": 1,
-                        "lmPwdHistory":1, "pwdLastSet": 1,
-                        "ntPwdHistory":1, "unicodePwd":1,"dBCSPwd":1,
-                        "supplementalCredentials":1, "gPCUserExtensionNames":1,
-                        "gPCMachineExtensionNames":1,"maxPwdAge":1, "secret":1,
-                        "possibleInferiors":1, "privilege":1,
-                        "sAMAccountType":1 }
+replAttrNotCopied = [   "dn", "whenCreated", "whenChanged", "objectGUID",
+                        "parentGUID", "objectCategory", "distinguishedName",
+                        "nTMixedDomain", "showInAdvancedViewOnly",
+                        "instanceType", "msDS-Behavior-Version", "cn",
+                        "lmPwdHistory", "pwdLastSet", "ntPwdHistory",
+                        "unicodePwd", "dBCSPwd", "supplementalCredentials",
+                        "gPCUserExtensionNames", "gPCMachineExtensionNames",
+                        "maxPwdAge", "secret", "possibleInferiors", "privilege",
+                        "sAMAccountType", "oEMInformation", "creationTime" ]
 
+nonreplAttrNotCopied = ["uSNCreated", "replPropertyMetaData", "uSNChanged",
+                        "nextRid" ,"rIDNextRID"]
+
+nonDSDBAttrNotCopied = ["msDS-KeyVersionNumber", "priorSecret", "priorWhenChanged"]
+
+
+attrNotCopied = replAttrNotCopied
+attrNotCopied.extend(nonreplAttrNotCopied)
+attrNotCopied.extend(nonDSDBAttrNotCopied)
 # Usually for an object that already exists we do not overwrite attributes as
 # they might have been changed for good reasons. Anyway for a few of them it's
 # mandatory to replace them otherwise the provision will be broken somehow.
@@ -108,15 +114,19 @@ hashOverwrittenAtt = {  "prefixMap": replace, "systemMayContain": replace,
                         "wellKnownObjects":replace, "privilege":never,
                         "defaultSecurityDescriptor": replace,
                         "rIDAvailablePool": never,
+                        "versionNumber" : add,
                         "rIDNextRID": add, "rIDUsedPool": never,
                         "defaultSecurityDescriptor": replace + add,
                         "isMemberOfPartialAttributeSet": delete,
                         "attributeDisplayNames": replace + add,
                         "versionNumber": add}
 
+dnNotToRecalculate = []
+dnToRecalculate = []
 backlinked = []
 forwardlinked = set()
 dn_syntax_att = []
+not_replicated = []
 def define_what_to_log(opts):
     what = 0
     if opts.debugchange:
@@ -238,6 +248,25 @@ def populate_links(samdb, schemadn):
     for t in linkedAttHash.keys():
         forwardlinked.add(t)
 
+def isReplicated(att):
+    """ Indicate if the attribute is replicated or not
+
+    :param att: Name of the attribute to be tested
+    :return: True is the attribute is replicated, False otherwise
+    """
+
+    return (att not in not_replicated)
+
+def populateNotReplicated(samdb, schemadn):
+    """Populate an array with all the attributes that are not replicated
+
+    :param samdb: A LDB object for sam.ldb file
+    :param schemadn: DN of the schema for the partition"""
+    res = samdb.search(expression="(&(objectclass=attributeSchema)(systemflags:1.2.840.113556.1.4.803:=1))", base=Dn(samdb,
+                        str(schemadn)), scope=SCOPE_SUBTREE,
+                        attrs=["lDAPDisplayName"])
+    for elem in res:
+        not_replicated.append(elem["lDAPDisplayName"])
 
 def populate_dnsyntax(samdb, schemadn):
     """Populate an array with all the attributes that have DN synthax
@@ -297,7 +326,7 @@ def print_provision_key_parameters(names):
     message(GUESS, "domainlevel :" + str(names.domainlevel))
 
 
-def handle_special_case(att, delta, new, old, usn, basedn, aldb):
+def handle_special_case(att, delta, new, old, useReplMetadata, basedn, aldb):
     """Define more complicate update rules for some attributes
 
     :param att: The attribute to be updated
@@ -305,7 +334,8 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb):
                   between the updated object and the reference one
     :param new: The reference object
     :param old: The Updated object
-    :param usn: The highest usn modified by a previous (upgrade)provision
+    :param useReplMetadata: A boolean that indicate if the update process
+                use replPropertyMetaData to decide what has to be updated.
     :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
@@ -315,7 +345,7 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb):
     # We do most of the special case handle if we do not have the
     # highest usn as otherwise the replPropertyMetaData will guide us more
     # correctly
-    if usn is None:
+    if not useReplMetadata:
         if (att == "sPNMappings" and flag == FLAG_MOD_REPLACE and
             ldb.Dn(aldb, "CN=Directory Service,CN=Windows NT,"
                         "CN=Services,CN=Configuration,%s" % basedn)
@@ -391,14 +421,14 @@ def handle_special_case(att, delta, new, old, usn, basedn, aldb):
     if (att == "servicePrincipalName" and flag == FLAG_MOD_REPLACE):
         hash = {}
         newval = []
-        changeDelta=0
+        changeDelta = 0
         for elem in old[0][att]:
             hash[str(elem)]=1
             newval.append(str(elem))
 
         for elem in new[0][att]:
             if not hash.has_key(str(elem)):
-                changeDelta=1
+                changeDelta = 1
                 newval.append(str(elem))
         if changeDelta == 1:
             delta[att] = MessageElement(newval, FLAG_MOD_REPLACE, att)
@@ -585,7 +615,7 @@ def add_missing_object(ref_samdb, samdb, dn, names, basedn, hash, index):
             m = re.match(r".*-(\d+)$", sid)
             if m and int(m.group(1))>999:
                 delta.remove("objectSid")
-        for att in hashAttrNotCopied.keys():
+        for att in attrNotCopied:
             delta.remove(att)
         for att in backlinked:
             delta.remove(att)
@@ -652,7 +682,7 @@ def add_deletedobj_containers(ref_samdb, samdb, names):
             delta = samdb.msg_diff(empty, reference[0])
 
             delta.dn = Dn(samdb, str(reference[0]["dn"]))
-            for att in hashAttrNotCopied.keys():
+            for att in attrNotCopied:
                 delta.remove(att)
 
             modcontrols = ["relax:0", "provision:0"]
@@ -773,8 +803,192 @@ msg_elt_flag_strs = {
     ldb.FLAG_MOD_REPLACE: "MOD_REPLACE",
     ldb.FLAG_MOD_DELETE: "MOD_DELETE" }
 
+def checkKeepAttributeOldMtd(delta, att, reference, current,
+                                    basedn, samdb):
+    """ Check if we should keep the attribute modification or not.
+        This function didn't use replicationMetadata to take a decision.
+
+        :param delta: A message diff object
+        :param att: An attribute
+        :param reference: A message object for the current entry comming from
+                            the reference provision.
+        :param current: A message object for the current entry commin from
+                            the current provision.
+        :param basedn: The DN of the partition
+        :param samdb: A ldb connection to the sam database of the current provision.
+
+        :return: The modified message diff.
+    """
+    # Old school way of handling things for pre alpha12 upgrade
+    global defSDmodified
+    isFirst = False
+    txt = ""
+    dn = current[0].dn
+
+    for att in list(delta):
+        msgElt = delta.get(att)
 
-def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
+        if att == "nTSecurityDescriptor":
+            defSDmodified = True
+            delta.remove(att)
+            continue
+
+        if att == "dn":
+            continue
+
+        if not hashOverwrittenAtt.has_key(att):
+            if msgElt.flags() != FLAG_MOD_ADD:
+                if not handle_special_case(att, delta, reference, current,
+                                            False, basedn, samdb):
+                    if opts.debugchange or opts.debugall:
+                        try:
+                            dump_denied_change(dn, att,
+                                msg_elt_flag_strs[msgElt.flags()],
+                                current[0][att], reference[0][att])
+                        except KeyError:
+                            dump_denied_change(dn, att,
+                                msg_elt_flag_strs[msgElt.flags()],
+                                current[0][att], None)
+                    delta.remove(att)
+                continue
+        else:
+            if hashOverwrittenAtt.get(att)&2**msgElt.flags() :
+                continue
+            elif  hashOverwrittenAtt.get(att)==never:
+                delta.remove(att)
+                continue
+
+    return delta
+
+def checkKeepAttributeWithMetadata(delta, att, message, reference, current,
+                                    hash_attr_usn, basedn, usns, samdb):
+    """ Check if we should keep the attribute modification or not
+
+        :param delta: A message diff object
+        :param att: An attribute
+        :param message: A function to print messages
+        :param reference: A message object for the current entry comming from
+                            the reference provision.
+        :param current: A message object for the current entry commin from
+                            the current provision.
+        :param hash_attr_usn: A dictionnary with attribute name as keys,
+                                USN and invocation id as values.
+        :param basedn: The DN of the partition
+        :param usns: A dictionnary with invocation ID as keys and USN ranges
+                     as values.
+        :param samdb: A ldb object pointing to the sam DB
+
+        :return: The modified message diff.
+    """
+    global defSDmodified
+    isFirst = True
+    txt = ""
+    dn = current[0].dn
+
+    for att in list(delta):
+        if att in ["dn", "objectSid"]:
+            delta.remove(att)
+            continue
+
+        # We have updated by provision usn information so let's exploit
+        # replMetadataProperties
+        if att in forwardlinked:
+            curval = current[0].get(att, ())
+            refval = reference[0].get(att, ())
+            handle_links(samdb, att, basedn, current[0]["dn"],
+                            curval, refval, delta)
+            continue
+
+        if isFirst and len(delta.items())>1:
+            isFirst = False
+            txt = "%s\n" % (str(dn))
+
+        if handle_special_case(att, delta, reference, current, True, None, None):
+            # This attribute is "complicated" to handle and handling
+            # was done in handle_special_case
+            continue
+
+        attrUSN = None
+        if hash_attr_usn.get(att):
+            [attrUSN, attInvId] = hash_attr_usn.get(att)
+
+        if attrUSN is None:
+            # If it's a replicated attribute and we don't have any USN


-- 
Samba Shared Repository


More information about the samba-cvs mailing list