[SCM] Samba Shared Repository - branch master updated
Andrew Tridgell
tridge at samba.org
Mon Feb 15 03:57:56 MST 2010
The branch, master has been updated
via 2dff1f4... s4-test: use local ldb for urgent_replication test
via 3035c7c... s4-ldb: fixed permissions on urgent_replication.py
via 1ca2bd7... s4-test: minor fixes to urgent_replication.py
via f5de126... s4-drs: Test situations for Urgent Replication
via cf1ed06... s4-drs: Function for accessing dsdb_load_partition_usn from Python
via 5aa42f8... s4-drs: Fixes bugs regarding Urgent Replication on wrong situations
from ddbda92... spoolss: disable GetPrinterDriver level 101 (as called by XP).
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 2dff1f45f72f77dd94fcab6552e2c957df9aac5f
Author: Andrew Tridgell <tridge at samba.org>
Date: Mon Feb 15 21:21:55 2010 +1100
s4-test: use local ldb for urgent_replication test
This test only currently works on a local ldb, as it needs system
access.
commit 3035c7c2ad2cb41ca01405ea7b2566fcc058fbe7
Author: Andrew Tridgell <tridge at samba.org>
Date: Mon Feb 15 21:18:13 2010 +1100
s4-ldb: fixed permissions on urgent_replication.py
commit 1ca2bd78b95ad5a0852620ba56481f19a9d3a084
Author: Andrew Tridgell <tridge at samba.org>
Date: Mon Feb 15 21:14:42 2010 +1100
s4-test: minor fixes to urgent_replication.py
- fix usage name
- remove unnecessary python functions
- remote unused gc ldb
commit f5de126b858cdfed5c763662dce270a7c4e42e57
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date: Thu Feb 4 17:03:41 2010 -0200
s4-drs: Test situations for Urgent Replication
Checks if the partition's uSNUrgent is updated or not, depending
on the class of the object which is created, modified or deleted.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit cf1ed0678acaf1a802d4b90c464edb638ab1364f
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date: Thu Feb 4 16:58:31 2010 -0200
s4-drs: Function for accessing dsdb_load_partition_usn from Python
Returns both uSNHighest and uSNUrgent as a dict object in Python
from a given partition dn.
Signed-off-by: Andrew Tridgell <tridge at samba.org>
commit 5aa42f8010d0895b5bc5018567c431f79c40f8f6
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date: Thu Feb 4 16:46:52 2010 -0200
s4-drs: Fixes bugs regarding Urgent Replication on wrong situations
It fixes the bug which causes an urgent replication to be enabled
incorrectly when an object is modified, but it should happen only
when it was created. This patch also fixes the bug that enable an
urgent replication when an object is deleted, but it should happen
only when it was modified and fixes the bug that does not enable
an urgent replication when an object is deleted and it should happen
only when it is deleted (not when it is modified).
Signed-off-by: Andrew Tridgell <tridge at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 23 +-
source4/lib/ldb/tests/python/urgent_replication.py | 391 ++++++++++++++++++++
source4/scripting/python/pyglue.c | 50 +++
source4/selftest/tests.sh | 1 +
4 files changed, 458 insertions(+), 7 deletions(-)
create mode 100755 source4/lib/ldb/tests/python/urgent_replication.py
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 725ba2a..51611ac 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -92,7 +92,7 @@ struct replmd_replicated_request {
enum urgent_situation {
REPL_URGENT_ON_CREATE = 1,
- REPL_URGENT_ON_UPDATE = 3, /* activated on creating as well*/
+ REPL_URGENT_ON_UPDATE = 2,
REPL_URGENT_ON_DELETE = 4
};
@@ -103,10 +103,10 @@ static const struct {
} urgent_objects[] = {
{"nTDSDSA", (REPL_URGENT_ON_CREATE | REPL_URGENT_ON_DELETE)},
{"crossRef", (REPL_URGENT_ON_CREATE | REPL_URGENT_ON_DELETE)},
- {"attributeSchema", REPL_URGENT_ON_UPDATE},
- {"classSchema", REPL_URGENT_ON_UPDATE},
- {"secret", REPL_URGENT_ON_UPDATE},
- {"rIDManager", REPL_URGENT_ON_UPDATE},
+ {"attributeSchema", (REPL_URGENT_ON_CREATE | REPL_URGENT_ON_UPDATE)},
+ {"classSchema", (REPL_URGENT_ON_CREATE | REPL_URGENT_ON_UPDATE)},
+ {"secret", (REPL_URGENT_ON_CREATE | REPL_URGENT_ON_UPDATE)},
+ {"rIDManager", (REPL_URGENT_ON_CREATE | REPL_URGENT_ON_UPDATE)},
{NULL, 0}
};
@@ -1077,6 +1077,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
struct ldb_result *res;
struct ldb_context *ldb;
struct ldb_message_element *objectclass_el;
+ enum urgent_situation situation;
ldb = ldb_module_get_ctx(module);
@@ -1098,9 +1099,17 @@ static int replmd_update_rpmd(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
+ /* if isDeleted is present and is TRUE, then we consider we are deleting,
+ * otherwise we consider we are updating */
+ if (ldb_msg_check_string_attribute(msg, "isDeleted", "TRUE")) {
+ situation = REPL_URGENT_ON_DELETE;
+ } else {
+ situation = REPL_URGENT_ON_UPDATE;
+ }
+
objectclass_el = ldb_msg_find_element(res->msgs[0], "objectClass");
if (is_urgent && replmd_check_urgent_objectclass(objectclass_el,
- REPL_URGENT_ON_UPDATE)) {
+ situation)) {
*is_urgent = true;
}
@@ -1133,7 +1142,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
return ret;
}
- if (is_urgent && !*is_urgent) {
+ if (is_urgent && !*is_urgent && (situation == REPL_URGENT_ON_UPDATE)) {
*is_urgent = replmd_check_urgent_attribute(&msg->elements[i]);
}
diff --git a/source4/lib/ldb/tests/python/urgent_replication.py b/source4/lib/ldb/tests/python/urgent_replication.py
new file mode 100755
index 0000000..752a95e
--- /dev/null
+++ b/source4/lib/ldb/tests/python/urgent_replication.py
@@ -0,0 +1,391 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# This is a port of the original in testprogs/ejs/ldap.js
+
+import getopt
+import optparse
+import sys
+import time
+import random
+import base64
+import os
+
+sys.path.append("bin/python")
+sys.path.append("../lib/subunit/python")
+
+import samba.getopt as options
+
+from samba.auth import system_session
+from ldb import SCOPE_BASE, LdbError
+from ldb import ERR_NO_SUCH_OBJECT
+from ldb import Message, MessageElement, Dn
+from ldb import FLAG_MOD_REPLACE
+from samba import Ldb
+from samba import glue
+
+from subunit.run import SubunitTestRunner
+import unittest
+
+from samba.ndr import ndr_pack, ndr_unpack
+from samba.dcerpc import security
+
+parser = optparse.OptionParser("urgent_replication [options] <host>")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+# use command line creds if available
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+opts, args = parser.parse_args()
+
+if len(args) < 1:
+ parser.print_usage()
+ sys.exit(1)
+
+host = args[0]
+
+lp = sambaopts.get_loadparm()
+creds = credopts.get_credentials(lp)
+
+class UrgentReplicationTests(unittest.TestCase):
+
+ def delete_force(self, ldb, dn):
+ try:
+ ldb.delete(dn)
+ except LdbError, (num, _):
+ self.assertEquals(num, ERR_NO_SUCH_OBJECT)
+
+ def find_basedn(self, ldb):
+ res = ldb.search(base="", expression="", scope=SCOPE_BASE,
+ attrs=["defaultNamingContext"])
+ self.assertEquals(len(res), 1)
+ return res[0]["defaultNamingContext"][0]
+
+ def setUp(self):
+ self.ldb = ldb
+ self.base_dn = self.find_basedn(ldb)
+
+ print "baseDN: %s\n" % self.base_dn
+
+ def test_nonurgent_object(self):
+ '''Test if the urgent replication is not activated
+ when handling a non urgent object'''
+ self.ldb.add({
+ "dn": "cn=nonurgenttest,cn=users," + self.base_dn,
+ "objectclass":"user",
+ "samaccountname":"nonurgenttest",
+ "description":"nonurgenttest description"});
+
+ ''' urgent replication should not be enabled when creating '''
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should not be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=nonurgenttest,cn=users," + self.base_dn)
+ m["description"] = MessageElement("new description", FLAG_MOD_REPLACE,
+ "description")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should not be enabled when deleting '''
+ self.delete_force(self.ldb, "cn=nonurgenttest,cn=users," + self.base_dn)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+ def test_nTDSDSA_object(self):
+ '''Test if the urgent replication is activated
+ when handling a nTDSDSA object'''
+ self.ldb.add({
+ "dn": "cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn,
+ "objectclass":"server",
+ "cn":"test server",
+ "name":"test server",
+ "systemFlags":"50000000"});
+
+ self.ldb.add_ldif(
+ """dn: cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration,%s""" % (self.base_dn) + """
+objectclass: nTDSDSA
+cn: NTDS Settings test
+options: 1
+instanceType: 4
+systemFlags: 33554432""", ["relax:0"]);
+
+ ''' urgent replication should be enabled when creation '''
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should NOT be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn)
+ m["options"] = MessageElement("0", FLAG_MOD_REPLACE,
+ "options")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Configuration," + self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should be enabled when deleting '''
+ self.delete_force(self.ldb, "cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn)
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ self.delete_force(self.ldb, "cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn)
+
+
+ def test_crossRef_object(self):
+ '''Test if the urgent replication is activated
+ when handling a crossRef object'''
+ self.ldb.add({
+ "dn": "CN=test crossRef,CN=Partitions,CN=Configuration,"+ self.base_dn,
+ "objectClass": "crossRef",
+ "cn": "test crossRef",
+ "instanceType": "4",
+ "nCName": self.base_dn,
+ "showInAdvancedViewOnly": "TRUE",
+ "name": "test crossRef",
+ "systemFlags": "1"});
+
+ ''' urgent replication should be enabled when creating '''
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should NOT be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=test crossRef,CN=Partitions,CN=Configuration," + self.base_dn)
+ m["systemFlags"] = MessageElement("0", FLAG_MOD_REPLACE,
+ "systemFlags")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Configuration," + self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+ ''' urgent replication should be enabled when deleting '''
+ self.delete_force(self.ldb, "cn=test crossRef,CN=Partitions,CN=Configuration," + self.base_dn)
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+
+ def test_attributeSchema_object(self):
+ '''Test if the urgent replication is activated
+ when handling an attributeSchema object'''
+
+ try:
+ self.ldb.add_ldif(
+ """dn: CN=test attributeSchema,cn=Schema,CN=Configuration,%s""" % self.base_dn + """
+objectClass: attributeSchema
+cn: test attributeSchema
+instanceType: 4
+isSingleValued: FALSE
+showInAdvancedViewOnly: FALSE
+attributeID: 0.9.2342.19200300.100.1.1
+attributeSyntax: 2.5.5.12
+adminDisplayName: test attributeSchema
+adminDescription: test attributeSchema
+oMSyntax: 64
+systemOnly: FALSE
+searchFlags: 8
+lDAPDisplayName: test attributeSchema
+name: test attributeSchema
+systemFlags: 0""", ["relax:0"]);
+
+ ''' urgent replication should be enabled when creating '''
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Schema,cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ except LdbError:
+ print "Not testing urgent replication when creating attributeSchema object ...\n"
+
+ ''' urgent replication should be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "CN=test attributeSchema,CN=Schema,CN=Configuration," + self.base_dn)
+ m["lDAPDisplayName"] = MessageElement("updated test attributeSchema", FLAG_MOD_REPLACE,
+ "lDAPDisplayName")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Schema,cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+ def test_classSchema_object(self):
+ '''Test if the urgent replication is activated
+ when handling a classSchema object'''
+ try:
+ self.ldb.add_ldif(
+ """dn: CN=test classSchema,CN=Schema,CN=Configuration,%s""" % self.base_dn + """
+objectClass: classSchema
+cn: test classSchema
+instanceType: 4
+subClassOf: top
+governsID: 1.2.840.113556.1.5.999
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: test classSchema
+adminDescription: test classSchema
+objectClassCategory: 1
+lDAPDisplayName: test classSchema
+name: test classSchema
+systemOnly: FALSE
+systemPossSuperiors: dfsConfiguration
+systemMustContain: msDFS-SchemaMajorVersion
+defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD
+ CLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;CO)
+systemFlags: 16
+defaultHidingValue: TRUE""", ["relax:0"]);
+
+ ''' urgent replication should be enabled when creating '''
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Schema,cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ except LdbError:
+ print "Not testing urgent replication when creating classSchema object ...\n"
+
+ ''' urgent replication should be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "CN=test classSchema,CN=Schema,CN=Configuration," + self.base_dn)
+ m["lDAPDisplayName"] = MessageElement("updated test classSchema", FLAG_MOD_REPLACE,
+ "lDAPDisplayName")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, "cn=Schema,cn=Configuration," + self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+ def test_secret_object(self):
+
+ '''Test if the urgent replication is activated
+ when handling a secret object'''
+
+ self.ldb.add({
+ "dn": "cn=test secret,cn=System," + self.base_dn,
+ "objectClass":"secret",
+ "cn":"test secret",
+ "name":"test secret",
+ "currentValue":"xxxxxxx"});
+
+
+ ''' urgent replication should be enabled when creationg '''
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=test secret,cn=System," + self.base_dn)
+ m["currentValue"] = MessageElement("yyyyyyyy", FLAG_MOD_REPLACE,
+ "currentValue")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should NOT be enabled when deleting '''
+ self.delete_force(self.ldb, "cn=test secret,cn=System," + self.base_dn)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+ def test_rIDManager_object(self):
+ '''Test if the urgent replication is activated
+ when handling a rIDManager object'''
+ self.ldb.add_ldif(
+ """dn: CN=RID Manager test,CN=System,%s""" % self.base_dn + """
+objectClass: rIDManager
+cn: RID Manager test
+instanceType: 4
+showInAdvancedViewOnly: TRUE
+name: RID Manager test
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+rIDAvailablePool: 133001-1073741823""", ["relax:0"])
+
+ ''' urgent replication should be enabled when creating '''
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should be enabled when modifying '''
+ m = Message()
+ m.dn = Dn(ldb, "CN=RID Manager test,CN=System," + self.base_dn)
+ m["systemFlags"] = MessageElement("0", FLAG_MOD_REPLACE,
+ "systemFlags")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should NOT be enabled when deleting '''
+ self.delete_force(self.ldb, "CN=RID Manager test,CN=System," + self.base_dn)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+ def test_urgent_attributes(self):
+ '''Test if the urgent replication is activated
+ when handling urgent attributes of an object'''
+
+ self.ldb.add({
+ "dn": "cn=user UrgAttr test,cn=users," + self.base_dn,
+ "objectclass":"user",
+ "samaccountname":"user UrgAttr test",
+ "userAccountControl":"1",
+ "lockoutTime":"0",
+ "pwdLastSet":"0",
+ "description":"urgent attributes test description"});
+
+ ''' urgent replication should NOT be enabled when creating '''
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should be enabled when modifying userAccountControl '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn)
+ m["userAccountControl"] = MessageElement("0", FLAG_MOD_REPLACE,
+ "userAccountControl")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should be enabled when modifying lockoutTime '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn)
+ m["lockoutTime"] = MessageElement("1", FLAG_MOD_REPLACE,
+ "lockoutTime")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should be enabled when modifying pwdLastSet '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn)
+ m["pwdLastSet"] = MessageElement("1", FLAG_MOD_REPLACE,
+ "pwdLastSet")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should NOT be enabled when modifying a not-urgent attribute '''
+ m = Message()
+ m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn)
+ m["description"] = MessageElement("updated urgent attributes test description",
+ FLAG_MOD_REPLACE, "description")
+ ldb.modify(m)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+ ''' urgent replication should NOT be enabled when deleting '''
+ self.delete_force(self.ldb, "cn=user UrgAttr test,cn=users," + self.base_dn)
+ res = glue.dsdb_load_partition_usn(self.ldb, self.base_dn)
+ self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]);
+
+
+if not "://" in host:
+ if os.path.isfile(host):
+ host = "tdb://%s" % host
+ else:
+ host = "ldap://%s" % host
+
+
+ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
+
+runner = SubunitTestRunner()
+rc = 0
+if not runner.run(unittest.makeSuite(UrgentReplicationTests)).wasSuccessful():
+ rc = 1
+sys.exit(rc)
diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c
index 5279a0b..57e6043 100644
--- a/source4/scripting/python/pyglue.c
+++ b/source4/scripting/python/pyglue.c
@@ -438,6 +438,54 @@ static PyObject *py_dsdb_make_schema_global(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+static PyObject *py_dsdb_load_partition_usn(PyObject *self, PyObject *args)
+{
+ PyObject *py_dn, *py_ldb, *result;
+ struct ldb_dn *dn;
+ uint64_t highest_uSN, urgent_uSN;
+ struct ldb_context *ldb;
+ TALLOC_CTX *mem_ctx;
+ int ret;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_dn)) {
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+ if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ ret = dsdb_load_partition_usn(ldb, dn, &highest_uSN, &urgent_uSN);
+ if (ret != LDB_SUCCESS) {
+ char *errstr = talloc_asprintf(mem_ctx, "Failed to load partition uSN - %s", ldb_errstring(ldb));
+ PyErr_SetString(PyExc_RuntimeError, errstr);
--
Samba Shared Repository
More information about the samba-cvs
mailing list