2 Unix SMB/CIFS mplementation.
4 implement possibleInferiors calculation
6 Copyright (C) Andrew Tridgell 2009
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 This module is a C implementation of the logic in the
25 dsdb/samdb/ldb_modules/tests/possibleInferiors.py code
27 To understand the C code, please see the python code first
31 #include "dsdb/samdb/samdb.h"
36 create the SUPCLASSES() list
38 static char * const *schema_supclasses(struct dsdb_schema *schema,
39 TALLOC_CTX *mem_ctx, struct dsdb_class *schema_class)
43 if (schema_class->supclasses) {
44 return schema_class->supclasses;
47 list = str_list_make(mem_ctx, NULL, NULL);
49 DEBUG(0,(__location__ " out of memory\n"));
53 /* Cope with 'top SUP top', ie top is subClassOf top */
54 if (strcmp(schema_class->lDAPDisplayName, schema_class->subClassOf) == 0) {
55 schema_class->supclasses = list;
59 if (schema_class->subClassOf) {
61 list = str_list_add(list, schema_class->subClassOf);
63 list2 = schema_supclasses(schema, mem_ctx, dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf));
64 list = str_list_append(list, list2);
67 schema_class->supclasses = list;
73 this one is used internally
74 matches SUBCLASSES() python function
76 static char **schema_subclasses(struct dsdb_schema *schema, TALLOC_CTX *mem_ctx,
77 const char * const *oclist)
79 char **list = str_list_make(mem_ctx, NULL, NULL);
82 for (i=0; oclist && oclist[i]; i++) {
83 struct dsdb_class *schema_class = dsdb_class_by_lDAPDisplayName(schema, oclist[i]);
84 list = str_list_append(list, schema_class->subclasses);
91 equivalent of the POSSSUPERIORS() python function
93 static char **schema_posssuperiors(struct dsdb_schema *schema, TALLOC_CTX *mem_ctx,
94 struct dsdb_class *schema_class)
96 char **list = str_list_make(mem_ctx, NULL, NULL);
98 if (schema_class->posssuperiors) {
99 return schema_class->posssuperiors;
101 char * const *list2 = str_list_make(mem_ctx, NULL, NULL);
102 list2 = str_list_append(list2, schema_class->systemPossSuperiors);
103 list2 = str_list_append(list2, schema_class->possSuperiors);
104 list2 = str_list_append(list2, schema_supclasses(schema, list2, schema_class));
105 list2 = str_list_append(list2, schema_subclasses(schema, list2, list2));
107 schema_class->posssuperiors = list2;
108 return schema_class->posssuperiors;
114 static char **schema_subclasses_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class)
116 char * const *list = str_list_copy(schema_class, schema_class->subclasses_direct);
118 for (i=0;list && list[i]; i++) {
119 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
120 if (schema_class != schema_class2) {
121 list = str_list_append(list, schema_subclasses_recurse(schema, schema_class2));
127 static void schema_create_subclasses(struct dsdb_schema *schema)
129 struct dsdb_class *schema_class;
131 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
132 struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf);
133 schema_class->subclasses_direct = str_list_make(schema_class, NULL, NULL);
134 if (schema_class != schema_class2) {
135 if (schema_class2->subclasses_direct == NULL) {
136 schema_class2->subclasses_direct = str_list_make(schema_class2, NULL, NULL);
138 schema_class2->subclasses_direct = str_list_add(schema_class2->subclasses_direct,
139 schema_class->subClassOf);
143 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
144 schema_class->subclasses = schema_subclasses_recurse(schema, schema_class);
148 static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
150 struct dsdb_class *c2;
152 for (c2=schema->classes; c2; c2=c2->next) {
153 char **superiors = schema_posssuperiors(schema, c2, c2);
154 if (c2->systemOnly == false
155 && c2->objectClassCategory != 2
156 && c2->objectClassCategory != 3
157 && str_list_check(superiors, schema_class->lDAPDisplayName)) {
158 if (c2->possible_inferiors == NULL) {
159 c2->possible_inferiors = str_list_make(c2, NULL, NULL);
161 c2->possible_inferiors = str_list_add_unique(c2->possible_inferiors,
162 schema_class->lDAPDisplayName);
164 talloc_free(superiors);
168 void schema_fill_constructed(struct dsdb_schema *schema)
170 struct dsdb_class *schema_class;
172 schema_create_subclasses(schema);
174 for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
175 schema_fill_possible_inferiors(schema, schema_class);