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 "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"
31 #include "torture/torture.h"
32 #include "torture/ldap/proto.h"
34 #include "param/param.h"
37 const char *defaultdn
;
43 struct test_schema_ctx
{
44 struct ldb_context
*ldb
;
46 struct ldb_paged_control
*ctrl
;
50 int (*callback
)(void *, struct ldb_context
*ldb
, struct ldb_message
*);
54 static bool test_search_rootDSE(struct ldb_context
*ldb
, struct test_rootDSE
*root
)
57 struct ldb_message
*msg
;
60 d_printf("Testing RootDSE Search\n");
62 ret
= ldb_search(ldb
, ldb
, &r
, ldb_dn_new(ldb
, ldb
, NULL
),
63 LDB_SCOPE_BASE
, NULL
, NULL
);
64 if (ret
!= LDB_SUCCESS
) {
66 } else if (r
->count
!= 1) {
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
);
87 static int test_schema_search_callback(struct ldb_request
*req
, struct ldb_reply
*ares
)
89 struct test_schema_ctx
*actx
;
90 int ret
= LDB_SUCCESS
;
92 actx
= talloc_get_type(req
->context
, struct test_schema_ctx
);
95 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
97 if (ares
->error
!= LDB_SUCCESS
) {
98 return ldb_request_done(req
, ares
->error
);
101 switch (ares
->type
) {
102 case LDB_REPLY_ENTRY
:
104 ret
= actx
->callback(actx
->private_data
, actx
->ldb
, ares
->message
);
107 case LDB_REPLY_REFERRAL
:
111 if (ares
->controls
) {
112 struct ldb_paged_control
*ctrl
= NULL
;
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
);
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
;
128 if (actx
->ctrl
->cookie_len
> 0) {
129 actx
->pending
= true;
133 return ldb_request_done(req
, LDB_SUCCESS
);
136 d_printf("%s: unknown Reply Type %u\n", __location__
, ares
->type
);
137 return ldb_request_done(req
, LDB_ERR_OTHER
);
140 if (talloc_free(ares
) == -1) {
141 d_printf("talloc_free failed\n");
143 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
147 return ldb_request_done(req
, LDB_ERR_OPERATIONS_ERROR
);
153 static bool test_create_schema_type(struct ldb_context
*ldb
, struct test_rootDSE
*root
,
155 int (*callback
)(void *, struct ldb_context
*ldb
, struct ldb_message
*),
158 struct ldb_control
**ctrl
;
159 struct ldb_paged_control
*control
;
160 struct ldb_request
*req
;
162 struct test_schema_ctx
*actx
;
164 actx
= talloc(ldb
, struct test_schema_ctx
);
166 actx
->private_data
= private_data
;
167 actx
->callback
= callback
;
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
;
180 ret
= ldb_build_search_req(&req
, ldb
, actx
,
181 ldb_dn_new(actx
, ldb
, root
->schemadn
),
185 actx
, test_schema_search_callback
,
188 actx
->ctrl
= control
;
191 actx
->pending
= false;
193 ret
= ldb_request(ldb
, req
);
194 if (ret
!= LDB_SUCCESS
) {
195 d_printf("search failed - %s\n", ldb_errstring(ldb
));
200 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
201 if (ret
!= LDB_SUCCESS
) {
202 d_printf("search error - %s\n", ldb_errstring(ldb
));
210 d_printf("filter[%s] count[%u]\n", filter
, actx
->count
);
215 static int test_add_attribute(void *ptr
, struct ldb_context
*ldb
, struct ldb_message
*msg
)
217 struct dsdb_schema
*schema
= talloc_get_type(ptr
, struct dsdb_schema
);
218 struct dsdb_attribute
*attr
= NULL
;
221 attr
= talloc_zero(schema
, struct dsdb_attribute
);
226 status
= dsdb_attribute_from_ldb(ldb
, schema
, msg
, attr
, attr
);
227 if (!W_ERROR_IS_OK(status
)) {
231 DLIST_ADD_END(schema
->attributes
, attr
, struct dsdb_attribute
*);
235 return LDB_ERR_OTHER
;
238 static int test_add_class(void *ptr
, struct ldb_context
*ldb
, struct ldb_message
*msg
)
240 struct dsdb_schema
*schema
= talloc_get_type(ptr
, struct dsdb_schema
);
241 struct dsdb_class
*obj
;
244 obj
= talloc_zero(schema
, struct dsdb_class
);
249 status
= dsdb_class_from_ldb(schema
, msg
, obj
, obj
);
250 if (!W_ERROR_IS_OK(status
)) {
254 DLIST_ADD_END(schema
->classes
, obj
, struct dsdb_class
*);
257 return LDB_ERR_OTHER
;
260 static bool test_create_schema(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
**_schema
)
263 struct dsdb_schema
*schema
;
265 schema
= talloc_zero(ldb
, struct dsdb_schema
);
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
);
280 static bool test_dump_not_replicated(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
282 struct dsdb_attribute
*a
;
285 d_printf("Dumping not replicated attributes\n");
287 for (a
=schema
->attributes
; a
; a
= a
->next
) {
288 if (!(a
->systemFlags
& 0x00000001)) continue;
289 d_printf("attr[%4u]: '%s'\n", a_i
++,
296 static bool test_dump_partial(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
298 struct dsdb_attribute
*a
;
301 d_printf("Dumping attributes which are provided by the global catalog\n");
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
,
313 static bool test_dump_contructed(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
315 struct dsdb_attribute
*a
;
318 d_printf("Dumping constructed attributes\n");
320 for (a
=schema
->attributes
; a
; a
= a
->next
) {
321 if (!(a
->systemFlags
& 0x00000004)) continue;
322 d_printf("attr[%4u]: '%s'\n", a_i
++,
329 static bool test_dump_sorted_syntax(struct ldb_context
*ldb
, struct test_rootDSE
*root
, struct dsdb_schema
*schema
)
331 struct dsdb_attribute
*a
;
334 const char *syntaxes
[] = {
355 d_printf("Dumping attribute syntaxes\n");
357 for (i
=0; i
< ARRAY_SIZE(syntaxes
); i
++) {
358 for (a
=schema
->attributes
; a
; a
= a
->next
) {
361 if (strcmp(syntaxes
[i
], a
->attributeSyntax_oid
) != 0) continue;
363 om_hex
= data_blob_hex_string(ldb
, &a
->oMObjectClass
);
368 d_printf("attr[%4u]: %s %u '%s' '%s'\n", a_i
++,
369 a
->attributeSyntax_oid
, a
->oMSyntax
,
370 om_hex
, a
->lDAPDisplayName
);
378 bool torture_ldap_schema(struct torture_context
*torture
)
380 struct ldb_context
*ldb
;
382 const char *host
= torture_setting_string(torture
, "host", NULL
);
384 struct test_rootDSE rootDSE
;
385 struct dsdb_schema
*schema
= NULL
;
387 ZERO_STRUCT(rootDSE
);
389 url
= talloc_asprintf(torture
, "ldap://%s/", host
);
391 ldb
= ldb_wrap_connect(torture
, torture
->ev
, torture
->lp_ctx
, url
,
395 if (!ldb
) goto failed
;
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
;
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
);