PEP8: fix E225: missing whitespace around operator
[nivanova/samba-autobuild/.git] / source4 / dsdb / tests / python / sec_descriptor.py
index 087ce5e2cbe232d674954261dad4f846091ac204..b35529bd9b5a43c2a21cf445e1cef7bf3ee36892 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
+from __future__ import print_function
 import optparse
 import sys
 import os
@@ -10,8 +11,8 @@ import random
 
 sys.path.insert(0, "bin/python")
 import samba
-samba.ensure_external_module("testtools", "testtools")
-samba.ensure_external_module("subunit", "subunit/python")
+
+from samba.tests.subunitrun import SubunitOptions, TestProgram
 
 import samba.getopt as options
 
@@ -19,7 +20,7 @@ import samba.getopt as options
 from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError, ERR_NO_SUCH_OBJECT
 
 # For running the test unit
-from samba.ndr import ndr_pack
+from samba.ndr import ndr_pack, ndr_unpack
 from samba.dcerpc import security
 
 from samba import gensec, sd_utils
@@ -29,10 +30,8 @@ from samba.auth import system_session
 from samba.dsdb import DS_DOMAIN_FUNCTION_2008
 from samba.dcerpc.security import (
     SECINFO_OWNER, SECINFO_GROUP, SECINFO_DACL, SECINFO_SACL)
-from subunit.run import SubunitTestRunner
 import samba.tests
 from samba.tests import delete_force
-import unittest
 
 parser = optparse.OptionParser("sec_descriptor.py [options] <host>")
 sambaopts = options.SambaOptions(parser)
@@ -42,6 +41,9 @@ parser.add_option_group(options.VersionOptions(parser))
 # use command line creds if available
 credopts = options.CredentialsOptions(parser)
 parser.add_option_group(credopts)
+subunitopts = SubunitOptions(parser)
+parser.add_option_group(subunitopts)
+
 opts, args = parser.parse_args()
 
 if len(args) < 1:
@@ -63,24 +65,24 @@ class DescriptorTests(samba.tests.TestCase):
     def get_users_domain_dn(self, name):
         return "CN=%s,CN=Users,%s" % (name, self.base_dn)
 
-    def get_unique_schema_class_name(self):
+    def create_schema_class(self, _ldb, desc=None):
         while True:
-            class_name = "test-class%s" % random.randint(1,100000)
+            class_id = random.randint(0,65535)
+            class_name = "descriptor-test-class%s" % class_id
             class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
             try:
-                self.ldb_admin.search(base=class_dn, attrs=["*"])
-            except LdbError, (num, _):
+                self.ldb_admin.search(base=class_dn, attrs=["name"])
+            except LdbError as e:
+                (num, _) = e.args
                 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
-                return class_name
+                break
 
-    def create_schema_class(self, _ldb, object_dn, desc=None):
         ldif = """
-dn: """ + object_dn + """
+dn: """ + class_dn + """
 objectClass: classSchema
 objectCategory: CN=Class-Schema,""" + self.schema_dn + """
-defaultObjectCategory: """ + object_dn + """
-distinguishedName: """ + object_dn + """
-governsID: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
+defaultObjectCategory: """ + class_dn + """
+governsId: 1.3.6.1.4.1.7165.4.6.2.3.""" + str(class_id) + """
 instanceType: 4
 objectClassCategory: 1
 subClassOf: organizationalPerson
@@ -94,8 +96,9 @@ systemOnly: FALSE
             if isinstance(desc, str):
                 ldif += "nTSecurityDescriptor: %s" % desc
             elif isinstance(desc, security.descriptor):
-                ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
+                ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc)).decode('utf8')
         _ldb.add_ldif(ldif)
+        return class_dn
 
     def create_configuration_container(self, _ldb, object_dn, desc=None):
         ldif = """
@@ -110,7 +113,7 @@ instanceType: 4
             if isinstance(desc, str):
                 ldif += "nTSecurityDescriptor: %s" % desc
             elif isinstance(desc, security.descriptor):
-                ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
+                ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc)).decode('utf8')
         _ldb.add_ldif(ldif)
 
     def create_configuration_specifier(self, _ldb, object_dn, desc=None):
