s4:objectclass LDB module - fix up the sorting in respect to structural or 88 objectc...
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Sun, 25 Mar 2012 20:51:51 +0000 (22:51 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 25 Mar 2012 22:57:29 +0000 (00:57 +0200)
Please have a look at MS-ADTS 3.1.1.1.4.

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/objectclass.c

index f125efc6c41630eff5aca1dc0d5b573f81300d27..b66b4d7a5f4f8f10199af62f6149bfd28bf31e32 100644 (file)
@@ -100,7 +100,9 @@ static int objectclass_sort(struct ldb_module *module,
 {
        struct ldb_context *ldb;
        unsigned int i, lowest;
-       struct class_list *unsorted = NULL, *sorted = NULL, *current = NULL, *poss_parent = NULL, *new_parent = NULL, *current_lowest = NULL;
+       struct class_list *unsorted = NULL, *sorted = NULL, *current = NULL,
+                         *poss_parent = NULL, *new_parent = NULL,
+                         *current_lowest = NULL, *current_lowest_struct = NULL;
 
        ldb = ldb_module_get_ctx(module);
 
@@ -190,13 +192,25 @@ static int objectclass_sort(struct ldb_module *module,
        /* For each object: order by hierarchy */
        while (unsorted != NULL) {
                lowest = UINT_MAX;
-               current_lowest = NULL;
+               current_lowest = current_lowest_struct = NULL;
                for (current = unsorted; current != NULL; current = current->next) {
-                       if(current->objectclass->subClass_order < lowest) {
-                               current_lowest = current;
+                       if (current->objectclass->subClass_order <= lowest) {
+                               /*
+                                * According to MS-ADTS 3.1.1.1.4 structural
+                                * and 88 object classes are always listed after
+                                * the other class types in a subclass hierarchy
+                                */
+                               if (current->objectclass->objectClassCategory > 1) {
+                                       current_lowest = current;
+                               } else {
+                                       current_lowest_struct = current;
+                               }
                                lowest = current->objectclass->subClass_order;
                        }
                }
+               if (current_lowest == NULL) {
+                       current_lowest = current_lowest_struct;
+               }
 
                if (current_lowest != NULL) {
                        DLIST_REMOVE(unsorted,current_lowest);