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