@@ -124,7 +127,7 @@ showInAdvancedViewOnly: TRUE
             if isinstance(desc, str):
                 ldif += "nTSecurityDescriptor: %s" % desc
             elif isinstance(desc, security.descriptor):
-                ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc))
+                ldif += "nTSecurityDescriptor:: %s" % base64.b64encode(ndr_pack(desc)).decode('utf8')
         _ldb.add_ldif(ldif)
 
     def get_ldb_connection(self, target_username, target_password):
@@ -142,13 +145,19 @@ showInAdvancedViewOnly: TRUE
 
     def setUp(self):
         super(DescriptorTests, self).setUp()
-        self.ldb_admin = ldb
-        self.base_dn = ldb.domain_dn()
+        self.ldb_admin = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp,
+                               options=ldb_options)
+        self.base_dn = self.ldb_admin.domain_dn()
         self.configuration_dn = self.ldb_admin.get_config_basedn().get_linearized()
         self.schema_dn = self.ldb_admin.get_schema_basedn().get_linearized()
         self.domain_sid = security.dom_sid(self.ldb_admin.get_domain_sid())
-        self.sd_utils = sd_utils.SDUtils(ldb)
-        print "baseDN: %s" % self.base_dn
+        self.sd_utils = sd_utils.SDUtils(self.ldb_admin)
+        self.addCleanup(self.delete_admin_connection)
+        print("baseDN: %s" % self.base_dn)
+
+    def delete_admin_connection(self):
+        del self.sd_utils
+        del self.ldb_admin
 
     ################################################################################################
 
