]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
dbcheck: check correct RID set attributes when looking for SID conflicts
authorAndrew Bartlett <abartlet@samba.org>
Thu, 27 Sep 2018 08:28:26 +0000 (20:28 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 11 Jun 2021 07:41:38 +0000 (07:41 +0000)
The previous code would only work for the first rid set ever given to a DC
because the names are so misleading.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13632

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
python/samba/dbchecker.py

index b2d029db9f227a7f1a6f2f8a01dcf6b8c80fae3d..253e392d26245f2db5b71815101efd209f123592 100644 (file)
@@ -2719,34 +2719,60 @@ newSuperior: %s""" % (str(from_dn), str(to_rdn), str(to_base)))
                         self.report("No RID Set found for this server: %s, and we are not the RID Master (so can not self-allocate)" % dn)
 
         # Check some details of our own RID Set
+        #
+        # Note that the attributes have very bad names.  From ridalloc.c:
+        #
+        #   Note: the RID allocation attributes in AD are very badly named. Here
+        #     is what we think they really do:
+        #
+        #     in RID Set object:
+        #       - rIDPreviousAllocationPool: the pool which a DC is currently
+        #         pulling RIDs from. Managed by client DC
+        #
+        #       - rIDAllocationPool: the pool that the DC will switch to next,
+        #         when rIDPreviousAllocationPool is exhausted. Managed by RID Manager.
+        #
+        #       - rIDNextRID: the last RID allocated by this DC. Managed by client DC
+        #
+        #     in RID Manager object:
+        #       - rIDAvailablePool: the pool where the RID Manager gets new rID
+        #         pools from when it gets a EXOP_RID_ALLOC getncchanges call (or
+        #         locally when the DC is the RID Manager)
+
         if dn == self.rid_set_dn:
             res = self.samdb.search(base=self.rid_set_dn, scope=ldb.SCOPE_BASE,
                                     attrs=["rIDAllocationPool",
                                            "rIDPreviousAllocationPool",
                                            "rIDUsedPool",
                                            "rIDNextRID"])
+            pool_attr = "rIDPreviousAllocationPool"
+            if (pool_attr not in res[0]
+                or int(res[0][pool_attr][0]) == 0):
+                # We have not used it yet, check the next pool instead
+                pool_attr = "rIDAllocationPool"
+
             if "rIDAllocationPool" not in res[0]:
                 self.report("No rIDAllocationPool found in %s" % dn)
                 error_count += 1
             else:
-                next_pool = int(res[0]["rIDAllocationPool"][0])
+                current_pool = int(res[0][pool_attr][0])
 
-                high = (0xFFFFFFFF00000000 & next_pool) >> 32
-                low = 0x00000000FFFFFFFF & next_pool
+                high = (0xFFFFFFFF00000000 & current_pool) >> 32
+                low = 0x00000000FFFFFFFF & current_pool
 
                 if high <= low:
-                    self.report("Invalid RID set %d-%s, %d > %d!" % (low, high, low, high))
+                    self.report("Invalid RID set %d-%s, %d >= %d!" % (low, high, low, high))
                     error_count += 1
 
                 if "rIDNextRID" in res[0]:
-                    next_free_rid = int(res[0]["rIDNextRID"][0])
+                    last_used_rid = int(res[0]["rIDNextRID"][0])
                 else:
-                    next_free_rid = 0
+                    last_used_rid = 0
 
-                if next_free_rid == 0:
+                if last_used_rid == 0:
                     next_free_rid = low
                 else:
-                    next_free_rid += 1
+                    next_free_rid = last_used_rid + 1
 
                 # Check the remainder of this pool for conflicts.  If
                 # ridalloc_allocate_rid() moves to a new pool, this