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"
33 const char *defaultdn
;
39 struct test_schema_ctx
{
40 struct ldb_context
*ldb
;
42 struct ldb_paged_control
*ctrl
;
46 int (*callback
)(void *, struct ldb_context
*ldb
, struct ldb_message
*);
50 static bool test_search_rootDSE(struct ldb_context
*ldb
, struct test_rootDSE
*root
)
53 struct ldb_message
*msg
;
56 d_printf("Testing RootDSE Search\n");
58 ret
= ldb_search(ldb
, ldb
, &r
, ldb_dn_new(ldb
, ldb
, NULL
),
59 LDB_SCOPE_BASE
, NULL
, NULL
);
60 if (ret
!= LDB_SUCCESS
) {
62 } else if (r
->count
!= 1) {
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
);
83 static int test_schema_search_callback(struct ldb_request
*req
, struct ldb_reply
*ares
)
85 struct test_schema_ctx
*actx
;
86 int ret
= LDB_SUCCESS
;
88 actx
= talloc_get_type(req
->context
, struct test_schema_ctx
);
91 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
93 if (ares
->error
!= LDB_SUCCESS
) {
94 return ldb_request_done(req
, ares
->error
);
100 ret
= actx
->callback(actx
->private_data
, actx
->ldb
, ares
->message
);
103 case LDB_REPLY_REFERRAL
:
107 if (ares
->controls
) {
108 struct ldb_paged_control
*ctrl
= NULL
;
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
);
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
;
124 if (actx
->ctrl
->cookie_len
> 0) {
125 actx
->pending
= true;
129 return ldb_request_done(req
, LDB_SUCCESS
);
132 d_printf("%s: unknown Reply Type %u\n", __location__
, ares
->type
);
133 return ldb_request_done(req
, LDB_ERR_OTHER
);
136 if (talloc_free(ares
) == -1) {
137 d_printf("talloc_free failed\n");
139 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
143 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
149 static bool test_create_schema_type(struct ldb_context
*ldb
, struct test_rootDSE
*root
,
151 int (*callback
)(void *, struct ldb_context
*ldb
, struct ldb_message
*),
154 struct ldb_control
**ctrl
;
155 struct ldb_paged_control
*control
;
156 struct ldb_request
*req
;
158 struct test_schema_ctx
*actx
;
160 actx
= talloc(ldb
, struct test_schema_ctx
);
162 actx
->private_data
= private_data
;
163 actx
->callback
= callback
;
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
;
176 ret
= ldb_build_search_req(&req
, ldb
, actx
,
177 ldb_dn_new(actx
, ldb
, root
->schemadn
),
181 actx
, test_schema_search_callback
,
184 actx
->ctrl
= control
;
187 actx
->pending
= false;
189 ret
= ldb_request(ldb
, req
);
190 if (ret
!= LDB_SUCCESS
) {
191 d_printf("search failed - %s\n", ldb_errstring(ldb
));
196 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
197 if (ret
!= LDB_SUCCESS
) {
198 d_printf("search error - %s\n", ldb_errstring(ldb
));
206 d_printf("filter[%s] count[%u]\n", filter
, actx
->count
);
211 static int test_add_attribute(void *ptr
, struct ldb_context
*ldb
, struct ldb_message
*msg
)
213 struct dsdb_schema
*schema
= talloc_get_type(ptr
, struct dsdb_schema
);
216 status
= dsdb_set_attribute_from_ldb(ldb
, schema
, msg
);
217 if (!W_ERROR_IS_OK(status
)) {
223 return LDB_ERR_OTHER
;
226 static int test_add_class(void *ptr
, struct ldb_context
*ldb
, struct ldb_message
*msg
)
228 struct dsdb_schema
*schema
= talloc_get_type(ptr
, struct dsdb_schema
);
231 status
= dsdb_set_class_from_ldb(schema
, msg
);
232 if (!W_ERROR_IS_OK(status
)) {
238 return LDB_ERR_OTHER
;
241 static bool test_create_schema(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
**_schema
)
244 struct dsdb_schema
*schema
;
246 schema
= talloc_zero(ldb
, struct dsdb_schema
);
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
);
261 static bool test_dump_not_replicated(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
263 struct dsdb_attribute
*a
;
266 d_printf("Dumping not replicated attributes\n");
268 for (a
=schema
->attributes
; a
; a
= a
->next
) {
269 if (!(a
->systemFlags
& 0x00000001)) continue;
270 d_printf("attr[%4u]: '%s'\n", a_i
++,
277 static bool test_dump_partial(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
279 struct dsdb_attribute
*a
;
282 d_printf("Dumping attributes which are provided by the global catalog\n");
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
,
294 static bool test_dump_contructed(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
296 struct dsdb_attribute
*a
;
299 d_printf("Dumping constructed attributes\n");
301 for (a
=schema
->attributes
; a
; a
= a
->next
) {
302 if (!(a
->systemFlags
& 0x00000004)) continue;
303 d_printf("attr[%4u]: '%s'\n", a_i
++,
310 static bool test_dump_sorted_syntax(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
312 struct dsdb_attribute
*a
;
315 const char *syntaxes
[] = {
336 d_printf("Dumping attribute syntaxes\n");
338 for (i
=0; i
< ARRAY_SIZE(syntaxes
); i
++) {
339 for (a
=schema
->attributes
; a
; a
= a
->next
) {
342 if (strcmp(syntaxes
[i
], a
->attributeSyntax_oid
) != 0) continue;
344 om_hex
= data_blob_hex_string_upper(ldb
, &a
->oMObjectClass
);
349 d_printf("attr[%4u]: %s %u '%s' '%s'\n", a_i
++,
350 a
->attributeSyntax_oid
, a
->oMSyntax
,
351 om_hex
, a
->lDAPDisplayName
);
359 static bool test_dump_not_in_filtered_replica(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
361 struct dsdb_attribute
*a
;
364 d_printf("Dumping attributes not in filtered replica\n");
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
++,
375 bool torture_ldap_schema(struct torture_context
*torture
)
377 struct ldb_context
*ldb
;
379 const char *host
= torture_setting_string(torture
, "host", NULL
);
381 struct test_rootDSE rootDSE
;
382 struct dsdb_schema
*schema
= NULL
;
384 ZERO_STRUCT(rootDSE
);
386 url
= talloc_asprintf(torture
, "ldap://%s/", host
);
388 ldb
= ldb_wrap_connect(torture
, torture
->ev
, torture
->lp_ctx
, url
,
392 if (!ldb
) goto failed
;
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
;
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
);