@@ -175,7 +184,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # SCHEMA
         # CONFIGURATION
         delete_force(self.ldb_admin, "CN=test-specifier1,CN=test-container1,CN=DisplaySpecifiers," \
-                + self.configuration_dn)
+                     + self.configuration_dn)
         delete_force(self.ldb_admin, "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn)
 
     def setUp(self):
@@ -211,112 +220,112 @@ class OwnerGroupDescriptorTests(DescriptorTests):
 
         self.results = {
             # msDS-Behavior-Version < DS_DOMAIN_FUNCTION_2008
-            "ds_behavior_win2003" : {
-                "100" : "O:EAG:DU",
-                "101" : "O:DAG:DU",
-                "102" : "O:%sG:DU",
-                "103" : "O:%sG:DU",
-                "104" : "O:DAG:DU",
-                "105" : "O:DAG:DU",
-                "106" : "O:DAG:DU",
-                "107" : "O:EAG:DU",
-                "108" : "O:DAG:DA",
-                "109" : "O:DAG:DA",
-                "110" : "O:%sG:DA",
-                "111" : "O:%sG:DA",
-                "112" : "O:DAG:DA",
-                "113" : "O:DAG:DA",
-                "114" : "O:DAG:DA",
-                "115" : "O:DAG:DA",
-                "130" : "O:EAG:DU",
-                "131" : "O:DAG:DU",
-                "132" : "O:SAG:DU",
-                "133" : "O:%sG:DU",
-                "134" : "O:EAG:DU",
-                "135" : "O:SAG:DU",
-                "136" : "O:SAG:DU",
-                "137" : "O:SAG:DU",
-                "138" : "O:DAG:DA",
-                "139" : "O:DAG:DA",
-                "140" : "O:%sG:DA",
-                "141" : "O:%sG:DA",
-                "142" : "O:DAG:DA",
-                "143" : "O:DAG:DA",
-                "144" : "O:DAG:DA",
-                "145" : "O:DAG:DA",
-                "160" : "O:EAG:DU",
-                "161" : "O:DAG:DU",
-                "162" : "O:%sG:DU",
-                "163" : "O:%sG:DU",
-                "164" : "O:EAG:DU",
-                "165" : "O:EAG:DU",
-                "166" : "O:DAG:DU",
-                "167" : "O:EAG:DU",
-                "168" : "O:DAG:DA",
-                "169" : "O:DAG:DA",
-                "170" : "O:%sG:DA",
-                "171" : "O:%sG:DA",
-                "172" : "O:DAG:DA",
-                "173" : "O:DAG:DA",
-                "174" : "O:DAG:DA",
-                "175" : "O:DAG:DA",
+            "ds_behavior_win2003": {
+                "100": "O:EAG:DU",
+                "101": "O:DAG:DU",
+                "102": "O:%sG:DU",
+                "103": "O:%sG:DU",
+                "104": "O:DAG:DU",
+                "105": "O:DAG:DU",
+                "106": "O:DAG:DU",
+                "107": "O:EAG:DU",
+                "108": "O:DAG:DA",
+                "109": "O:DAG:DA",
+                "110": "O:%sG:DA",
+                "111": "O:%sG:DA",
+                "112": "O:DAG:DA",
+                "113": "O:DAG:DA",
+                "114": "O:DAG:DA",
+                "115": "O:DAG:DA",
+                "130": "O:EAG:DU",
+                "131": "O:DAG:DU",
+                "132": "O:SAG:DU",
+                "133": "O:%sG:DU",
+                "134": "O:EAG:DU",
+                "135": "O:SAG:DU",
+                "136": "O:SAG:DU",
+                "137": "O:SAG:DU",
+                "138": "O:DAG:DA",
+                "139": "O:DAG:DA",
+                "140": "O:%sG:DA",
+                "141": "O:%sG:DA",
+                "142": "O:DAG:DA",
+                "143": "O:DAG:DA",
+                "144": "O:DAG:DA",
+                "145": "O:DAG:DA",
+                "160": "O:EAG:DU",
+                "161": "O:DAG:DU",
+                "162": "O:%sG:DU",
+                "163": "O:%sG:DU",
+                "164": "O:EAG:DU",
+                "165": "O:EAG:DU",
+                "166": "O:DAG:DU",
+                "167": "O:EAG:DU",
+                "168": "O:DAG:DA",
+                "169": "O:DAG:DA",
+                "170": "O:%sG:DA",
+                "171": "O:%sG:DA",
+                "172": "O:DAG:DA",
+                "173": "O:DAG:DA",
+                "174": "O:DAG:DA",
+                "175": "O:DAG:DA",
             },
             # msDS-Behavior-Version >= DS_DOMAIN_FUNCTION_2008
-            "ds_behavior_win2008" : {
-                "100" : "O:EAG:EA",
-                "101" : "O:DAG:DA",
-                "102" : "O:%sG:DU",
-                "103" : "O:%sG:DU",
-                "104" : "O:DAG:DA",
-                "105" : "O:DAG:DA",
-                "106" : "O:DAG:DA",
-                "107" : "O:EAG:EA",
-                "108" : "O:DAG:DA",
-                "109" : "O:DAG:DA",
-                "110" : "O:%sG:DA",
-                "111" : "O:%sG:DA",
-                "112" : "O:DAG:DA",
-                "113" : "O:DAG:DA",
-                "114" : "O:DAG:DA",
-                "115" : "O:DAG:DA",
-                "130" : "O:EAG:EA",
-                "131" : "O:DAG:DA",
-                "132" : "O:SAG:SA",
-                "133" : "O:%sG:DU",
-                "134" : "O:EAG:EA",
-                "135" : "O:SAG:SA",
-                "136" : "O:SAG:SA",
-                "137" : "O:SAG:SA",
-                "138" : "",
-                "139" : "",
-                "140" : "O:%sG:DA",
-                "141" : "O:%sG:DA",
-                "142" : "",
-                "143" : "",
-                "144" : "",
-                "145" : "",
-                "160" : "O:EAG:EA",
-                "161" : "O:DAG:DA",
-                "162" : "O:%sG:DU",
-                "163" : "O:%sG:DU",
-                "164" : "O:EAG:EA",
-                "165" : "O:EAG:EA",
-                "166" : "O:DAG:DA",
-                "167" : "O:EAG:EA",
-                "168" : "O:DAG:DA",
-                "169" : "O:DAG:DA",
-                "170" : "O:%sG:DA",
-                "171" : "O:%sG:DA",
-                "172" : "O:DAG:DA",
-                "173" : "O:DAG:DA",
-                "174" : "O:DAG:DA",
-                "175" : "O:DAG:DA",
+            "ds_behavior_win2008": {
+                "100": "O:EAG:EA",
+                "101": "O:DAG:DA",
+                "102": "O:%sG:DU",
+                "103": "O:%sG:DU",
+                "104": "O:DAG:DA",
+                "105": "O:DAG:DA",
+                "106": "O:DAG:DA",
+                "107": "O:EAG:EA",
+                "108": "O:DAG:DA",
+                "109": "O:DAG:DA",
+                "110": "O:%sG:DA",
+                "111": "O:%sG:DA",
+                "112": "O:DAG:DA",
+                "113": "O:DAG:DA",
+                "114": "O:DAG:DA",
+                "115": "O:DAG:DA",
+                "130": "O:EAG:EA",
+                "131": "O:DAG:DA",
+                "132": "O:SAG:SA",
+                "133": "O:%sG:DU",
+                "134": "O:EAG:EA",
+                "135": "O:SAG:SA",
+                "136": "O:SAG:SA",
+                "137": "O:SAG:SA",
+                "138": "",
+                "139": "",
+                "140": "O:%sG:DA",
+                "141": "O:%sG:DA",
+                "142": "",
+                "143": "",
+                "144": "",
+                "145": "",
+                "160": "O:EAG:EA",
+                "161": "O:DAG:DA",
+                "162": "O:%sG:DU",
+                "163": "O:%sG:DU",
+                "164": "O:EAG:EA",
+                "165": "O:EAG:EA",
+                "166": "O:DAG:DA",
+                "167": "O:EAG:EA",
+                "168": "O:DAG:DA",
+                "169": "O:DAG:DA",
+                "170": "O:%sG:DA",
+                "171": "O:%sG:DA",
+                "172": "O:DAG:DA",
+                "173": "O:DAG:DA",
+                "174": "O:DAG:DA",
+                "175": "O:DAG:DA",
             },
         }
-        # Discover 'msDS-Behavior-Version'
-        res = self.ldb_admin.search(base=self.base_dn, expression="distinguishedName=%s" % self.base_dn, \
-                attrs=['msDS-Behavior-Version'])
-        res = int(res[0]['msDS-Behavior-Version'][0])
+        # Discover 'domainControllerFunctionality'
+        res = self.ldb_admin.search(base="", scope=SCOPE_BASE,
+                                    attrs=['domainControllerFunctionality'])
+        res = int(res[0]['domainControllerFunctionality'][0])
         if res < DS_DOMAIN_FUNCTION_2008:
             self.DS_BEHAVIOR = "ds_behavior_win2003"
         else:
@@ -341,7 +350,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
             # User is not a member of any additional groups but default
             res = self.ldb_admin.search(user_dn, attrs=["*"])
             res = [x.upper() for x in res[0].keys()]
-            self.assertFalse( "MEMBEROF" in res)
+            self.assertFalse("MEMBEROF" in res)
 
     def check_modify_inheritance(self, _ldb, object_dn, owner_group=""):
         # Modify
@@ -356,7 +365,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         self.assertTrue(ace in desc_sddl)
         # Make sure we have identical result for both "add" and "modify"
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
-        print self._testMethodName
+        print(self._testMethodName)
         test_number = self._testMethodName[5:]
         self.assertEqual(self.results[self.DS_BEHAVIOR][test_number], res)
 
@@ -400,7 +409,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "OU=test_domain_ou1," + self.base_dn
         delete_force(self.ldb_admin, object_dn)
         self.ldb_admin.create_ou(object_dn)
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;CI;WPWDCC;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create additional object into the first one
@@ -424,7 +433,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "OU=test_domain_ou1," + self.base_dn
         delete_force(self.ldb_admin, object_dn)
         self.ldb_admin.create_ou(object_dn)
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;CI;WPWDCC;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create additional object into the first one
@@ -544,7 +553,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "OU=test_domain_ou1," + self.base_dn
         delete_force(self.ldb_admin, object_dn)
         self.ldb_admin.create_ou(object_dn)
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;CI;WOWDCC;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create a custom security descriptor
@@ -571,7 +580,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "OU=test_domain_ou1," + self.base_dn
         delete_force(self.ldb_admin, object_dn)
         self.ldb_admin.create_ou(object_dn)
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;CI;WOWDCC;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create a custom security descriptor
@@ -661,7 +670,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "OU=test_domain_ou1," + self.base_dn
         delete_force(self.ldb_admin, object_dn)
         self.ldb_admin.create_ou(object_dn)
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(D;CI;WP;;;S-1-3-0)"
         #mod = ""
         self.sd_utils.dacl_add_ace(object_dn, mod)
@@ -682,13 +691,11 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Open Ldb connection with the tested user
         _ldb = self.get_ldb_connection(user_name, "samba123@")
         # Change Schema partition descriptor
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -703,9 +710,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -720,9 +725,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -734,13 +737,11 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Open Ldb connection with the tested user
         _ldb = self.get_ldb_connection(user_name, "samba123@")
         #Change Schema partition descriptor
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]] % str(user_sid), res)
@@ -755,9 +756,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -772,9 +771,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -789,9 +786,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -806,9 +801,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(self.schema_dn, mod)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn)
+        class_dn = self.create_schema_class(_ldb)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]], res)
@@ -827,9 +820,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Create a custom security descriptor
         desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual("O:DAG:DA", res)
