source: trunk/server/source4/torture/ldap/schema.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 10.4 KB
Line 
1/*
2 Unix SMB/CIFS mplementation.
3 LDAP schema tests
4
5 Copyright (C) Stefan Metzmacher 2006
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
22#include "includes.h"
23#include "libcli/ldap/ldap_client.h"
24#include "lib/cmdline/popt_common.h"
25#include "ldb_wrap.h"
26#include "dsdb/samdb/samdb.h"
27#include "../lib/util/dlinklist.h"
28
29#include "torture/torture.h"
30
31
32struct test_rootDSE {
33 const char *defaultdn;
34 const char *rootdn;
35 const char *configdn;
36 const char *schemadn;
37};
38
39struct test_schema_ctx {
40 struct ldb_context *ldb;
41
42 struct ldb_paged_control *ctrl;
43 uint32_t count;
44 bool pending;
45
46 int (*callback)(void *, struct ldb_context *ldb, struct ldb_message *);
47 void *private_data;
48};
49
50static bool test_search_rootDSE(struct ldb_context *ldb, struct test_rootDSE *root)
51{
52 int ret;
53 struct ldb_message *msg;
54 struct ldb_result *r;
55
56 d_printf("Testing RootDSE Search\n");
57
58 ret = ldb_search(ldb, ldb, &r, ldb_dn_new(ldb, ldb, NULL),
59 LDB_SCOPE_BASE, NULL, NULL);
60 if (ret != LDB_SUCCESS) {
61 return false;
62 } else if (r->count != 1) {
63 talloc_free(r);
64 return false;
65 }
66
67 msg = r->msgs[0];
68
69 root->defaultdn = ldb_msg_find_attr_as_string(msg, "defaultNamingContext", NULL);
70 talloc_steal(ldb, root->defaultdn);
71 root->rootdn = ldb_msg_find_attr_as_string(msg, "rootDomainNamingContext", NULL);
72 talloc_steal(ldb, root->rootdn);
73 root->configdn = ldb_msg_find_attr_as_string(msg, "configurationNamingContext", NULL);
74 talloc_steal(ldb, root->configdn);
75 root->schemadn = ldb_msg_find_attr_as_string(msg, "schemaNamingContext", NULL);
76 talloc_steal(ldb, root->schemadn);
77
78 talloc_free(r);
79
80 return true;
81}
82
83static int test_schema_search_callback(struct ldb_request *req, struct ldb_reply *ares)
84{
85 struct test_schema_ctx *actx;
86 int ret = LDB_SUCCESS;
87
88 actx = talloc_get_type(req->context, struct test_schema_ctx);
89
90 if (!ares) {
91 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
92 }
93 if (ares->error != LDB_SUCCESS) {
94 return ldb_request_done(req, ares->error);
95 }
96
97 switch (ares->type) {
98 case LDB_REPLY_ENTRY:
99 actx->count++;
100 ret = actx->callback(actx->private_data, actx->ldb, ares->message);
101 break;
102
103 case LDB_REPLY_REFERRAL:
104 break;
105
106 case LDB_REPLY_DONE:
107 if (ares->controls) {
108 struct ldb_paged_control *ctrl = NULL;
109 int i;
110
111 for (i=0; ares->controls[i]; i++) {
112 if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[i]->oid) == 0) {
113 ctrl = talloc_get_type(ares->controls[i]->data, struct ldb_paged_control);
114 break;
115 }
116 }
117
118 if (!ctrl) break;
119
120 talloc_free(actx->ctrl->cookie);
121 actx->ctrl->cookie = talloc_steal(actx->ctrl->cookie, ctrl->cookie);
122 actx->ctrl->cookie_len = ctrl->cookie_len;
123
124 if (actx->ctrl->cookie_len > 0) {
125 actx->pending = true;
126 }
127 }
128 talloc_free(ares);
129 return ldb_request_done(req, LDB_SUCCESS);
130
131 default:
132 d_printf("%s: unknown Reply Type %u\n", __location__, ares->type);
133 return ldb_request_done(req, LDB_ERR_OTHER);
134 }
135
136 if (talloc_free(ares) == -1) {
137 d_printf("talloc_free failed\n");
138 actx->pending = 0;
139 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
140 }
141
142 if (ret) {
143 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
144 }
145
146 return LDB_SUCCESS;
147}
148
149static bool test_create_schema_type(struct ldb_context *ldb, struct test_rootDSE *root,
150 const char *filter,
151 int (*callback)(void *, struct ldb_context *ldb, struct ldb_message *),
152 void *private_data)
153{
154 struct ldb_control **ctrl;
155 struct ldb_paged_control *control;
156 struct ldb_request *req;
157 int ret;
158 struct test_schema_ctx *actx;
159
160 actx = talloc(ldb, struct test_schema_ctx);
161 actx->ldb = ldb;
162 actx->private_data = private_data;
163 actx->callback= callback;
164
165 ctrl = talloc_array(actx, struct ldb_control *, 2);
166 ctrl[0] = talloc(ctrl, struct ldb_control);
167 ctrl[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
168 ctrl[0]->critical = true;
169 control = talloc(ctrl[0], struct ldb_paged_control);
170 control->size = 1000;
171 control->cookie = NULL;
172 control->cookie_len = 0;
173 ctrl[0]->data = control;
174 ctrl[1] = NULL;
175
176 ret = ldb_build_search_req(&req, ldb, actx,
177 ldb_dn_new(actx, ldb, root->schemadn),
178 LDB_SCOPE_SUBTREE,
179 filter, NULL,
180 ctrl,
181 actx, test_schema_search_callback,
182 NULL);
183
184 actx->ctrl = control;
185 actx->count = 0;
186again:
187 actx->pending = false;
188
189 ret = ldb_request(ldb, req);
190 if (ret != LDB_SUCCESS) {
191 d_printf("search failed - %s\n", ldb_errstring(ldb));
192 talloc_free(actx);
193 return false;
194 }
195
196 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
197 if (ret != LDB_SUCCESS) {
198 d_printf("search error - %s\n", ldb_errstring(ldb));
199 talloc_free(actx);
200 return false;
201 }
202
203 if (actx->pending)
204 goto again;
205
206 d_printf("filter[%s] count[%u]\n", filter, actx->count);
207 talloc_free(actx);
208 return true;
209}
210
211static int test_add_attribute(void *ptr, struct ldb_context *ldb, struct ldb_message *msg)
212{
213 struct dsdb_schema *schema = talloc_get_type(ptr, struct dsdb_schema);
214 WERROR status;
215
216 status = dsdb_attribute_from_ldb(ldb, schema, msg);
217 if (!W_ERROR_IS_OK(status)) {
218 goto failed;
219 }
220
221 return LDB_SUCCESS;
222failed:
223 return LDB_ERR_OTHER;
224}
225
226static int test_add_class(void *ptr, struct ldb_context *ldb, struct ldb_message *msg)
227{
228 struct dsdb_schema *schema = talloc_get_type(ptr, struct dsdb_schema);
229 WERROR status;
230
231 status = dsdb_class_from_ldb(schema, msg);
232 if (!W_ERROR_IS_OK(status)) {
233 goto failed;
234 }
235
236 return LDB_SUCCESS;
237failed:
238 return LDB_ERR_OTHER;
239}
240
241static bool test_create_schema(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema **_schema)
242{
243 bool ret = true;
244 struct dsdb_schema *schema;
245
246 schema = talloc_zero(ldb, struct dsdb_schema);
247
248 d_printf("Fetching attributes...\n");
249 ret &= test_create_schema_type(ldb, root, "(objectClass=attributeSchema)",
250 test_add_attribute, schema);
251 d_printf("Fetching objectClasses...\n");
252 ret &= test_create_schema_type(ldb, root, "(objectClass=classSchema)",
253 test_add_class, schema);
254
255 if (ret == true) {
256 *_schema = schema;
257 }
258 return ret;
259}
260
261static bool test_dump_not_replicated(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
262{
263 struct dsdb_attribute *a;
264 uint32_t a_i = 1;
265
266 d_printf("Dumping not replicated attributes\n");
267
268 for (a=schema->attributes; a; a = a->next) {
269 if (!(a->systemFlags & 0x00000001)) continue;
270 d_printf("attr[%4u]: '%s'\n", a_i++,
271 a->lDAPDisplayName);
272 }
273
274 return true;
275}
276
277static bool test_dump_partial(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
278{
279 struct dsdb_attribute *a;
280 uint32_t a_i = 1;
281
282 d_printf("Dumping attributes which are provided by the global catalog\n");
283
284 for (a=schema->attributes; a; a = a->next) {
285 if (!(a->systemFlags & 0x00000002) && !a->isMemberOfPartialAttributeSet) continue;
286 d_printf("attr[%4u]: %u %u '%s'\n", a_i++,
287 a->systemFlags & 0x00000002, a->isMemberOfPartialAttributeSet,
288 a->lDAPDisplayName);
289 }
290
291 return true;
292}
293
294static bool test_dump_contructed(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
295{
296 struct dsdb_attribute *a;
297 uint32_t a_i = 1;
298
299 d_printf("Dumping constructed attributes\n");
300
301 for (a=schema->attributes; a; a = a->next) {
302 if (!(a->systemFlags & 0x00000004)) continue;
303 d_printf("attr[%4u]: '%s'\n", a_i++,
304 a->lDAPDisplayName);
305 }
306
307 return true;
308}
309
310static bool test_dump_sorted_syntax(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
311{
312 struct dsdb_attribute *a;
313 uint32_t a_i = 1;
314 uint32_t i;
315 const char *syntaxes[] = {
316 "2.5.5.0",
317 "2.5.5.1",
318 "2.5.5.2",
319 "2.5.5.3",
320 "2.5.5.4",
321 "2.5.5.5",
322 "2.5.5.6",
323 "2.5.5.7",
324 "2.5.5.8",
325 "2.5.5.9",
326 "2.5.5.10",
327 "2.5.5.11",
328 "2.5.5.12",
329 "2.5.5.13",
330 "2.5.5.14",
331 "2.5.5.15",
332 "2.5.5.16",
333 "2.5.5.17"
334 };
335
336 d_printf("Dumping attribute syntaxes\n");
337
338 for (i=0; i < ARRAY_SIZE(syntaxes); i++) {
339 for (a=schema->attributes; a; a = a->next) {
340 char *om_hex;
341
342 if (strcmp(syntaxes[i], a->attributeSyntax_oid) != 0) continue;
343
344 om_hex = data_blob_hex_string_upper(ldb, &a->oMObjectClass);
345 if (!om_hex) {
346 return false;
347 }
348
349 d_printf("attr[%4u]: %s %u '%s' '%s'\n", a_i++,
350 a->attributeSyntax_oid, a->oMSyntax,
351 om_hex, a->lDAPDisplayName);
352 talloc_free(om_hex);
353 }
354 }
355
356 return true;
357}
358
359static bool test_dump_not_in_filtered_replica(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
360{
361 struct dsdb_attribute *a;
362 uint32_t a_i = 1;
363
364 d_printf("Dumping attributes not in filtered replica\n");
365
366 for (a=schema->attributes; a; a = a->next) {
367 if (!dsdb_attribute_is_attr_in_filtered_replica(a)) {
368 d_printf("attr[%4u]: '%s'\n", a_i++,
369 a->lDAPDisplayName);
370 }
371 }
372 return true;
373}
374
375bool torture_ldap_schema(struct torture_context *torture)
376{
377 struct ldb_context *ldb;
378 bool ret = true;
379 const char *host = torture_setting_string(torture, "host", NULL);
380 char *url;
381 struct test_rootDSE rootDSE;
382 struct dsdb_schema *schema = NULL;
383
384 ZERO_STRUCT(rootDSE);
385
386 url = talloc_asprintf(torture, "ldap://%s/", host);
387
388 ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url,
389 NULL,
390 cmdline_credentials,
391 0);
392 if (!ldb) goto failed;
393
394 ret &= test_search_rootDSE(ldb, &rootDSE);
395 if (!ret) goto failed;
396 ret &= test_create_schema(ldb, &rootDSE, &schema);
397 if (!ret) goto failed;
398
399 ret &= test_dump_not_replicated(ldb, &rootDSE, schema);
400 ret &= test_dump_partial(ldb, &rootDSE, schema);
401 ret &= test_dump_contructed(ldb, &rootDSE, schema);
402 ret &= test_dump_sorted_syntax(ldb, &rootDSE, schema);
403 ret &= test_dump_not_in_filtered_replica(ldb, &rootDSE, schema);
404
405failed:
406 return ret;
407}
Note: See TracBrowser for help on using the repository browser.