Remove DESCRIPTION from generated schema lines.
[kai/samba.git] / source4 / dsdb / schema / schema_description.c
1 /* 
2    Unix SMB/CIFS mplementation.
3    Print schema info into string format
4    
5    Copyright (C) Andrew Bartlett 2006-2008
6     
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.
11    
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.
16    
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/>.
19    
20 */
21 #include "includes.h"
22 #include "dsdb/samdb/samdb.h"
23
24 #define IF_NULL_FAIL_RET(x) do {     \
25                 if (!x) {               \
26                         return NULL;    \
27                 }                       \
28         } while (0) 
29
30
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 *equality, 
37                                           const char *substring, 
38                                           const char *syntax,
39                                           bool single_value, bool operational)
40 {
41         char *schema_entry = talloc_asprintf(mem_ctx, 
42                                              "(%s%s%s", seperator, oid, seperator);
43         
44         schema_entry = talloc_asprintf_append(schema_entry, 
45                                               "NAME '%s'%s", name, seperator);
46         IF_NULL_FAIL_RET(schema_entry);
47         
48         if (equality) {
49                 schema_entry = talloc_asprintf_append(schema_entry, 
50                                                       "EQUALITY %s%s", equality, seperator);
51                 IF_NULL_FAIL_RET(schema_entry);
52         }
53         if (substring) {
54                 schema_entry = talloc_asprintf_append(schema_entry, 
55                                                       "SUBSTR %s%s", substring, seperator);
56                 IF_NULL_FAIL_RET(schema_entry);
57         }
58         
59         schema_entry = talloc_asprintf_append(schema_entry, 
60                                               "SYNTAX %s%s", syntax, seperator);
61         IF_NULL_FAIL_RET(schema_entry);
62         
63         if (single_value) {
64                 schema_entry = talloc_asprintf_append(schema_entry, 
65                                                       "SINGLE-VALUE%s", seperator);
66                 IF_NULL_FAIL_RET(schema_entry);
67         }
68         
69         if (operational) {
70                 schema_entry = talloc_asprintf_append(schema_entry, 
71                                                       "NO-USER-MODIFICATION%s", seperator);
72                 IF_NULL_FAIL_RET(schema_entry);
73         }
74         
75         schema_entry = talloc_asprintf_append(schema_entry, 
76                                               ")");
77         return schema_entry;
78 }
79
80 char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute) 
81 {
82         char *schema_description;
83         const struct dsdb_syntax *map = find_syntax_map_by_ad_oid(attribute->attributeSyntax_oid);
84         const char *syntax = map ? map->ldap_oid : attribute->attributeSyntax_oid;
85         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
86         if (!tmp_ctx) {
87                 return NULL;
88         }
89
90         
91         schema_description 
92                 = schema_attribute_description(mem_ctx, 
93                                                TARGET_AD_SCHEMA_SUBENTRY,
94                                                " ",
95                                                attribute->attributeID_oid,
96                                                attribute->lDAPDisplayName,
97                                                NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax),
98                                                attribute->isSingleValued,
99                                                attribute->systemOnly);
100         talloc_free(tmp_ctx);
101         return schema_description;
102 }
103
104 #define APPEND_ATTRS(attributes)                                \
105         do {                                                            \
106                 int k;                                                  \
107                 for (k=0; attributes && attributes[k]; k++) {           \
108                         const char *attr_name = attributes[k];          \
109                                                                         \
110                         schema_entry = talloc_asprintf_append(schema_entry, \
111                                                               "%s ",    \
112                                                               attr_name); \
113                         IF_NULL_FAIL_RET(schema_entry);                 \
114                         if (attributes[k+1]) {                          \
115                                 IF_NULL_FAIL_RET(schema_entry);         \
116                                 if (target == TARGET_OPENLDAP && ((k+1)%5 == 0)) { \
117                                         schema_entry = talloc_asprintf_append(schema_entry, \
118                                                                               "$%s ", seperator); \
119                                         IF_NULL_FAIL_RET(schema_entry); \
120                                 } else {                                \
121                                         schema_entry = talloc_asprintf_append(schema_entry, \
122                                                                               "$ "); \
123                                 }                                       \
124                         }                                               \
125                 }                                                       \
126         } while (0)
127         
128
129 /* Print a schema class or dITContentRule as a string.  
130  *
131  * To print a scheam class, specify objectClassCategory but not auxillary_classes
132  * To print a dITContentRule, specify auxillary_classes but set objectClassCategory == -1
133  *
134  */
135
136 char *schema_class_description(TALLOC_CTX *mem_ctx, 
137                                enum dsdb_schema_convert_target target,
138                                const char *seperator,
139                                const char *oid, 
140                                const char *name,
141                                const char **auxillary_classes,
142                                const char *subClassOf,
143                                int objectClassCategory,
144                                char **must,
145                                char **may)
146 {
147         char *schema_entry = talloc_asprintf(mem_ctx, 
148                                              "(%s%s%s", seperator, oid, seperator);
149         
150         IF_NULL_FAIL_RET(schema_entry);
151
152         schema_entry = talloc_asprintf_append(schema_entry, 
153                                               "NAME '%s'%s", name, seperator);
154         IF_NULL_FAIL_RET(schema_entry);
155         
156         if (auxillary_classes) {
157                 schema_entry = talloc_asprintf_append(schema_entry, 
158                                                       "AUX ( ");
159                 IF_NULL_FAIL_RET(schema_entry);
160                 
161                 APPEND_ATTRS(auxillary_classes);
162                 
163                 schema_entry = talloc_asprintf_append(schema_entry, 
164                                                       ")%s", seperator);
165                 IF_NULL_FAIL_RET(schema_entry);
166         }
167
168         if (subClassOf && strcasecmp(subClassOf, name) != 0) {
169                 schema_entry = talloc_asprintf_append(schema_entry, 
170                                                       "SUP %s%s", subClassOf, seperator);
171                 IF_NULL_FAIL_RET(schema_entry);
172         }
173         
174         switch (objectClassCategory) {
175         case -1:
176                 break;
177                 /* Dummy case for when used for printing ditContentRules */
178         case 0:
179                 /*
180                  * NOTE: this is an type 88 class
181                  *       e.g. 2.5.6.6 NAME 'person'
182                  *       but w2k3 gives STRUCTURAL here!
183                  */
184                 schema_entry = talloc_asprintf_append(schema_entry, 
185                                                       "STRUCTURAL%s", seperator);
186                 IF_NULL_FAIL_RET(schema_entry);
187                 break;
188         case 1:
189                 schema_entry = talloc_asprintf_append(schema_entry, 
190                                                       "STRUCTURAL%s", seperator);
191                 IF_NULL_FAIL_RET(schema_entry);
192                 break;
193         case 2:
194                 schema_entry = talloc_asprintf_append(schema_entry, 
195                                                       "ABSTRACT%s", seperator);
196                 IF_NULL_FAIL_RET(schema_entry);
197                 break;
198         case 3:
199                 schema_entry = talloc_asprintf_append(schema_entry, 
200                                                       "AUXILIARY%s", seperator);
201                 IF_NULL_FAIL_RET(schema_entry);
202                 break;
203         }
204         
205         if (must) {
206                 schema_entry = talloc_asprintf_append(schema_entry, 
207                                                       "MUST (%s", target == TARGET_AD_SCHEMA_SUBENTRY ? "" : " ");
208                 IF_NULL_FAIL_RET(schema_entry);
209                 
210                 APPEND_ATTRS(must);
211                 
212                 schema_entry = talloc_asprintf_append(schema_entry, 
213                                                       ")%s", seperator);
214                 IF_NULL_FAIL_RET(schema_entry);
215         }
216         
217         if (may) {
218                 schema_entry = talloc_asprintf_append(schema_entry, 
219                                                       "MAY (%s", target == TARGET_AD_SCHEMA_SUBENTRY ? "" : " ");
220                 IF_NULL_FAIL_RET(schema_entry);
221                 
222                 APPEND_ATTRS(may);
223                 
224                 schema_entry = talloc_asprintf_append(schema_entry, 
225                                                       ")%s", seperator);
226                 IF_NULL_FAIL_RET(schema_entry);
227         }
228         
229         schema_entry = talloc_asprintf_append(schema_entry, 
230                                               ")");
231         return schema_entry;
232 }
233
234 char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class *class) 
235 {
236         char *schema_description;
237         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
238         if (!tmp_ctx) {
239                 return NULL;
240         }
241         
242         schema_description
243                 = schema_class_description(mem_ctx, 
244                                            TARGET_AD_SCHEMA_SUBENTRY,
245                                            " ",
246                                            class->governsID_oid,
247                                            class->lDAPDisplayName,
248                                            NULL, 
249                                            class->subClassOf,
250                                            class->objectClassCategory,
251                                            dsdb_attribute_list(tmp_ctx, 
252                                                                class, DSDB_SCHEMA_ALL_MUST),
253                                            dsdb_attribute_list(tmp_ctx, 
254                                                                class, DSDB_SCHEMA_ALL_MAY));
255         talloc_free(tmp_ctx);
256         return schema_description;
257 }
258 char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_class *class,
259                                      const struct dsdb_schema *schema) 
260 {
261         int i;
262         char *schema_description;
263         char **aux_class_list = NULL;
264         char **attrs;
265         char **must_attr_list = NULL;
266         char **may_attr_list = NULL;
267         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
268         const struct dsdb_class *aux_class;
269         if (!tmp_ctx) {
270                 return NULL;
271         }
272
273         aux_class_list = merge_attr_list(tmp_ctx, aux_class_list, class->systemAuxiliaryClass);
274         aux_class_list = merge_attr_list(tmp_ctx, aux_class_list, class->auxiliaryClass);
275
276         for (i=0; aux_class_list && aux_class_list[i]; i++) {
277                 aux_class = dsdb_class_by_lDAPDisplayName(schema, aux_class_list[i]);
278                 
279                 attrs = dsdb_attribute_list(mem_ctx, aux_class, DSDB_SCHEMA_ALL_MUST);
280                 must_attr_list = merge_attr_list(mem_ctx, must_attr_list, attrs);
281
282                 attrs = dsdb_attribute_list(mem_ctx, aux_class, DSDB_SCHEMA_ALL_MAY);
283                 may_attr_list = merge_attr_list(mem_ctx, may_attr_list, attrs);
284         }
285
286         schema_description
287                 = schema_class_description(mem_ctx, 
288                                            TARGET_AD_SCHEMA_SUBENTRY,
289                                            " ",
290                                            class->governsID_oid,
291                                            class->lDAPDisplayName,
292                                            (const char **)aux_class_list,
293                                            NULL, /* Must not specify a
294                                                   * SUP (subclass) in
295                                                   * ditContentRules
296                                                   * per MS-ADTS
297                                                   * 3.1.1.3.1.1.1 */
298                                            -1, must_attr_list, may_attr_list);
299         talloc_free(tmp_ctx);
300         return schema_description;
301 }