@@ -845,9 +836,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Create a custom security descriptor
         desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual("O:DAG:DA", res)
@@ -859,12 +848,10 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         _ldb = self.get_ldb_connection(user_name, "samba123@")
         # Create a custom security descriptor
         # NB! Problematic owner part won't accept DA only <User Sid> !!!
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]] % str(user_sid), res)
@@ -876,12 +863,10 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         _ldb = self.get_ldb_connection(user_name, "samba123@")
         # Create a custom security descriptor
         # NB! Problematic owner part won't accept DA only <User Sid> !!!
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         desc_sddl = "O:%sG:DAD:(A;;RP;;;DU)" % str(user_sid)
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual(self.results[self.DS_BEHAVIOR][self._testMethodName[5:]] % str(user_sid), res)
@@ -897,9 +882,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Create a custom security descriptor
         desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual("O:DAG:DA", res)
@@ -915,9 +898,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Create a custom security descriptor
         desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual("O:DAG:DA", res)
@@ -933,9 +914,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Create a custom security descriptor
         desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual("O:DAG:DA", res)
@@ -951,9 +930,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         # Create a custom security descriptor
         desc_sddl = "O:DAG:DAD:(A;;RP;;;DU)"
         # Create example Schema class
-        class_name = self.get_unique_schema_class_name()
-        class_dn = "CN=%s,%s" % (class_name, self.schema_dn)
-        self.create_schema_class(_ldb, class_dn, desc_sddl)
+        class_dn = self.create_schema_class(_ldb, desc_sddl)
         desc_sddl = self.sd_utils.get_sd_as_sddl(class_dn)
         res = re.search("(O:.*G:.*?)D:", desc_sddl).group(1)
         self.assertEqual("O:DAG:DA", res)
