[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Wed Jun 12 03:54:02 MDT 2013
The branch, master has been updated
via 68f8f4e dsdb-tests ldap.py: Add test for usn behaviour on certain changes
via 51298d3 dsdb-tests ldap.py: Fix quoting of print statements
via 96980f7 dsdb: Fix behaviour for when to update the USN when there is no change
via e461ff5 dsdb: Allow dsdb_find_dn_by_guid to show deleted DNs
via eec29db python samba-tool drs: Correctly print KCC references to deleted servers
from 3e66cb7 Fix bug #9932 - Currently the maximum number of aces in an SD is limited to 1000, but Microsoft supports around 1800.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 68f8f4ec4dbbdb20c4c51a6059535b5ef669373f
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 31 14:14:54 2013 +1000
dsdb-tests ldap.py: Add test for usn behaviour on certain changes
This probes when the usn is updated, and when it is not.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Wed Jun 12 11:54:01 CEST 2013 on sn-devel-104
commit 51298d33dd28e034967db38312e0129935a27a66
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 31 11:15:51 2013 +1000
dsdb-tests ldap.py: Fix quoting of print statements
While python didn't mind (oddly) it really confused my editor.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 96980f7c04cc4226ed109654025b8254921f8d58
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 31 14:16:02 2013 +1000
dsdb: Fix behaviour for when to update the USN when there is no change
This handles deletions and replacements with no value, or with an
exactly specified value, as well as modifies.
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Andrew Bartlett
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit e461ff530046199b7e647b81d6dfb2746f68b0d7
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Jun 10 12:22:40 2013 +1000
dsdb: Allow dsdb_find_dn_by_guid to show deleted DNs
This helps us in the KCC as we need to return the deleted DN for the GUID
in DsReplicaGetInfo calls (tested for deleted servers against Windows 2008R2).
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit eec29db7c237c70732f94e33147c960fa8df39fb
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Jun 10 11:43:18 2013 +1000
python samba-tool drs: Correctly print KCC references to deleted servers
Tested against Windows 2008R2, presumably before the KCC ran.
Andrew Bartlett
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
python/samba/netcmd/drs.py | 15 ++-
source4/dsdb/common/util.c | 6 +-
source4/dsdb/kcc/kcc_connection.c | 4 +-
source4/dsdb/kcc/kcc_drs_replica_info.c | 10 +-
source4/dsdb/repl/drepl_partitions.c | 2 +-
source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 34 +++-
source4/dsdb/tests/python/ldap.py | 229 ++++++++++++++++-------
source4/rpc_server/drsuapi/getncchanges.c | 4 +-
8 files changed, 222 insertions(+), 82 deletions(-)
Changeset truncated at 500 lines:
diff --git a/python/samba/netcmd/drs.py b/python/samba/netcmd/drs.py
index ff8d830..de78ac7 100644
--- a/python/samba/netcmd/drs.py
+++ b/python/samba/netcmd/drs.py
@@ -170,10 +170,19 @@ class cmd_drs_showrepl(Command):
self.message("==== KCC CONNECTION OBJECTS ====\n")
for c in conn:
- c_rdn, sep, c_server_dn = c['fromServer'][0].partition(',')
- c_server_res = self.samdb.search(base=c_server_dn, scope=ldb.SCOPE_BASE, attrs=["dnsHostName"])
- c_server_dns = c_server_res[0]["dnsHostName"][0]
self.message("Connection --")
+
+ c_rdn, sep, c_server_dn = c['fromServer'][0].partition(',')
+ try:
+ c_server_res = self.samdb.search(base=c_server_dn, scope=ldb.SCOPE_BASE, attrs=["dnsHostName"])
+ c_server_dns = c_server_res[0]["dnsHostName"][0]
+ except ldb.LdbError, (errno, _):
+ if errno == ldb.ERR_NO_SUCH_OBJECT:
+ self.message("\tWARNING: Connection to DELETED server!")
+ c_server_dns = ""
+ except KeyError:
+ c_server_dns = ""
+
self.message("\tConnection name: %s" % c['name'][0])
self.message("\tEnabled : %s" % attr_default(c, 'enabledConnection', 'TRUE'))
self.message("\tServer DNS name : %s" % c_server_dns)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 8e40776..7a243c3 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2458,7 +2458,9 @@ struct ldb_dn *samdb_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
*/
int dsdb_find_dn_by_guid(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx,
- const struct GUID *guid, struct ldb_dn **dn)
+ const struct GUID *guid,
+ uint32_t dsdb_flags,
+ struct ldb_dn **dn)
{
int ret;
struct ldb_result *res;
@@ -2472,7 +2474,7 @@ int dsdb_find_dn_by_guid(struct ldb_context *ldb,
ret = dsdb_search(ldb, mem_ctx, &res, NULL, LDB_SCOPE_SUBTREE, attrs,
DSDB_SEARCH_SEARCH_ALL_PARTITIONS |
DSDB_SEARCH_SHOW_EXTENDED_DN |
- DSDB_SEARCH_ONE_ONLY,
+ DSDB_SEARCH_ONE_ONLY | dsdb_flags,
"objectGUID=%s", guid_str);
talloc_free(guid_str);
if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/kcc/kcc_connection.c b/source4/dsdb/kcc/kcc_connection.c
index ea63833..f85ed13 100644
--- a/source4/dsdb/kcc/kcc_connection.c
+++ b/source4/dsdb/kcc/kcc_connection.c
@@ -70,7 +70,7 @@ static int kccsrv_add_connection(struct kccsrv_service *s,
ret = LDB_ERR_INVALID_DN_SYNTAX;
goto done;
}
- ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->dsa_guid, &server_dn);
+ ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->dsa_guid, 0, &server_dn);
if (ret != LDB_SUCCESS) {
DEBUG(0, ("failed to find fromServer DN '%s'\n",
GUID_string(tmp_ctx, &conn->dsa_guid)));
@@ -111,7 +111,7 @@ static int kccsrv_delete_connection(struct kccsrv_service *s,
int ret;
tmp_ctx = talloc_new(s);
- ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->obj_guid, &dn);
+ ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->obj_guid, 0, &dn);
if (ret != LDB_SUCCESS) {
DEBUG(0, ("failed to find nTDSConnection's DN: %s\n",
ldb_strerror(ret)));
diff --git a/source4/dsdb/kcc/kcc_drs_replica_info.c b/source4/dsdb/kcc/kcc_drs_replica_info.c
index 7aa7f5a..ac22312 100644
--- a/source4/dsdb/kcc/kcc_drs_replica_info.c
+++ b/source4/dsdb/kcc/kcc_drs_replica_info.c
@@ -533,6 +533,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
neigh->source_dsa_obj_guid = reps_from->source_dsa_obj_guid;
ret = dsdb_find_dn_by_guid(samdb, mem_ctx, &reps_from->source_dsa_obj_guid,
+ DSDB_SEARCH_SHOW_RECYCLED,
&source_dsa_dn);
if (ret != LDB_SUCCESS) {
@@ -544,13 +545,15 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn);
neigh->naming_context_dn = ldb_dn_get_linearized(nc_dn);
- if (dsdb_find_guid_by_dn(samdb, nc_dn, &neigh->naming_context_obj_guid)
+ if (dsdb_find_guid_by_dn(samdb, nc_dn,
+ &neigh->naming_context_obj_guid)
!= LDB_SUCCESS) {
return WERR_DS_DRA_INTERNAL_ERROR;
}
if (!GUID_all_zero(&reps_from->transport_guid)) {
ret = dsdb_find_dn_by_guid(samdb, mem_ctx, &reps_from->transport_guid,
+ DSDB_SEARCH_SHOW_RECYCLED,
&transport_obj_dn);
if (ret != LDB_SUCCESS) {
return WERR_DS_DRA_INTERNAL_ERROR;
@@ -668,7 +671,10 @@ static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx,
neigh->last_attempt = reps_to->last_attempt;
neigh->source_dsa_obj_guid = reps_to->source_dsa_obj_guid;
- ret = dsdb_find_dn_by_guid(samdb, mem_ctx, &reps_to->source_dsa_obj_guid, &source_dsa_dn);
+ ret = dsdb_find_dn_by_guid(samdb, mem_ctx,
+ &reps_to->source_dsa_obj_guid,
+ DSDB_SEARCH_SHOW_RECYCLED,
+ &source_dsa_dn);
if (ret != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n",
GUID_string(mem_ctx, &reps_to->source_dsa_obj_guid)));
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 2a16a45..4c5dde2 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -172,7 +172,7 @@ NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
tmp_ctx = talloc_new(mem_ctx);
/* we need to find their hostname */
- ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &rft->source_dsa_obj_guid, &ntds_dn);
+ ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &rft->source_dsa_obj_guid, 0, &ntds_dn);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
/* its OK for their NTDSDSA DN not to be in our database */
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 24dcc6f..0f2aa58 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -1086,6 +1086,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
uint32_t i;
const struct dsdb_attribute *a;
struct replPropertyMetaData1 *md1;
+ bool may_skip = false;
a = dsdb_attribute_by_lDAPDisplayName(schema, el->name);
if (a == NULL) {
@@ -1104,13 +1105,34 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
return LDB_SUCCESS;
}
- /* if the attribute's value haven't changed then return LDB_SUCCESS
- * Unless we have the provision control or if the attribute is
- * interSiteTopologyGenerator as this page explain: http://support.microsoft.com/kb/224815
- * this attribute is periodicaly written by the DC responsible for the intersite generation
- * in a given site
+ /*
+ * if the attribute's value haven't changed, and this isn't
+ * just a delete of everything then return LDB_SUCCESS Unless
+ * we have the provision control or if the attribute is
+ * interSiteTopologyGenerator as this page explain:
+ * http://support.microsoft.com/kb/224815 this attribute is
+ * periodicaly written by the DC responsible for the intersite
+ * generation in a given site
+ *
+ * Unchanged could be deleting or replacing an already-gone
+ * thing with an unconstrained delete/empty replace or a
+ * replace with the same value, but not an add with the same
+ * value because that could be about adding a duplicate (which
+ * is for someone else to error out on).
*/
- if (old_el != NULL && ldb_msg_element_compare(el, old_el) == 0) {
+ if (old_el != NULL && ldb_msg_element_equal_ordered(el, old_el)) {
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) {
+ may_skip = true;
+ }
+ } else if (old_el == NULL && el->num_values == 0) {
+ if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) {
+ may_skip = true;
+ } else if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
+ may_skip = true;
+ }
+ }
+
+ if (may_skip) {
if (strcmp(el->name, "interSiteTopologyGenerator") != 0 &&
!ldb_request_get_control(req, LDB_CONTROL_PROVISION_OID)) {
/*
diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py
index 5ca4c26..0a95b2a 100755
--- a/source4/dsdb/tests/python/ldap.py
+++ b/source4/dsdb/tests/python/ldap.py
@@ -712,7 +712,7 @@ class BasicTests(samba.tests.TestCase):
def test_attribute_ranges(self):
"""Test attribute ranges"""
- print "Test attribute ranges"""
+ print "Test attribute ranges"
# Too short (min. 1)
try:
@@ -833,7 +833,7 @@ class BasicTests(samba.tests.TestCase):
def test_instanceType(self):
"""Tests the 'instanceType' attribute"""
- print "Tests the 'instanceType' attribute"""
+ print "Tests the 'instanceType' attribute"
# The instance type is single-valued
try:
@@ -902,7 +902,7 @@ class BasicTests(samba.tests.TestCase):
def test_distinguished_name(self):
"""Tests the 'distinguishedName' attribute"""
- print "Tests the 'distinguishedName' attribute"""
+ print "Tests the 'distinguishedName' attribute"
# The "dn" shortcut isn't supported
m = Message()
@@ -982,7 +982,7 @@ class BasicTests(samba.tests.TestCase):
def test_rdn_name(self):
"""Tests the RDN"""
- print "Tests the RDN"""
+ print "Tests the RDN"
# Search
@@ -1177,7 +1177,7 @@ objectClass: container
def test_rename(self):
"""Tests the rename operation"""
- print "Tests the rename operations"""
+ print "Tests the rename operations"
try:
# cannot rename to be a child of itself
@@ -1288,7 +1288,7 @@ objectClass: container
def test_rename_twice(self):
"""Tests the rename operation twice - this corresponds to a past bug"""
- print "Tests the rename twice operation"""
+ print "Tests the rename twice operation"
self.ldb.add({
"dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
@@ -1327,60 +1327,6 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
"dn": "cn=ldaptestcontainer," + self.base_dn,
"objectClass": "container" })
- res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
- scope=SCOPE_BASE,
- attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
- self.assertTrue(len(res) == 1)
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("uSNCreated" in res[0])
- self.assertTrue("uSNChanged" in res[0])
- self.assertTrue("whenCreated" in res[0])
- self.assertTrue("whenChanged" in res[0])
-
- delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
-
- # All the following attributes are specificable on add operations
- self.ldb.add({
- "dn": "cn=ldaptestcontainer," + self.base_dn,
- "objectClass": "container",
- "uSNCreated" : "1",
- "uSNChanged" : "1",
- "whenCreated": timestring(long(time.time())),
- "whenChanged": timestring(long(time.time())) })
-
- res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
- scope=SCOPE_BASE,
- attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
- self.assertTrue(len(res) == 1)
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("uSNCreated" in res[0])
- self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
- self.assertTrue("uSNChanged" in res[0])
- self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
-
- delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
-
- # All this attributes are specificable on add operations
- self.ldb.add({
- "dn": "cn=ldaptestcontainer," + self.base_dn,
- "objectclass": "container",
- "uSNCreated" : "1",
- "uSNChanged" : "1",
- "whenCreated": timestring(long(time.time())),
- "whenChanged": timestring(long(time.time())) })
-
- res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
- scope=SCOPE_BASE,
- attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
- self.assertTrue(len(res) == 1)
- self.assertTrue("objectGUID" in res[0])
- self.assertTrue("uSNCreated" in res[0])
- self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
- self.assertTrue("uSNChanged" in res[0])
- self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
- self.assertTrue("whenCreated" in res[0])
- self.assertTrue("whenChanged" in res[0])
-
# The objectGUID cannot directly be changed
try:
self.ldb.modify_ldif("""
@@ -1469,6 +1415,161 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
+ def test_usnChanged(self):
+ """Test usnChanged behaviour"""
+ print "Testing usnChanged behaviour\n"
+
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectClass": "container" })
+
+ res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("description" in res[0])
+ self.assertTrue("objectGUID" in res[0])
+ self.assertTrue("uSNCreated" in res[0])
+ self.assertTrue("uSNChanged" in res[0])
+ self.assertTrue("whenCreated" in res[0])
+ self.assertTrue("whenChanged" in res[0])
+
+ delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
+
+ # All this attributes are specificable on add operations
+ self.ldb.add({
+ "dn": "cn=ldaptestcontainer," + self.base_dn,
+ "objectclass": "container",
+ "uSNCreated" : "1",
+ "uSNChanged" : "1",
+ "whenCreated": timestring(long(time.time())),
+ "whenChanged": timestring(long(time.time())) })
+
+ res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("description" in res[0])
+ self.assertTrue("objectGUID" in res[0])
+ self.assertTrue("uSNCreated" in res[0])
+ self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
+ self.assertTrue("uSNChanged" in res[0])
+ self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
+ self.assertTrue("whenCreated" in res[0])
+ self.assertTrue("whenChanged" in res[0])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+replace: description
+""")
+
+ res2 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("description" in res2[0])
+ self.assertEqual(res[0]["usnCreated"], res2[0]["usnCreated"])
+ self.assertEqual(res[0]["usnCreated"], res2[0]["usnChanged"])
+ self.assertEqual(res[0]["usnChanged"], res2[0]["usnChanged"])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+replace: description
+description: test
+""")
+
+ res3 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res3[0])
+ self.assertEqual("test", str(res3[0]["description"][0]))
+ self.assertEqual(res[0]["usnCreated"], res3[0]["usnCreated"])
+ self.assertNotEqual(res[0]["usnCreated"], res3[0]["usnChanged"])
+ self.assertNotEqual(res[0]["usnChanged"], res3[0]["usnChanged"])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+replace: description
+description: test
+""")
+
+ res4 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res4[0])
+ self.assertEqual("test", str(res4[0]["description"][0]))
+ self.assertEqual(res[0]["usnCreated"], res4[0]["usnCreated"])
+ self.assertNotEqual(res3[0]["usnCreated"], res4[0]["usnChanged"])
+ self.assertEqual(res3[0]["usnChanged"], res4[0]["usnChanged"])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+replace: description
+description: test2
+""")
+
+ res5 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res5[0])
+ self.assertEqual("test2", str(res5[0]["description"][0]))
+ self.assertEqual(res[0]["usnCreated"], res5[0]["usnCreated"])
+ self.assertNotEqual(res3[0]["usnChanged"], res5[0]["usnChanged"])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+delete: description
+description: test2
+""")
+
+ res6 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("description" in res6[0])
+ self.assertEqual(res[0]["usnCreated"], res6[0]["usnCreated"])
+ self.assertNotEqual(res5[0]["usnChanged"], res6[0]["usnChanged"])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+add: description
+description: test3
+""")
+
+ res7 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertTrue("description" in res7[0])
+ self.assertEqual("test3", str(res7[0]["description"][0]))
+ self.assertEqual(res[0]["usnCreated"], res7[0]["usnCreated"])
+ self.assertNotEqual(res6[0]["usnChanged"], res7[0]["usnChanged"])
+
+ ldb.modify_ldif("""
+dn: cn=ldaptestcontainer,""" + self.base_dn + """
+changetype: modify
+delete: description
+""")
+
+ res8 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
+ scope=SCOPE_BASE,
+ attrs=["uSNCreated", "uSNChanged", "description"])
+ self.assertTrue(len(res) == 1)
+ self.assertFalse("description" in res8[0])
+ self.assertEqual(res[0]["usnCreated"], res8[0]["usnCreated"])
+ self.assertNotEqual(res7[0]["usnChanged"], res8[0]["usnChanged"])
+
+ delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
+
def test_groupType_int32(self):
"""Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
print "Testing groupType (int32) behaviour\n"
@@ -1576,7 +1677,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
def test_wkguid(self):
"""Test Well known GUID behaviours (including DN+Binary)"""
- print "Test Well known GUID behaviours (including DN+Binary)"""
+ print "Test Well known GUID behaviours (including DN+Binary)"
res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
self.assertEquals(len(res), 1)
@@ -1593,7 +1694,7 @@ objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
def test_subschemasubentry(self):
"""Test subSchemaSubEntry appears when requested, but not when not requested"""
- print "Test subSchemaSubEntry"""
+ print "Test subSchemaSubEntry"
res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
self.assertEquals(len(res), 1)
@@ -2720,7 +2821,7 @@ nTSecurityDescriptor:: """ + desc_base64
def test_dsheuristics(self):
"""Tests the 'dSHeuristics' attribute"""
- print "Tests the 'dSHeuristics' attribute"""
+ print "Tests the 'dSHeuristics' attribute"
# Get the current value to restore it later
dsheuristics = self.ldb.get_dsheuristics()
@@ -2763,7 +2864,7 @@ nTSecurityDescriptor:: """ + desc_base64
def test_operational(self):
"""Tests operational attributes"""
- print "Tests operational attributes"""
+ print "Tests operational attributes"
res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
attrs=["createTimeStamp", "modifyTimeStamp",
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
index 219ddbc..5ee87cb 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
--
Samba Shared Repository
More information about the samba-cvs
mailing list