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(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);