@@ -1001,7 +978,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
         delete_force(self.ldb_admin, object_dn)
         self.create_configuration_container(self.ldb_admin, object_dn, )
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create child object with user's credentials
@@ -1022,7 +999,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
         delete_force(self.ldb_admin, object_dn)
         self.create_configuration_container(self.ldb_admin, object_dn, )
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;CI;WDCC;;;AU)"
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create child object with user's credentials
@@ -1137,7 +1114,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
         delete_force(self.ldb_admin, object_dn)
         self.create_configuration_container(self.ldb_admin, object_dn, )
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;;CC;;;AU)"
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create child object with user's credentials
@@ -1160,7 +1137,7 @@ class OwnerGroupDescriptorTests(DescriptorTests):
         object_dn = "CN=test-container1,CN=DisplaySpecifiers," + self.configuration_dn
         delete_force(self.ldb_admin, object_dn)
         self.create_configuration_container(self.ldb_admin, object_dn, )
-        user_sid = self.sd_utils.get_object_sid( self.get_users_domain_dn(user_name) )
+        user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn(user_name))
         mod = "(A;;CC;;;AU)"
         self.sd_utils.dacl_add_ace(object_dn, mod)
         # Create child object with user's credentials
@@ -1261,7 +1238,7 @@ class DaclDescriptorTests(DescriptorTests):
     def create_clean_ou(self, object_dn):
         """ Base repeating setup for unittests to follow """
         res = self.ldb_admin.search(base=self.base_dn, scope=SCOPE_SUBTREE, \
-                expression="distinguishedName=%s" % object_dn)
+                                    expression="distinguishedName=%s" % object_dn)
         # Make sure top testing OU has been deleted before starting the test
         self.assertEqual(len(res), 0)
         self.ldb_admin.create_ou(object_dn)
