~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/ldap/schema.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
36
struct test_rootDSE {
 
37
        const char *defaultdn;
 
38
        const char *rootdn;
 
39
        const char *configdn;
 
40
        const char *schemadn;
 
41
};
 
42
 
 
43
struct 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
 
 
54
static 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
 
 
87
static 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
 
 
153
static 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;
 
190
again:
 
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
 
 
215
static 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(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;
 
233
failed:
 
234
        talloc_free(attr);
 
235
        return LDB_ERR_OTHER;
 
236
}
 
237
 
 
238
static 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;
 
256
failed:
 
257
        return LDB_ERR_OTHER;
 
258
}
 
259
 
 
260
static 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
 
 
280
static 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
 
 
296
static 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
 
 
313
static 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
 
 
329
static 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
 
 
378
bool 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
 
 
407
failed:
 
408
        return ret;
 
409
}