Generate the subSchema in cn=Aggregate
[Samba.git] / source4 / dsdb / schema / schema_description.c
blob2f3acd1336ef96bd3b92577224c1f32533744779
1 /*
2 Unix SMB/CIFS mplementation.
3 Print schema info into string format
5 Copyright (C) Andrew Bartlett 2006-2008
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "dsdb/samdb/samdb.h"
24 #define IF_NULL_FAIL_RET(x) do { \
25 if (!x) { \
26 return NULL; \
27 } \
28 } while (0)
31 char *schema_attribute_description(TALLOC_CTX *mem_ctx,
32 enum dsdb_schema_convert_target target,
33 const char *seperator,
34 const char *oid,
35 const char *name,
36 const char *description,
37 const char *equality,
38 const char *substring,
39 const char *syntax,
40 bool single_value, bool operational)
42 char *schema_entry = talloc_asprintf(mem_ctx,
43 "(%s%s%s", seperator, oid, seperator);
45 schema_entry = talloc_asprintf_append(schema_entry,
46 "NAME '%s'%s", name, seperator);
47 IF_NULL_FAIL_RET(schema_entry);
49 if (description) {
50 #if 0
51 /* Need a way to escape ' characters from the description */
52 schema_entry = talloc_asprintf_append(schema_entry,
53 "DESC '%s'%s", description, seperator);
54 IF_NULL_FAIL_RET(schema_entry);
55 #endif
58 if (equality) {
59 schema_entry = talloc_asprintf_append(schema_entry,
60 "EQUALITY %s%s", equality, seperator);
61 IF_NULL_FAIL_RET(schema_entry);
63 if (substring) {
64 schema_entry = talloc_asprintf_append(schema_entry,
65 "SUBSTR %s%s", substring, seperator);
66 IF_NULL_FAIL_RET(schema_entry);
69 schema_entry = talloc_asprintf_append(schema_entry,
70 "SYNTAX %s%s", syntax, seperator);
71 IF_NULL_FAIL_RET(schema_entry);
73 if (single_value) {
74 schema_entry = talloc_asprintf_append(schema_entry,
75 "SINGLE-VALUE%s", seperator);
76 IF_NULL_FAIL_RET(schema_entry);
79 if (operational) {
80 schema_entry = talloc_asprintf_append(schema_entry,
81 "NO-USER-MODIFICATION%s", seperator);
82 IF_NULL_FAIL_RET(schema_entry);
85 schema_entry = talloc_asprintf_append(schema_entry,
86 ")");
87 return schema_entry;
90 char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute)
92 char *schema_description;
93 const struct dsdb_syntax_map *map = find_syntax_map_by_ad_oid(attribute->attributeSyntax_oid);
94 const char *syntax = map ? map->Standard_OID : attribute->attributeSyntax_oid;
95 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
96 if (!tmp_ctx) {
97 return NULL;
101 schema_description
102 = schema_attribute_description(mem_ctx,
103 TARGET_AD_SCHEMA_SUBENTRY,
104 " ",
105 attribute->attributeID_oid,
106 attribute->lDAPDisplayName,
107 NULL, NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax),
108 attribute->isSingleValued,
109 attribute->systemOnly);
110 talloc_free(tmp_ctx);
111 return schema_description;
114 #define APPEND_ATTRS(attributes) \
115 do { \
116 int k; \
117 for (k=0; attributes && attributes[k]; k++) { \
118 const char *attr_name = attributes[k]; \
120 schema_entry = talloc_asprintf_append(schema_entry, \
121 "%s ", \
122 attr_name); \
123 IF_NULL_FAIL_RET(schema_entry); \
124 if (attributes[k+1]) { \
125 IF_NULL_FAIL_RET(schema_entry); \
126 if (target == TARGET_OPENLDAP && ((k+1)%5 == 0)) { \
127 schema_entry = talloc_asprintf_append(schema_entry, \
128 "$%s ", seperator); \
129 IF_NULL_FAIL_RET(schema_entry); \
130 } else { \
131 schema_entry = talloc_asprintf_append(schema_entry, \
132 "$ "); \
136 } while (0)
139 /* Print a schema class or dITContentRule as a string.
141 * To print a scheam class, specify objectClassCategory but not auxillary_classes
142 * To print a dITContentRule, specify auxillary_classes but set objectClassCategory == -1
146 char *schema_class_description(TALLOC_CTX *mem_ctx,
147 enum dsdb_schema_convert_target target,
148 const char *seperator,
149 const char *oid,
150 const char *name,
151 const char **auxillary_classes,
152 const char *description,
153 const char *subClassOf,
154 int objectClassCategory,
155 char **must,
156 char **may)
158 char *schema_entry = talloc_asprintf(mem_ctx,
159 "(%s%s%s", seperator, oid, seperator);
161 IF_NULL_FAIL_RET(schema_entry);
163 schema_entry = talloc_asprintf_append(schema_entry,
164 "NAME '%s'%s", name, seperator);
165 IF_NULL_FAIL_RET(schema_entry);
167 if (description) {
168 schema_entry = talloc_asprintf_append(schema_entry,
169 "DESC '%s'%s", description, seperator);
170 IF_NULL_FAIL_RET(schema_entry);
173 if (auxillary_classes) {
174 schema_entry = talloc_asprintf_append(schema_entry,
175 "AUX ( ");
176 IF_NULL_FAIL_RET(schema_entry);
178 APPEND_ATTRS(auxillary_classes);
180 schema_entry = talloc_asprintf_append(schema_entry,
181 ")%s", seperator);
182 IF_NULL_FAIL_RET(schema_entry);
185 if (subClassOf) {
186 schema_entry = talloc_asprintf_append(schema_entry,
187 "SUP %s%s", subClassOf, seperator);
188 IF_NULL_FAIL_RET(schema_entry);
191 switch (objectClassCategory) {
192 case -1:
193 break;
194 /* Dummy case for when used for printing ditContentRules */
195 case 0:
197 * NOTE: this is an type 88 class
198 * e.g. 2.5.6.6 NAME 'person'
199 * but w2k3 gives STRUCTURAL here!
201 schema_entry = talloc_asprintf_append(schema_entry,
202 "STRUCTURAL%s", seperator);
203 IF_NULL_FAIL_RET(schema_entry);
204 break;
205 case 1:
206 schema_entry = talloc_asprintf_append(schema_entry,
207 "STRUCTURAL%s", seperator);
208 IF_NULL_FAIL_RET(schema_entry);
209 break;
210 case 2:
211 schema_entry = talloc_asprintf_append(schema_entry,
212 "ABSTRACT%s", seperator);
213 IF_NULL_FAIL_RET(schema_entry);
214 break;
215 case 3:
216 schema_entry = talloc_asprintf_append(schema_entry,
217 "AUXILIARY%s", seperator);
218 IF_NULL_FAIL_RET(schema_entry);
219 break;
222 if (must) {
223 schema_entry = talloc_asprintf_append(schema_entry,
224 "MUST ( ");
225 IF_NULL_FAIL_RET(schema_entry);
227 APPEND_ATTRS(must);
229 schema_entry = talloc_asprintf_append(schema_entry,
230 ")%s", seperator);
231 IF_NULL_FAIL_RET(schema_entry);
234 if (may) {
235 schema_entry = talloc_asprintf_append(schema_entry,
236 "MAY ( ");
237 IF_NULL_FAIL_RET(schema_entry);
239 APPEND_ATTRS(may);
241 schema_entry = talloc_asprintf_append(schema_entry,
242 ")%s", seperator);
243 IF_NULL_FAIL_RET(schema_entry);
246 schema_entry = talloc_asprintf_append(schema_entry,
247 ")");
248 return schema_entry;
251 char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class *class)
253 char *schema_description;
254 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
255 if (!tmp_ctx) {
256 return NULL;
259 schema_description
260 = schema_class_description(mem_ctx,
261 TARGET_AD_SCHEMA_SUBENTRY,
262 " ",
263 class->governsID_oid,
264 class->lDAPDisplayName,
265 NULL,
266 NULL,
267 class->subClassOf,
268 class->objectClassCategory,
269 dsdb_attribute_list(tmp_ctx,
270 class, DSDB_SCHEMA_ALL_MUST),
271 dsdb_attribute_list(tmp_ctx,
272 class, DSDB_SCHEMA_ALL_MAY));
273 talloc_free(tmp_ctx);
274 return schema_description;
276 char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_class *class,
277 const struct dsdb_schema *schema)
279 int i;
280 char *schema_description;
281 char **aux_class_list = NULL;
282 char **attrs;
283 char **must_attr_list = NULL;
284 char **may_attr_list = NULL;
285 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
286 const struct dsdb_class *aux_class;
287 if (!tmp_ctx) {
288 return NULL;
291 aux_class_list = merge_attr_list(tmp_ctx, aux_class_list, class->systemAuxiliaryClass);
292 aux_class_list = merge_attr_list(tmp_ctx, aux_class_list, class->auxiliaryClass);
294 for (i=0; aux_class_list && aux_class_list[i]; i++) {
295 aux_class = dsdb_class_by_lDAPDisplayName(schema, aux_class_list[i]);
297 attrs = dsdb_attribute_list(mem_ctx, aux_class, DSDB_SCHEMA_ALL_MUST);
298 must_attr_list = merge_attr_list(mem_ctx, must_attr_list, attrs);
300 attrs = dsdb_attribute_list(mem_ctx, aux_class, DSDB_SCHEMA_ALL_MAY);
301 may_attr_list = merge_attr_list(mem_ctx, may_attr_list, attrs);
304 schema_description
305 = schema_class_description(mem_ctx,
306 TARGET_AD_SCHEMA_SUBENTRY,
307 " ",
308 class->governsID_oid,
309 class->lDAPDisplayName,
310 (const char **)aux_class_list,
311 NULL,
312 class->subClassOf,
313 -1, must_attr_list, may_attr_list);
314 talloc_free(tmp_ctx);
315 return schema_description;