@@ -1391,7 +1368,7 @@ class DaclDescriptorTests(DescriptorTests):
         desc_sddl = self.sd_utils.get_sd_as_sddl(group_dn)
         mod = mod.replace(";OI;", ";OIIOID;") # change it how it's gonna look like
         self.assertTrue(mod in desc_sddl)
-        self.sd_utils.modify_sd_on_dn(group_dn, "D:" +moded)
+        self.sd_utils.modify_sd_on_dn(group_dn, "D:" + moded)
         desc_sddl = self.sd_utils.get_sd_as_sddl(group_dn)
         self.assertTrue(moded in desc_sddl)
         self.assertTrue(mod in desc_sddl)
@@ -1848,6 +1825,129 @@ class SdFlagsDescriptorTests(DescriptorTests):
         self.assertFalse("S:" in desc_sddl)
         self.assertFalse("G:" in desc_sddl)
 
+    def test_311(self):
+        sd_flags = (SECINFO_OWNER |
+                    SECINFO_GROUP |
+                    SECINFO_DACL |
+                    SECINFO_SACL)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    [], controls=None)
+        self.assertFalse("nTSecurityDescriptor" in res[0])
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["name"], controls=None)
+        self.assertFalse("nTSecurityDescriptor" in res[0])
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["name"], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertFalse("nTSecurityDescriptor" in res[0])
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    [], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["*"], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["nTSecurityDescriptor", "*"], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["*", "nTSecurityDescriptor"], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["nTSecurityDescriptor", "name"], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["name", "nTSecurityDescriptor"], controls=["sd_flags:1:%d" % (sd_flags)])
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["nTSecurityDescriptor"], controls=None)
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["name", "nTSecurityDescriptor"], controls=None)
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None,
+                                    ["nTSecurityDescriptor", "name"], controls=None)
+        self.assertTrue("nTSecurityDescriptor" in res[0])
+        tmp = res[0]["nTSecurityDescriptor"][0]
+        sd = ndr_unpack(security.descriptor, tmp)
+        sddl = sd.as_sddl(self.sd_utils.domain_sid)
+        self.assertTrue("O:" in sddl)
+        self.assertTrue("G:" in sddl)
+        self.assertTrue("D:" in sddl)
+        self.assertTrue("S:" in sddl)
+
+    def test_312(self):
+        """This search is done by the windows dc join..."""
+
+        res = self.ldb_admin.search(self.base_dn, SCOPE_BASE, None, ["1.1"],
+                                    controls=["extended_dn:1:0", "sd_flags:1:0", "search_options:1:1"])
+        self.assertFalse("nTSecurityDescriptor" in res[0])
 
 class RightsAttributesTests(DescriptorTests):
 
@@ -1872,14 +1972,14 @@ class RightsAttributesTests(DescriptorTests):
         object_dn = "OU=test_domain_ou1," + self.base_dn
         delete_force(self.ldb_admin, object_dn)
         self.ldb_admin.create_ou(object_dn)
-        print self.get_users_domain_dn("testuser_attr")
+        print(self.get_users_domain_dn("testuser_attr"))
         user_sid = self.sd_utils.get_object_sid(self.get_users_domain_dn("testuser_attr"))
         #give testuser1 read access so attributes can be retrieved
         mod = "(A;CI;RP;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         _ldb = self.get_ldb_connection("testuser_attr", "samba123@")
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["sDRightsEffective"])
+                          attrs=["sDRightsEffective"])
         #user whould have no rights at all
         self.assertEquals(len(res), 1)
         self.assertEquals(res[0]["sDRightsEffective"][0], "0")
@@ -1887,7 +1987,7 @@ class RightsAttributesTests(DescriptorTests):
         mod = "(A;CI;WD;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["sDRightsEffective"])
+                          attrs=["sDRightsEffective"])
         #user whould have DACL_SECURITY_INFORMATION
         self.assertEquals(len(res), 1)
         self.assertEquals(res[0]["sDRightsEffective"][0], ("%d") % SECINFO_DACL)
