2 Unix SMB/CIFS mplementation.
5 Copyright (C) Stefan Metzmacher 2006
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/>.
23 #include "libcli/ldap/ldap_client.h"
24 #include "lib/cmdline/popt_common.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "../lib/util/dlinklist.h"
29 #include "torture/torture.h"
30 #include "torture/ldap/proto.h"
34 const char *defaultdn
;
40 struct test_schema_ctx
{
41 struct ldb_context
*ldb
;
43 struct ldb_paged_control
*ctrl
;
47 int (*callback
)(void *, struct ldb_context
*ldb
, struct ldb_message
*);
51 static bool test_search_rootDSE(struct ldb_context
*ldb
, struct test_rootDSE
*root
)
54 struct ldb_message
*msg
;
57 d_printf("Testing RootDSE Search\n");
59 ret
= ldb_search(ldb
, ldb
, &r
, ldb_dn_new(ldb
, ldb
, NULL
),
60 LDB_SCOPE_BASE
, NULL
, NULL
);
61 if (ret
!= LDB_SUCCESS
) {
63 } else if (r
->count
!= 1) {
70 root
->defaultdn
= ldb_msg_find_attr_as_string(msg
, "defaultNamingContext", NULL
);
71 talloc_steal(ldb
, root
->defaultdn
);
72 root
->rootdn
= ldb_msg_find_attr_as_string(msg
, "rootDomainNamingContext", NULL
);
73 talloc_steal(ldb
, root
->rootdn
);
74 root
->configdn
= ldb_msg_find_attr_as_string(msg
, "configurationNamingContext", NULL
);
75 talloc_steal(ldb
, root
->configdn
);
76 root
->schemadn
= ldb_msg_find_attr_as_string(msg
, "schemaNamingContext", NULL
);
77 talloc_steal(ldb
, root
->schemadn
);
84 static int test_schema_search_callback(struct ldb_request
*req
, struct ldb_reply
*ares
)
86 struct test_schema_ctx
*actx
;
87 int ret
= LDB_SUCCESS
;
89 actx
= talloc_get_type(req
->context
, struct test_schema_ctx
);
92 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
94 if (ares
->error
!= LDB_SUCCESS
) {
95 return ldb_request_done(req
, ares
->error
);
101 ret
= actx
->callback(actx
->private_data
, actx
->ldb
, ares
->message
);
104 case LDB_REPLY_REFERRAL
:
108 if (ares
->controls
) {
109 struct ldb_paged_control
*ctrl
= NULL
;
112 for (i
=0; ares
->controls
[i
]; i
++) {
113 if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID
, ares
->controls
[i
]->oid
) == 0) {
114 ctrl
= talloc_get_type(ares
->controls
[i
]->data
, struct ldb_paged_control
);
121 talloc_free(actx
->ctrl
->cookie
);
122 actx
->ctrl
->cookie
= talloc_steal(actx
->ctrl
->cookie
, ctrl
->cookie
);
123 actx
->ctrl
->cookie_len
= ctrl
->cookie_len
;
125 if (actx
->ctrl
->cookie_len
> 0) {
126 actx
->pending
= true;
130 return ldb_request_done(req
, LDB_SUCCESS
);
133 d_printf("%s: unknown Reply Type %u\n", __location__
, ares
->type
);
134 return ldb_request_done(req
, LDB_ERR_OTHER
);
137 if (talloc_free(ares
) == -1) {
138 d_printf("talloc_free failed\n");
140 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
144 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
150 static bool test_create_schema_type(struct ldb_context
*ldb
, struct test_rootDSE
*root
,
152 int (*callback
)(void *, struct ldb_context
*ldb
, struct ldb_message
*),
155 struct ldb_control
**ctrl
;
156 struct ldb_paged_control
*control
;
157 struct ldb_request
*req
;
159 struct test_schema_ctx
*actx
;
161 actx
= talloc(ldb
, struct test_schema_ctx
);
163 actx
->private_data
= private_data
;
164 actx
->callback
= callback
;
166 ctrl
= talloc_array(actx
, struct ldb_control
*, 2);
167 ctrl
[0] = talloc(ctrl
, struct ldb_control
);
168 ctrl
[0]->oid
= LDB_CONTROL_PAGED_RESULTS_OID
;
169 ctrl
[0]->critical
= true;
170 control
= talloc(ctrl
[0], struct ldb_paged_control
);
171 control
->size
= 1000;
172 control
->cookie
= NULL
;
173 control
->cookie_len
= 0;
174 ctrl
[0]->data
= control
;
177 ret
= ldb_build_search_req(&req
, ldb
, actx
,
178 ldb_dn_new(actx
, ldb
, root
->schemadn
),
182 actx
, test_schema_search_callback
,
185 actx
->ctrl
= control
;
188 actx
->pending
= false;
190 ret
= ldb_request(ldb
, req
);
191 if (ret
!= LDB_SUCCESS
) {
192 d_printf("search failed - %s\n", ldb_errstring(ldb
));
197 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
198 if (ret
!= LDB_SUCCESS
) {
199 d_printf("search error - %s\n", ldb_errstring(ldb
));
207 d_printf("filter[%s] count[%u]\n", filter
, actx
->count
);
212 static int test_add_attribute(void *ptr
, struct ldb_context
*ldb
, struct ldb_message
*msg
)
214 struct dsdb_schema
*schema
= talloc_get_type(ptr
, struct dsdb_schema
);
217 status
= dsdb_set_attribute_from_ldb(ldb
, schema
, msg
);
218 if (!W_ERROR_IS_OK(status
)) {
224 return LDB_ERR_OTHER
;
227 static int test_add_class(void *ptr
, struct ldb_context
*ldb
, struct ldb_message
*msg
)
229 struct dsdb_schema
*schema
= talloc_get_type(ptr
, struct dsdb_schema
);
232 status
= dsdb_set_class_from_ldb(schema
, msg
);
233 if (!W_ERROR_IS_OK(status
)) {
239 return LDB_ERR_OTHER
;
242 static bool test_create_schema(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
**_schema
)
245 struct dsdb_schema
*schema
;
247 schema
= talloc_zero(ldb
, struct dsdb_schema
);
249 d_printf("Fetching attributes...\n");
250 ret
&= test_create_schema_type(ldb
, root
, "(objectClass=attributeSchema)",
251 test_add_attribute
, schema
);
252 d_printf("Fetching objectClasses...\n");
253 ret
&= test_create_schema_type(ldb
, root
, "(objectClass=classSchema)",
254 test_add_class
, schema
);
262 static bool test_dump_not_replicated(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
264 struct dsdb_attribute
*a
;
267 d_printf("Dumping not replicated attributes\n");
269 for (a
=schema
->attributes
; a
; a
= a
->next
) {
270 if (!(a
->systemFlags
& 0x00000001)) continue;
271 d_printf("attr[%4u]: '%s'\n", a_i
++,
278 static bool test_dump_partial(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
280 struct dsdb_attribute
*a
;
283 d_printf("Dumping attributes which are provided by the global catalog\n");
285 for (a
=schema
->attributes
; a
; a
= a
->next
) {
286 if (!(a
->systemFlags
& 0x00000002) && !a
->isMemberOfPartialAttributeSet
) continue;
287 d_printf("attr[%4u]: %u %u '%s'\n", a_i
++,
288 a
->systemFlags
& 0x00000002, a
->isMemberOfPartialAttributeSet
,
295 static bool test_dump_contructed(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
297 struct dsdb_attribute
*a
;
300 d_printf("Dumping constructed attributes\n");
302 for (a
=schema
->attributes
; a
; a
= a
->next
) {
303 if (!(a
->systemFlags
& 0x00000004)) continue;
304 d_printf("attr[%4u]: '%s'\n", a_i
++,
311 static bool test_dump_sorted_syntax(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
313 struct dsdb_attribute
*a
;
316 const char *syntaxes
[] = {
337 d_printf("Dumping attribute syntaxes\n");
339 for (i
=0; i
< ARRAY_SIZE(syntaxes
); i
++) {
340 for (a
=schema
->attributes
; a
; a
= a
->next
) {
343 if (strcmp(syntaxes
[i
], a
->attributeSyntax_oid
) != 0) continue;
345 om_hex
= data_blob_hex_string_upper(ldb
, &a
->oMObjectClass
);
350 d_printf("attr[%4u]: %s %u '%s' '%s'\n", a_i
++,
351 a
->attributeSyntax_oid
, a
->oMSyntax
,
352 om_hex
, a
->lDAPDisplayName
);
360 static bool test_dump_not_in_filtered_replica(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
362 struct dsdb_attribute
*a
;
365 d_printf("Dumping attributes not in filtered replica\n");
367 for (a
=schema
->attributes
; a
; a
= a
->next
) {
368 if (!dsdb_attribute_is_attr_in_filtered_replica(a
)) {
369 d_printf("attr[%4u]: '%s'\n", a_i
++,
376 bool torture_ldap_schema(struct torture_context
*torture
)
378 struct ldb_context
*ldb
;
380 const char *host
= torture_setting_string(torture
, "host", NULL
);
382 struct test_rootDSE rootDSE
;
383 struct dsdb_schema
*schema
= NULL
;
385 ZERO_STRUCT(rootDSE
);
387 url
= talloc_asprintf(torture
, "ldap://%s/", host
);
389 ldb
= ldb_wrap_connect(torture
, torture
->ev
, torture
->lp_ctx
, url
,
391 popt_get_cmdline_credentials(),
393 if (!ldb
) goto failed
;
395 ret
&= test_search_rootDSE(ldb
, &rootDSE
);
396 if (!ret
) goto failed
;
397 ret
&= test_create_schema(ldb
, &rootDSE
, &schema
);
398 if (!ret
) goto failed
;
400 ret
&= test_dump_not_replicated(ldb
, &rootDSE
, schema
);
401 ret
&= test_dump_partial(ldb
, &rootDSE
, schema
);
402 ret
&= test_dump_contructed(ldb
, &rootDSE
, schema
);
403 ret
&= test_dump_sorted_syntax(ldb
, &rootDSE
, schema
);
404 ret
&= test_dump_not_in_filtered_replica(ldb
, &rootDSE
, schema
);