provision: Ignore duplicate attid and governsID check
authorBob Campbell <bobcampbell@catalyst.net.nz>
Thu, 30 Jun 2016 03:03:39 +0000 (15:03 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 6 Jul 2016 13:35:17 +0000 (15:35 +0200)
During the provision this causes a huge performance hit as these two
attributes are unindexed.

Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Signed-off-by: Bob Campbell <bobcampbell@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Pair-programmed-with: Garming Sam <garming@catalyst.net.nz>

python/samba/dbchecker.py
python/samba/provision/__init__.py
source4/dsdb/pydsdb.c
source4/dsdb/samdb/ldb_modules/samldb.c
source4/dsdb/samdb/samdb.h
source4/setup/schema_samba4.ldif

index e652f8688ea081b3b8a5375c7e4c853ddcf52fe4..039f84185061f65c46dae0b1cc09dfe8c2d40dc4 100644 (file)
@@ -142,6 +142,8 @@ class dbcheck(object):
 
         error_count += self.check_deleted_objects_containers()
 
+        self.attribute_or_class_ids = set()
+
         for object in res:
             self.dn_set.add(str(object.dn))
             error_count += self.check_object(object.dn, attrs=attrs)
@@ -1557,6 +1559,14 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                     self.err_doubled_userParameters(obj, attrname, obj[attrname])
                     continue
 
+            if attrname.lower() == 'attributeid' or attrname.lower() == 'governsid':
+                if obj[attrname][0] in self.attribute_or_class_ids:
+                    error_count += 1
+                    self.report('Error: %s %s on %s already exists as an attributeId or governsId'
+                                % (attrname, obj.dn, obj[attrname][0]))
+                else:
+                    self.attribute_or_class_ids.add(obj[attrname][0])
+
             # check for empty attributes
             for val in obj[attrname]:
                 if val == '':
index ce7506addb6d2a6c1b8765cd896b4bd581ab48b2..d21a22d7fff489be87be17b7b3797ecedcc0b2c9 100644 (file)
@@ -38,6 +38,7 @@ import socket
 import urllib
 import string
 import tempfile
+import samba.dsdb
 
 import ldb
 
@@ -1312,13 +1313,17 @@ def fill_samdb(samdb, lp, names, logger, policyguid,
                 })
 
         # The LDIF here was created when the Schema object was constructed
+        ignore_checks_oid = "local_oid:%s:0" % samba.dsdb.DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID
         logger.info("Setting up sam.ldb schema")
-        samdb.add_ldif(schema.schema_dn_add, controls=["relax:0"])
-        samdb.modify_ldif(schema.schema_dn_modify)
+        samdb.add_ldif(schema.schema_dn_add,
+                       controls=["relax:0", ignore_checks_oid])
+        samdb.modify_ldif(schema.schema_dn_modify,
+                          controls=[ignore_checks_oid])
         samdb.write_prefixes_from_schema()
-        samdb.add_ldif(schema.schema_data, controls=["relax:0"])
+        samdb.add_ldif(schema.schema_data, controls=["relax:0", ignore_checks_oid])
         setup_add_ldif(samdb, setup_path("aggregate_schema.ldif"),
-                       {"SCHEMADN": names.schemadn})
+                       {"SCHEMADN": names.schemadn},
+                       controls=["relax:0", ignore_checks_oid])
 
     # Now register this container in the root of the forest
     msg = ldb.Message(ldb.Dn(samdb, names.domaindn))
@@ -1864,6 +1869,9 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
                                   'ipsecISAKMPReference',
                                   'ipsecNegotiationPolicyReference',
                                   'ipsecNFAReference'])
+        if chk.check_database(DN=names.schemadn, scope=ldb.SCOPE_SUBTREE,
+                attrs=['attributeId', 'governsId']) != 0:
+            raise ProvisioningError("Duplicate attributeId or governsId in schema. Must be fixed manually!!")
     except:
         samdb.transaction_cancel()
         raise
index f663b435e59b96fb51573868a9ac2d5d49f07029..faed682c5b1b9a7cd132dc6c63e33fd11d65cc44 100644 (file)
@@ -1324,6 +1324,7 @@ void initdsdb(void)
        ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK);
        ADD_DSDB_STRING(DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA);
        ADD_DSDB_STRING(DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
+       ADD_DSDB_STRING(DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID);
 
        ADD_DSDB_STRING(DS_GUID_COMPUTERS_CONTAINER);
        ADD_DSDB_STRING(DS_GUID_DELETED_OBJECTS_CONTAINER);
index 047b6ee2a93c126f90ad478058c0f6e060edbd0d..811262427fa8c068c328c73b1bf6eea5d768d6c4 100644 (file)
@@ -3219,9 +3219,12 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
                                 "objectclass", "classSchema") != NULL) {
                ac->type = SAMLDB_TYPE_CLASS;
 
-               ret = samldb_schema_governsid_valid_check(ac);
-               if (ret != LDB_SUCCESS) {
-                       return ret;
+               /* If in provision, these checks are too slow to do */
+               if (!ldb_request_get_control(req, DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID)) {
+                       ret = samldb_schema_governsid_valid_check(ac);
+                       if (ret != LDB_SUCCESS) {
+                               return ret;
+                       }
                }
 
                ret = samldb_schema_ldapdisplayname_valid_check(ac);
@@ -3242,9 +3245,12 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
                                 "objectclass", "attributeSchema") != NULL) {
                ac->type = SAMLDB_TYPE_ATTRIBUTE;
 
-               ret = samldb_schema_attributeid_valid_check(ac);
-               if (ret != LDB_SUCCESS) {
-                       return ret;
+               /* If in provision, these checks are too slow to do */
+               if (!ldb_request_get_control(req, DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID)) {
+                       ret = samldb_schema_attributeid_valid_check(ac);
+                       if (ret != LDB_SUCCESS) {
+                               return ret;
+                       }
                }
 
                ret = samldb_schema_ldapdisplayname_valid_check(ac);
index 4fff80ec89a3edbbc5a025c5d450a727b6e11a11..20a55fecb754dc421462dc20a715a38b981f8429 100644 (file)
@@ -175,6 +175,13 @@ struct dsdb_control_password_user_account_control {
        uint32_t new_flags; /* the new flags stored */
 };
 
+/*
+ * Ignores strict checking when adding objects to samldb.
+ * This is used when provisioning, as checking all objects when added
+ * was slow due to an unindexed search.
+ */
+#define DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID "1.3.6.1.4.1.7165.4.3.28"
+
 #define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1"
 struct dsdb_extended_replicated_object {
        struct ldb_message *msg;
index 4c0bbee655bd5e7f2aa3e224320205ea02c91f6a..ac56f51840ace1a1c269a3d4001314b9aabc3f36 100644 (file)
 #Allocated: DSDB_CONTROL_CHANGEREPLMETADATA_RESORT_OID 1.3.6.1.4.1.7165.4.3.25
 #Allocated: DSDB_CONTROL_PASSWORD_DEFAULT_LAST_SET_OID 1.3.6.1.4.1.7165.4.3.26
 #Allocated: DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID 1.3.6.1.4.1.7165.4.3.27
+#Allocated: DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID 1.3.6.1.4.1.7165.4.3.28
 
 # Extended 1.3.6.1.4.1.7165.4.4.x
 #Allocated: DSDB_EXTENDED_REPLICATED_OBJECTS_OID 1.3.6.1.4.1.7165.4.4.1