@@ -1895,14 +1995,14 @@ class RightsAttributesTests(DescriptorTests):
         mod = "(A;CI;WO;;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["sDRightsEffective"])
+                          attrs=["sDRightsEffective"])
         #user whould have DACL_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION
         self.assertEquals(len(res), 1)
         self.assertEquals(res[0]["sDRightsEffective"][0], ("%d") % (SECINFO_DACL | SECINFO_GROUP | SECINFO_OWNER))
         #no way to grant security privilege bu adding ACE's so we use a memeber of Domain Admins
         _ldb = self.get_ldb_connection("testuser_attr2", "samba123@")
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["sDRightsEffective"])
+                          attrs=["sDRightsEffective"])
         #user whould have DACL_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION
         self.assertEquals(len(res), 1)
         self.assertEquals(res[0]["sDRightsEffective"][0], \
@@ -1918,7 +2018,7 @@ class RightsAttributesTests(DescriptorTests):
         self.sd_utils.dacl_add_ace(object_dn, mod)
         _ldb = self.get_ldb_connection("testuser_attr", "samba123@")
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["allowedChildClassesEffective"])
+                          attrs=["allowedChildClassesEffective"])
         #there should be no allowed child classes
         self.assertEquals(len(res), 1)
         self.assertFalse("allowedChildClassesEffective" in res[0].keys())
@@ -1926,7 +2026,7 @@ class RightsAttributesTests(DescriptorTests):
         mod = "(OA;CI;CC;bf967aba-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod)
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["allowedChildClassesEffective"])
+                          attrs=["allowedChildClassesEffective"])
         # allowedChildClassesEffective should only have one value, user
         self.assertEquals(len(res), 1)
         self.assertEquals(len(res[0]["allowedChildClassesEffective"]), 1)
@@ -1942,7 +2042,7 @@ class RightsAttributesTests(DescriptorTests):
         self.sd_utils.dacl_add_ace(object_dn, mod)
         _ldb = self.get_ldb_connection("testuser_attr", "samba123@")
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["allowedAttributesEffective"])
+                          attrs=["allowedAttributesEffective"])
         #there should be no allowed attributes
         self.assertEquals(len(res), 1)
         self.assertFalse("allowedAttributesEffective" in res[0].keys())
@@ -1953,13 +2053,93 @@ class RightsAttributesTests(DescriptorTests):
         mod3 = "(OA;CI;WP;9a7ad949-ca53-11d1-bbd0-0080c76670c0;;%s)" % str(user_sid)
         self.sd_utils.dacl_add_ace(object_dn, mod + mod2 + mod3)
         res = _ldb.search(base=object_dn, expression="", scope=SCOPE_BASE,
-                         attrs=["allowedAttributesEffective"])
+                          attrs=["allowedAttributesEffective"])
         # value should only contain user and managedBy
         self.assertEquals(len(res), 1)
         self.assertEquals(len(res[0]["allowedAttributesEffective"]), 2)
         self.assertTrue("displayName" in res[0]["allowedAttributesEffective"])
         self.assertTrue("managedBy" in res[0]["allowedAttributesEffective"])
 
