• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/dsdb/schema/
1/*
2   Unix SMB/CIFS mplementation.
3
4   implement possibleInferiors calculation
5
6   Copyright (C) Andrew Tridgell 2009
7   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
8
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.
13
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.
18
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/>.
21
22*/
23/*
24  This module is a C implementation of the logic in the
25  dsdb/samdb/ldb_modules/tests/possibleInferiors.py code
26
27  To understand the C code, please see the python code first
28 */
29
30#include "includes.h"
31#include "dsdb/samdb/samdb.h"
32
33
34/*
35  create the SUPCLASSES() list
36 */
37static char **schema_supclasses(struct dsdb_schema *schema, struct dsdb_class *schema_class)
38{
39	char **list;
40
41	if (schema_class->supclasses) {
42		return schema_class->supclasses;
43	}
44
45	list = str_list_make_empty(schema_class);
46	if (list == NULL) {
47		DEBUG(0,(__location__ " out of memory\n"));
48		return NULL;
49	}
50
51	/* Cope with 'top SUP top', ie top is subClassOf top */
52	if (schema_class->subClassOf &&
53	    strcmp(schema_class->lDAPDisplayName, schema_class->subClassOf) == 0) {
54		schema_class->supclasses = list;
55		return list;
56	}
57
58	if (schema_class->subClassOf) {
59		const char **list2;
60		list = str_list_add_const(list, schema_class->subClassOf);
61
62		list2 = schema_supclasses(schema,
63					  discard_const_p(struct dsdb_class,
64							  dsdb_class_by_lDAPDisplayName(schema,
65											schema_class->subClassOf)));
66		list = str_list_append_const(list, list2);
67	}
68
69	schema_class->supclasses = str_list_unique(list);
70
71	return list;
72}
73
74/*
75  this one is used internally
76  matches SUBCLASSES() python function
77 */
78static char **schema_subclasses(struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, char **oclist)
79{
80	char **list = str_list_make_empty(mem_ctx);
81	int i;
82
83	for (i=0; oclist && oclist[i]; i++) {
84		struct dsdb_class *schema_class = dsdb_class_by_lDAPDisplayName(schema, oclist[i]);
85		if (!schema_class) {
86			DEBUG(0, ("ERROR: Unable to locate subClass: '%s'\n", oclist[i]));
87			continue;
88		}
89		list = str_list_append_const(list, schema_class->subclasses);
90	}
91	return list;
92}
93
94
95/*
96   equivalent of the POSSSUPERIORS() python function
97 */
98static char **schema_posssuperiors(struct dsdb_schema *schema,
99				   struct dsdb_class *schema_class)
100{
101	if (schema_class->posssuperiors == NULL) {
102		char **list2 = str_list_make_empty(schema_class);
103		char **list3;
104		int i;
105
106		list2 = str_list_append_const(list2, schema_class->systemPossSuperiors);
107		list2 = str_list_append_const(list2, schema_class->possSuperiors);
108		list3 = schema_supclasses(schema, schema_class);
109		for (i=0; list3 && list3[i]; i++) {
110			struct dsdb_class *class2 = dsdb_class_by_lDAPDisplayName(schema, list3[i]);
111			if (!class2) {
112				DEBUG(0, ("ERROR: Unable to locate supClass: '%s'\n", list3[i]));
113				continue;
114			}
115			list2 = str_list_append_const(list2, schema_posssuperiors(schema, class2));
116		}
117		list2 = str_list_append_const(list2, schema_subclasses(schema, list2, list2));
118
119		schema_class->posssuperiors = str_list_unique(list2);
120	}
121
122	return schema_class->posssuperiors;
123}
124
125static char **schema_subclasses_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class)
126{
127	char **list = str_list_copy_const(schema_class, schema_class->subclasses_direct);
128	int i;
129	for (i=0;list && list[i]; i++) {
130		struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
131		if (schema_class != schema_class2) {
132			list = str_list_append_const(list, schema_subclasses_recurse(schema, schema_class2));
133		}
134	}
135	return list;
136}
137
138/* Walk down the subClass tree, setting a higher index as we go down
139 * each level.  top is 1, subclasses of top are 2, etc */
140void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_class *schema_class, int order)
141{
142	const char **list = schema_class->subclasses_direct;
143	int i;
144	schema_class->subClass_order = order;
145	for (i=0;list && list[i]; i++) {
146		struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, list[i]);
147		schema_subclasses_order_recurse(schema, schema_class2, order+1);
148	}
149	return;
150}
151
152static void schema_create_subclasses(struct dsdb_schema *schema)
153{
154	struct dsdb_class *schema_class;
155
156	for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
157		struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf);
158		if (schema_class2 == NULL) {
159			DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName));
160			continue;
161		}
162		if (schema_class2 && schema_class != schema_class2) {
163			if (schema_class2->subclasses_direct == NULL) {
164				schema_class2->subclasses_direct = str_list_make_empty(schema_class2);
165			}
166			schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct,
167									schema_class->lDAPDisplayName);
168		}
169	}
170
171	for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
172		schema_class->subclasses = str_list_unique(schema_subclasses_recurse(schema, schema_class));
173
174		/* Initilise the subClass order, to ensure we can't have uninitilised sort on the subClass hirarchy */
175		schema_class->subClass_order = 0;
176	}
177
178	schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1);
179}
180
181static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
182{
183	struct dsdb_class *c2;
184
185	for (c2=schema->classes; c2; c2=c2->next) {
186		char **superiors = schema_posssuperiors(schema, c2);
187		if (c2->systemOnly == false
188		    && c2->objectClassCategory != 2
189		    && c2->objectClassCategory != 3
190		    && str_list_check(superiors, schema_class->lDAPDisplayName)) {
191			if (schema_class->possibleInferiors == NULL) {
192				schema_class->possibleInferiors = str_list_make_empty(schema_class);
193			}
194			schema_class->possibleInferiors = str_list_add_const(schema_class->possibleInferiors,
195								       c2->lDAPDisplayName);
196		}
197	}
198	schema_class->possibleInferiors = str_list_unique(schema_class->possibleInferiors);
199}
200
201/*
202  fill in a string class name from a governs_ID
203 */
204static void schema_fill_from_class_one(struct dsdb_schema *schema, struct dsdb_class *c,
205				    const char **s, uint32_t id)
206{
207	if (*s == NULL && id != 0) {
208		struct dsdb_class *c2 = dsdb_class_by_governsID_id(schema, id);
209		if (c2) {
210			*s = c2->lDAPDisplayName;
211		}
212	}
213}
214
215/*
216  fill in a list of string class names from a governs_ID list
217 */
218static void schema_fill_from_class_list(struct dsdb_schema *schema, struct dsdb_class *c,
219				     const char ***s, uint32_t *ids)
220{
221	if (*s == NULL && ids != NULL) {
222		int i;
223		for (i=0;ids[i];i++) ;
224		*s = talloc_array(c, const char *, i+1);
225		for (i=0;ids[i];i++) {
226			struct dsdb_class *c2 = dsdb_class_by_governsID_id(schema, ids[i]);
227			if (c2) {
228				(*s)[i] = c2->lDAPDisplayName;
229			} else {
230				(*s)[i] = NULL;
231			}
232		}
233		(*s)[i] = NULL;
234	}
235}
236
237/*
238  fill in a list of string attribute names from a attributeID list
239 */
240static void schema_fill_from_attribute_list(struct dsdb_schema *schema, struct dsdb_class *c,
241					    const char ***s, uint32_t *ids)
242{
243	if (*s == NULL && ids != NULL) {
244		int i;
245		for (i=0;ids[i];i++) ;
246		*s = talloc_array(c, const char *, i+1);
247		for (i=0;ids[i];i++) {
248			struct dsdb_attribute *a = dsdb_attribute_by_attributeID_id(schema, ids[i]);
249			if (a) {
250				(*s)[i] = a->lDAPDisplayName;
251			} else {
252				(*s)[i] = NULL;
253			}
254		}
255		(*s)[i] = NULL;
256	}
257}
258
259/*
260  if the schema came from DRS then some attributes will be setup as IDs
261 */
262static void schema_fill_from_ids(struct dsdb_schema *schema)
263{
264	struct dsdb_class *c;
265	for (c=schema->classes; c; c=c->next) {
266		schema_fill_from_class_one(schema, c, &c->subClassOf, c->subClassOf_id);
267		schema_fill_from_attribute_list(schema, c, &c->systemMayContain, c->systemMayContain_ids);
268		schema_fill_from_attribute_list(schema, c, &c->systemMustContain, c->systemMustContain_ids);
269		schema_fill_from_attribute_list(schema, c, &c->mustContain, c->mustContain_ids);
270		schema_fill_from_attribute_list(schema, c, &c->mayContain, c->mayContain_ids);
271		schema_fill_from_class_list(schema, c, &c->possSuperiors, c->possSuperiors_ids);
272		schema_fill_from_class_list(schema, c, &c->systemPossSuperiors, c->systemPossSuperiors_ids);
273		schema_fill_from_class_list(schema, c, &c->systemAuxiliaryClass, c->systemAuxiliaryClass_ids);
274		schema_fill_from_class_list(schema, c, &c->auxiliaryClass, c->auxiliaryClass_ids);
275	}
276}
277
278void schema_fill_constructed(struct dsdb_schema *schema)
279{
280	struct dsdb_class *schema_class;
281
282	schema_fill_from_ids(schema);
283
284	schema_create_subclasses(schema);
285
286	for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
287		schema_fill_possible_inferiors(schema, schema_class);
288	}
289
290	/* free up our internal cache elements */
291	for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
292		talloc_free(schema_class->supclasses);
293		talloc_free(schema_class->subclasses_direct);
294		talloc_free(schema_class->subclasses);
295		talloc_free(schema_class->posssuperiors);
296		schema_class->supclasses = NULL;
297		schema_class->subclasses_direct = NULL;
298		schema_class->subclasses = NULL;
299		schema_class->posssuperiors = NULL;
300	}
301}
302