+class SdAutoInheritTests(DescriptorTests):
+    def deleteAll(self):
+        delete_force(self.ldb_admin, self.sub_dn)
+        delete_force(self.ldb_admin, self.ou_dn)
+
+    def setUp(self):
+        super(SdAutoInheritTests, self).setUp()
+        self.ou_dn = "OU=test_SdAutoInherit_ou," + self.base_dn
+        self.sub_dn = "OU=test_sub," + self.ou_dn
+        self.deleteAll()
+
+    def test_301(self):
+        """ Modify a descriptor with OWNER_SECURITY_INFORMATION set.
+            See that only the owner has been changed.
+        """
+        attrs = ["nTSecurityDescriptor", "replPropertyMetaData", "uSNChanged"]
+        controls = ["sd_flags:1:%d" % (SECINFO_DACL)]
+        ace = "(A;CI;CC;;;NU)"
+        sub_ace = "(A;CIID;CC;;;NU)"
+        sd_sddl = "O:BAG:BAD:P(A;CI;0x000f01ff;;;AU)"
+        sd = security.descriptor.from_sddl(sd_sddl, self.domain_sid)
+
+        self.ldb_admin.create_ou(self.ou_dn,sd=sd)
+        self.ldb_admin.create_ou(self.sub_dn)
+
+        ou_res0 = self.sd_utils.ldb.search(self.ou_dn, SCOPE_BASE,
+                                           None, attrs, controls=controls)
+        sub_res0 = self.sd_utils.ldb.search(self.sub_dn, SCOPE_BASE,
+                                            None, attrs, controls=controls)
+
+        ou_sd0 = ndr_unpack(security.descriptor, ou_res0[0]["nTSecurityDescriptor"][0])
+        sub_sd0 = ndr_unpack(security.descriptor, sub_res0[0]["nTSecurityDescriptor"][0])
+
+        ou_sddl0 = ou_sd0.as_sddl(self.domain_sid)
+        sub_sddl0 = sub_sd0.as_sddl(self.domain_sid)
+
+        self.assertFalse(ace in ou_sddl0)
+        self.assertFalse(ace in sub_sddl0)
+
+        ou_sddl1 = (ou_sddl0[:ou_sddl0.index("(")] + ace +
+                    ou_sddl0[ou_sddl0.index("("):])
+
+        sub_sddl1 = (sub_sddl0[:sub_sddl0.index("(")] + ace +
+                     sub_sddl0[sub_sddl0.index("("):])
+
+        self.sd_utils.modify_sd_on_dn(self.ou_dn, ou_sddl1, controls=controls)
+
+        sub_res2 = self.sd_utils.ldb.search(self.sub_dn, SCOPE_BASE,
+                                            None, attrs, controls=controls)
+        ou_res2 = self.sd_utils.ldb.search(self.ou_dn, SCOPE_BASE,
+                                           None, attrs, controls=controls)
+
+        ou_sd2 = ndr_unpack(security.descriptor, ou_res2[0]["nTSecurityDescriptor"][0])
+        sub_sd2 = ndr_unpack(security.descriptor, sub_res2[0]["nTSecurityDescriptor"][0])
+
+        ou_sddl2 = ou_sd2.as_sddl(self.domain_sid)
+        sub_sddl2 = sub_sd2.as_sddl(self.domain_sid)
+
+        self.assertFalse(ou_sddl2 == ou_sddl0)
+        self.assertFalse(sub_sddl2 == sub_sddl0)
+
+        if ace not in ou_sddl2:
+            print("ou0: %s" % ou_sddl0)
+            print("ou2: %s" % ou_sddl2)
+
+        if sub_ace not in sub_sddl2:
+            print("sub0: %s" % sub_sddl0)
+            print("sub2: %s" % sub_sddl2)
+
+        self.assertTrue(ace in ou_sddl2)
+        self.assertTrue(sub_ace in sub_sddl2)
+
+        ou_usn0 = int(ou_res0[0]["uSNChanged"][0])
+        ou_usn2 = int(ou_res2[0]["uSNChanged"][0])
+        self.assertTrue(ou_usn2 > ou_usn0)
+
+        sub_usn0 = int(sub_res0[0]["uSNChanged"][0])
+        sub_usn2 = int(sub_res2[0]["uSNChanged"][0])
+        self.assertTrue(sub_usn2 == sub_usn0)
+
 if not "://" in host:
     if os.path.isfile(host):
         host = "tdb://%s" % host
@@ -1970,20 +2150,4 @@ if not "://" in host:
 if host.lower().startswith("ldap://"):
     ldb_options = ["modules:paged_searches"]
 
-ldb = SamDB(host,
-            credentials=creds,
-            session_info=system_session(lp),
-            lp=lp,
-            options=ldb_options)
-
-runner = SubunitTestRunner()
-rc = 0
-if not runner.run(unittest.makeSuite(OwnerGroupDescriptorTests)).wasSuccessful():
-    rc = 1
-if not runner.run(unittest.makeSuite(DaclDescriptorTests)).wasSuccessful():
-    rc = 1
-if not runner.run(unittest.makeSuite(SdFlagsDescriptorTests)).wasSuccessful():
-    rc = 1
-if not runner.run(unittest.makeSuite(RightsAttributesTests)).wasSuccessful():
-    rc = 1
-sys.exit(rc)
+TestProgram(module=__name__, opts=subunitopts)