source: trunk/server/source4/torture/ldap/basic.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 24.2 KB
Line 
1/*
2 Unix SMB/CIFS mplementation.
3 LDAP protocol helper functions for SAMBA
4
5 Copyright (C) Stefan Metzmacher 2004
6 Copyright (C) Simo Sorce 2004
7 Copyright (C) Matthias Dieter Wallnöfer 2009-2010
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22*/
23
24#include "includes.h"
25#include "ldb_wrap.h"
26#include "libcli/ldap/ldap_client.h"
27#include "lib/cmdline/popt_common.h"
28
29#include "torture/torture.h"
30#include "torture/ldap/proto.h"
31
32
33static bool test_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password)
34{
35 NTSTATUS status;
36 bool ret = true;
37
38 status = torture_ldap_bind(conn, userdn, password);
39 if (!NT_STATUS_IS_OK(status)) {
40 ret = false;
41 }
42
43 return ret;
44}
45
46static bool test_bind_sasl(struct torture_context *tctx,
47 struct ldap_connection *conn, struct cli_credentials *creds)
48{
49 NTSTATUS status;
50 bool ret = true;
51
52 printf("Testing sasl bind as user\n");
53
54 status = torture_ldap_bind_sasl(conn, creds, tctx->lp_ctx);
55 if (!NT_STATUS_IS_OK(status)) {
56 ret = false;
57 }
58
59 return ret;
60}
61
62static bool test_multibind(struct ldap_connection *conn, const char *userdn, const char *password)
63{
64 bool ret = true;
65
66 printf("Testing multiple binds on a single connection as anonymous and user\n");
67
68 ret = test_bind_simple(conn, NULL, NULL);
69 if (!ret) {
70 printf("1st bind as anonymous failed\n");
71 return ret;
72 }
73
74 ret = test_bind_simple(conn, userdn, password);
75 if (!ret) {
76 printf("2nd bind as authenticated user failed\n");
77 }
78
79 return ret;
80}
81
82static bool test_search_rootDSE(struct ldap_connection *conn, const char **basedn,
83 const char ***partitions)
84{
85 bool ret = true;
86 struct ldap_message *msg, *result;
87 struct ldap_request *req;
88 int i;
89 struct ldap_SearchResEntry *r;
90 NTSTATUS status;
91
92 printf("Testing RootDSE Search\n");
93
94 *basedn = NULL;
95
96 if (partitions != NULL) {
97 *partitions = const_str_list(str_list_make_empty(conn));
98 }
99
100 msg = new_ldap_message(conn);
101 if (!msg) {
102 return false;
103 }
104
105 msg->type = LDAP_TAG_SearchRequest;
106 msg->r.SearchRequest.basedn = "";
107 msg->r.SearchRequest.scope = LDAP_SEARCH_SCOPE_BASE;
108 msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER;
109 msg->r.SearchRequest.timelimit = 0;
110 msg->r.SearchRequest.sizelimit = 0;
111 msg->r.SearchRequest.attributesonly = false;
112 msg->r.SearchRequest.tree = ldb_parse_tree(msg, "(objectclass=*)");
113 msg->r.SearchRequest.num_attributes = 0;
114 msg->r.SearchRequest.attributes = NULL;
115
116 req = ldap_request_send(conn, msg);
117 if (req == NULL) {
118 printf("Could not setup ldap search\n");
119 return false;
120 }
121
122 status = ldap_result_one(req, &result, LDAP_TAG_SearchResultEntry);
123 if (!NT_STATUS_IS_OK(status)) {
124 printf("search failed - %s\n", nt_errstr(status));
125 return false;
126 }
127
128 printf("received %d replies\n", req->num_replies);
129
130 r = &result->r.SearchResultEntry;
131
132 DEBUG(1,("\tdn: %s\n", r->dn));
133 for (i=0; i<r->num_attributes; i++) {
134 int j;
135 for (j=0; j<r->attributes[i].num_values; j++) {
136 DEBUG(1,("\t%s: %d %.*s\n", r->attributes[i].name,
137 (int)r->attributes[i].values[j].length,
138 (int)r->attributes[i].values[j].length,
139 (char *)r->attributes[i].values[j].data));
140 if (!(*basedn) &&
141 strcasecmp("defaultNamingContext",r->attributes[i].name)==0) {
142 *basedn = talloc_asprintf(conn, "%.*s",
143 (int)r->attributes[i].values[j].length,
144 (char *)r->attributes[i].values[j].data);
145 }
146 if ((partitions != NULL) &&
147 (strcasecmp("namingContexts", r->attributes[i].name) == 0)) {
148 char *entry = talloc_asprintf(conn, "%.*s",
149 (int)r->attributes[i].values[j].length,
150 (char *)r->attributes[i].values[j].data);
151 *partitions = str_list_add(*partitions, entry);
152 }
153 }
154 }
155
156 return ret;
157}
158
159static bool test_compare_sasl(struct ldap_connection *conn, const char *basedn)
160{
161 struct ldap_message *msg, *rep;
162 struct ldap_request *req;
163 const char *val;
164 NTSTATUS status;
165
166 printf("Testing SASL Compare: %s\n", basedn);
167
168 if (!basedn) {
169 return false;
170 }
171
172 msg = new_ldap_message(conn);
173 if (!msg) {
174 return false;
175 }
176
177 msg->type = LDAP_TAG_CompareRequest;
178 msg->r.CompareRequest.dn = basedn;
179 msg->r.CompareRequest.attribute = talloc_strdup(msg, "objectClass");
180 val = "domain";
181 msg->r.CompareRequest.value = data_blob_talloc(msg, val, strlen(val));
182
183 req = ldap_request_send(conn, msg);
184 if (!req) {
185 return false;
186 }
187
188 status = ldap_result_one(req, &rep, LDAP_TAG_CompareResponse);
189 if (!NT_STATUS_IS_OK(status)) {
190 printf("error in ldap compare request - %s\n", nt_errstr(status));
191 return false;
192 }
193
194 DEBUG(5,("Code: %d DN: [%s] ERROR:[%s] REFERRAL:[%s]\n",
195 rep->r.CompareResponse.resultcode,
196 rep->r.CompareResponse.dn,
197 rep->r.CompareResponse.errormessage,
198 rep->r.CompareResponse.referral));
199
200 return true;
201}
202
203/*
204 * This takes an AD error message and splits it into the WERROR code
205 * (WERR_DS_GENERIC if none found) and the reason (remaining string).
206 */
207static WERROR ad_error(const char *err_msg, char **reason)
208{
209 WERROR err = W_ERROR(strtol(err_msg, reason, 16));
210
211 if ((reason != NULL) && (*reason[0] != ':')) {
212 return WERR_DS_GENERIC_ERROR; /* not an AD std error message */
213 }
214
215 if (reason != NULL) {
216 *reason += 2; /* skip ": " */
217 }
218 return err;
219}
220
221/* This has to be done using the LDAP API since the LDB API does only transmit
222 * the error code and not the error message. */
223static bool test_error_codes(struct torture_context *tctx,
224 struct ldap_connection *conn, const char *basedn)
225{
226 struct ldap_message *msg, *rep;
227 struct ldap_request *req;
228 const char *err_code_str;
229 char *endptr;
230 WERROR err;
231 NTSTATUS status;
232
233 printf("Testing the most important error code -> error message conversions!\n");
234
235 if (!basedn) {
236 return false;
237 }
238
239 msg = new_ldap_message(conn);
240 if (!msg) {
241 return false;
242 }
243
244 printf(" Try a wrong addition\n");
245
246 msg->type = LDAP_TAG_AddRequest;
247 msg->r.AddRequest.dn = basedn;
248 msg->r.AddRequest.num_attributes = 0;
249 msg->r.AddRequest.attributes = NULL;
250
251 req = ldap_request_send(conn, msg);
252 if (!req) {
253 return false;
254 }
255
256 status = ldap_result_one(req, &rep, LDAP_TAG_AddResponse);
257 if (!NT_STATUS_IS_OK(status)) {
258 printf("error in ldap add request - %s\n", nt_errstr(status));
259 return false;
260 }
261
262 if ((rep->r.AddResponse.resultcode == 0)
263 || (rep->r.AddResponse.errormessage == NULL)
264 || (strtol(rep->r.AddResponse.errormessage, &endptr,16) <= 0)
265 || (*endptr != ':')) {
266 printf("Invalid error message!\n");
267 return false;
268 }
269
270 err = ad_error(rep->r.AddResponse.errormessage, &endptr);
271 err_code_str = win_errstr(err);
272 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
273 if ((!W_ERROR_EQUAL(err, WERR_DS_REFERRAL))
274 || (rep->r.AddResponse.resultcode != LDAP_REFERRAL)) {
275 return false;
276 }
277 if ((rep->r.AddResponse.referral == NULL)
278 || (strstr(rep->r.AddResponse.referral, basedn) == NULL)) {
279 return false;
280 }
281
282 printf(" Try another wrong addition\n");
283
284 msg->type = LDAP_TAG_AddRequest;
285 msg->r.AddRequest.dn = "";
286 msg->r.AddRequest.num_attributes = 0;
287 msg->r.AddRequest.attributes = NULL;
288
289 req = ldap_request_send(conn, msg);
290 if (!req) {
291 return false;
292 }
293
294 status = ldap_result_one(req, &rep, LDAP_TAG_AddResponse);
295 if (!NT_STATUS_IS_OK(status)) {
296 printf("error in ldap add request - %s\n", nt_errstr(status));
297 return false;
298 }
299
300 if ((rep->r.AddResponse.resultcode == 0)
301 || (rep->r.AddResponse.errormessage == NULL)
302 || (strtol(rep->r.AddResponse.errormessage, &endptr,16) <= 0)
303 || (*endptr != ':')) {
304 printf("Invalid error message!\n");
305 return false;
306 }
307
308 err = ad_error(rep->r.AddResponse.errormessage, &endptr);
309 err_code_str = win_errstr(err);
310 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
311 if ((!W_ERROR_EQUAL(err, WERR_DS_ROOT_MUST_BE_NC) &&
312 !W_ERROR_EQUAL(err, WERR_DS_NAMING_VIOLATION))
313 || (rep->r.AddResponse.resultcode != LDAP_NAMING_VIOLATION)) {
314 return false;
315 }
316
317 printf(" Try a wrong modification\n");
318
319 msg->type = LDAP_TAG_ModifyRequest;
320 msg->r.ModifyRequest.dn = basedn;
321 msg->r.ModifyRequest.num_mods = 0;
322 msg->r.ModifyRequest.mods = NULL;
323
324 req = ldap_request_send(conn, msg);
325 if (!req) {
326 return false;
327 }
328
329 status = ldap_result_one(req, &rep, LDAP_TAG_ModifyResponse);
330 if (!NT_STATUS_IS_OK(status)) {
331 printf("error in ldap modifification request - %s\n", nt_errstr(status));
332 return false;
333 }
334
335 if ((rep->r.ModifyResponse.resultcode == 0)
336 || (rep->r.ModifyResponse.errormessage == NULL)
337 || (strtol(rep->r.ModifyResponse.errormessage, &endptr,16) <= 0)
338 || (*endptr != ':')) {
339 printf("Invalid error message!\n");
340 return false;
341 }
342
343 err = ad_error(rep->r.ModifyResponse.errormessage, &endptr);
344 err_code_str = win_errstr(err);
345 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
346 if ((!W_ERROR_EQUAL(err, WERR_INVALID_PARAM) &&
347 !W_ERROR_EQUAL(err, WERR_DS_UNWILLING_TO_PERFORM))
348 || (rep->r.ModifyResponse.resultcode != LDAP_UNWILLING_TO_PERFORM)) {
349 return false;
350 }
351
352 printf(" Try another wrong modification\n");
353
354 msg->type = LDAP_TAG_ModifyRequest;
355 msg->r.ModifyRequest.dn = "";
356 msg->r.ModifyRequest.num_mods = 0;
357 msg->r.ModifyRequest.mods = NULL;
358
359 req = ldap_request_send(conn, msg);
360 if (!req) {
361 return false;
362 }
363
364 status = ldap_result_one(req, &rep, LDAP_TAG_ModifyResponse);
365 if (!NT_STATUS_IS_OK(status)) {
366 printf("error in ldap modifification request - %s\n", nt_errstr(status));
367 return false;
368 }
369
370 if ((rep->r.ModifyResponse.resultcode == 0)
371 || (rep->r.ModifyResponse.errormessage == NULL)
372 || (strtol(rep->r.ModifyResponse.errormessage, &endptr,16) <= 0)
373 || (*endptr != ':')) {
374 printf("Invalid error message!\n");
375 return false;
376 }
377
378 err = ad_error(rep->r.ModifyResponse.errormessage, &endptr);
379 err_code_str = win_errstr(err);
380 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
381 if ((!W_ERROR_EQUAL(err, WERR_INVALID_PARAM) &&
382 !W_ERROR_EQUAL(err, WERR_DS_UNWILLING_TO_PERFORM))
383 || (rep->r.ModifyResponse.resultcode != LDAP_UNWILLING_TO_PERFORM)) {
384 return false;
385 }
386
387 printf(" Try a wrong removal\n");
388
389 msg->type = LDAP_TAG_DelRequest;
390 msg->r.DelRequest.dn = basedn;
391
392 req = ldap_request_send(conn, msg);
393 if (!req) {
394 return false;
395 }
396
397 status = ldap_result_one(req, &rep, LDAP_TAG_DelResponse);
398 if (!NT_STATUS_IS_OK(status)) {
399 printf("error in ldap removal request - %s\n", nt_errstr(status));
400 return false;
401 }
402
403 if ((rep->r.DelResponse.resultcode == 0)
404 || (rep->r.DelResponse.errormessage == NULL)
405 || (strtol(rep->r.DelResponse.errormessage, &endptr,16) <= 0)
406 || (*endptr != ':')) {
407 printf("Invalid error message!\n");
408 return false;
409 }
410
411 err = ad_error(rep->r.DelResponse.errormessage, &endptr);
412 err_code_str = win_errstr(err);
413 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
414 if ((!W_ERROR_EQUAL(err, WERR_DS_CANT_DELETE) &&
415 !W_ERROR_EQUAL(err, WERR_DS_UNWILLING_TO_PERFORM))
416 || (rep->r.DelResponse.resultcode != LDAP_UNWILLING_TO_PERFORM)) {
417 return false;
418 }
419
420 printf(" Try another wrong removal\n");
421
422 msg->type = LDAP_TAG_DelRequest;
423 msg->r.DelRequest.dn = "";
424
425 req = ldap_request_send(conn, msg);
426 if (!req) {
427 return false;
428 }
429
430 status = ldap_result_one(req, &rep, LDAP_TAG_DelResponse);
431 if (!NT_STATUS_IS_OK(status)) {
432 printf("error in ldap removal request - %s\n", nt_errstr(status));
433 return false;
434 }
435
436 if ((rep->r.DelResponse.resultcode == 0)
437 || (rep->r.DelResponse.errormessage == NULL)
438 || (strtol(rep->r.DelResponse.errormessage, &endptr,16) <= 0)
439 || (*endptr != ':')) {
440 printf("Invalid error message!\n");
441 return false;
442 }
443
444 err = ad_error(rep->r.DelResponse.errormessage, &endptr);
445 err_code_str = win_errstr(err);
446 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
447 if ((!W_ERROR_EQUAL(err, WERR_DS_OBJ_NOT_FOUND) &&
448 !W_ERROR_EQUAL(err, WERR_DS_NO_SUCH_OBJECT))
449 || (rep->r.DelResponse.resultcode != LDAP_NO_SUCH_OBJECT)) {
450 return false;
451 }
452
453 printf(" Try a wrong rename\n");
454
455 msg->type = LDAP_TAG_ModifyDNRequest;
456 msg->r.ModifyDNRequest.dn = basedn;
457 msg->r.ModifyDNRequest.newrdn = "dc=test";
458 msg->r.ModifyDNRequest.deleteolddn = true;
459 msg->r.ModifyDNRequest.newsuperior = NULL;
460
461 req = ldap_request_send(conn, msg);
462 if (!req) {
463 return false;
464 }
465
466 status = ldap_result_one(req, &rep, LDAP_TAG_ModifyDNResponse);
467 if (!NT_STATUS_IS_OK(status)) {
468 printf("error in ldap rename request - %s\n", nt_errstr(status));
469 return false;
470 }
471
472 if ((rep->r.ModifyDNResponse.resultcode == 0)
473 || (rep->r.ModifyDNResponse.errormessage == NULL)
474 || (strtol(rep->r.ModifyDNResponse.errormessage, &endptr,16) <= 0)
475 || (*endptr != ':')) {
476 printf("Invalid error message!\n");
477 return false;
478 }
479
480 err = ad_error(rep->r.ModifyDNResponse.errormessage, &endptr);
481 err_code_str = win_errstr(err);
482 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
483 if ((!W_ERROR_EQUAL(err, WERR_DS_NO_PARENT_OBJECT) &&
484 !W_ERROR_EQUAL(err, WERR_DS_GENERIC_ERROR))
485 || (rep->r.ModifyDNResponse.resultcode != LDAP_OTHER)) {
486 return false;
487 }
488
489 printf(" Try another wrong rename\n");
490
491 msg->type = LDAP_TAG_ModifyDNRequest;
492 msg->r.ModifyDNRequest.dn = basedn;
493 msg->r.ModifyDNRequest.newrdn = basedn;
494 msg->r.ModifyDNRequest.deleteolddn = true;
495 msg->r.ModifyDNRequest.newsuperior = NULL;
496
497 req = ldap_request_send(conn, msg);
498 if (!req) {
499 return false;
500 }
501
502 status = ldap_result_one(req, &rep, LDAP_TAG_ModifyDNResponse);
503 if (!NT_STATUS_IS_OK(status)) {
504 printf("error in ldap rename request - %s\n", nt_errstr(status));
505 return false;
506 }
507
508 if ((rep->r.ModifyDNResponse.resultcode == 0)
509 || (rep->r.ModifyDNResponse.errormessage == NULL)
510 || (strtol(rep->r.ModifyDNResponse.errormessage, &endptr,16) <= 0)
511 || (*endptr != ':')) {
512 printf("Invalid error message!\n");
513 return false;
514 }
515
516 err = ad_error(rep->r.ModifyDNResponse.errormessage, &endptr);
517 err_code_str = win_errstr(err);
518 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
519 if ((!W_ERROR_EQUAL(err, WERR_INVALID_PARAM) &&
520 !W_ERROR_EQUAL(err, WERR_DS_NAMING_VIOLATION))
521 || (rep->r.ModifyDNResponse.resultcode != LDAP_NAMING_VIOLATION)) {
522 return false;
523 }
524
525 printf(" Try another wrong rename\n");
526
527 msg->type = LDAP_TAG_ModifyDNRequest;
528 msg->r.ModifyDNRequest.dn = basedn;
529 msg->r.ModifyDNRequest.newrdn = "";
530 msg->r.ModifyDNRequest.deleteolddn = true;
531 msg->r.ModifyDNRequest.newsuperior = NULL;
532
533 req = ldap_request_send(conn, msg);
534 if (!req) {
535 return false;
536 }
537
538 status = ldap_result_one(req, &rep, LDAP_TAG_ModifyDNResponse);
539 if (!NT_STATUS_IS_OK(status)) {
540 printf("error in ldap rename request - %s\n", nt_errstr(status));
541 return false;
542 }
543
544 if ((rep->r.ModifyDNResponse.resultcode == 0)
545 || (rep->r.ModifyDNResponse.errormessage == NULL)
546 || (strtol(rep->r.ModifyDNResponse.errormessage, &endptr,16) <= 0)
547 || (*endptr != ':')) {
548 printf("Invalid error message!\n");
549 return false;
550 }
551
552 err = ad_error(rep->r.ModifyDNResponse.errormessage, &endptr);
553 err_code_str = win_errstr(err);
554 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
555 if ((!W_ERROR_EQUAL(err, WERR_INVALID_PARAM) &&
556 !W_ERROR_EQUAL(err, WERR_DS_PROTOCOL_ERROR))
557 || (rep->r.ModifyDNResponse.resultcode != LDAP_PROTOCOL_ERROR)) {
558 return false;
559 }
560
561 printf(" Try another wrong rename\n");
562
563 msg->type = LDAP_TAG_ModifyDNRequest;
564 msg->r.ModifyDNRequest.dn = "";
565 msg->r.ModifyDNRequest.newrdn = "cn=temp";
566 msg->r.ModifyDNRequest.deleteolddn = true;
567 msg->r.ModifyDNRequest.newsuperior = NULL;
568
569 req = ldap_request_send(conn, msg);
570 if (!req) {
571 return false;
572 }
573
574 status = ldap_result_one(req, &rep, LDAP_TAG_ModifyDNResponse);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("error in ldap rename request - %s\n", nt_errstr(status));
577 return false;
578 }
579
580 if ((rep->r.ModifyDNResponse.resultcode == 0)
581 || (rep->r.ModifyDNResponse.errormessage == NULL)
582 || (strtol(rep->r.ModifyDNResponse.errormessage, &endptr,16) <= 0)
583 || (*endptr != ':')) {
584 printf("Invalid error message!\n");
585 return false;
586 }
587
588 err = ad_error(rep->r.ModifyDNResponse.errormessage, &endptr);
589 err_code_str = win_errstr(err);
590 printf(" - Errorcode: %s; Reason: %s\n", err_code_str, endptr);
591 if ((!W_ERROR_EQUAL(err, WERR_DS_OBJ_NOT_FOUND) &&
592 !W_ERROR_EQUAL(err, WERR_DS_NO_SUCH_OBJECT))
593 || (rep->r.ModifyDNResponse.resultcode != LDAP_NO_SUCH_OBJECT)) {
594 return false;
595 }
596
597 return true;
598}
599
600static bool test_referrals(struct torture_context *tctx, TALLOC_CTX *mem_ctx,
601 const char *url, const char *basedn, const char **partitions)
602{
603 struct ldb_context *ldb;
604 struct ldb_result *res;
605 const char * const *attrs = { NULL };
606 struct ldb_dn *dn1, *dn2;
607 int ret;
608 int i, j, k;
609 char *tempstr;
610 bool found, l_found;
611
612 printf("Testing referrals\n");
613
614 if (partitions[0] == NULL) {
615 printf("Partitions list empty!\n");
616 return false;
617 }
618
619 if (strcmp(partitions[0], basedn) != 0) {
620 printf("The first (root) partition DN should be the base DN!\n");
621 return false;
622 }
623
624 ldb = ldb_wrap_connect(mem_ctx, tctx->ev, tctx->lp_ctx, url,
625 NULL, cmdline_credentials, 0);
626
627 /* "partitions[i]" are the partitions for which we search the parents */
628 for (i = 1; partitions[i] != NULL; i++) {
629 dn1 = ldb_dn_new(mem_ctx, ldb, partitions[i]);
630 if (dn1 == NULL) {
631 printf("Out of memory\n");
632 talloc_free(ldb);
633 return false;
634 }
635
636 /* search using base scope */
637 /* "partitions[j]" are the parent candidates */
638 for (j = str_list_length(partitions) - 1; j >= 0; --j) {
639 dn2 = ldb_dn_new(mem_ctx, ldb, partitions[j]);
640 if (dn2 == NULL) {
641 printf("Out of memory\n");
642 talloc_free(ldb);
643 return false;
644 }
645
646 ret = ldb_search(ldb, mem_ctx, &res, dn2,
647 LDB_SCOPE_BASE, attrs,
648 "(foo=bar)");
649 if (ret != LDB_SUCCESS) {
650 printf("%s", ldb_errstring(ldb));
651 talloc_free(ldb);
652 return false;
653 }
654
655 if (res->refs != NULL) {
656 printf("There shouldn't be generated any referrals in the base scope!\n");
657 talloc_free(ldb);
658 return false;
659 }
660
661 talloc_free(res);
662 talloc_free(dn2);
663 }
664
665 /* search using onelevel scope */
666 found = false;
667 /* "partitions[j]" are the parent candidates */
668 for (j = str_list_length(partitions) - 1; j >= 0; --j) {
669 dn2 = ldb_dn_new(mem_ctx, ldb, partitions[j]);
670 if (dn2 == NULL) {
671 printf("Out of memory\n");
672 talloc_free(ldb);
673 return false;
674 }
675
676 ret = ldb_search(ldb, mem_ctx, &res, dn2,
677 LDB_SCOPE_ONELEVEL, attrs,
678 "(foo=bar)");
679 if (ret != LDB_SUCCESS) {
680 printf("%s", ldb_errstring(ldb));
681 talloc_free(ldb);
682 return false;
683 }
684
685 tempstr = talloc_asprintf(mem_ctx, "/%s??base",
686 partitions[i]);
687 if (tempstr == NULL) {
688 printf("Out of memory\n");
689 talloc_free(ldb);
690 return false;
691 }
692
693 /* Try to find or find not a matching referral */
694 l_found = false;
695 for (k = 0; (!l_found) && (res->refs != NULL)
696 && (res->refs[k] != NULL); k++) {
697 if (strstr(res->refs[k], tempstr) != NULL) {
698 l_found = true;
699 }
700 }
701
702 talloc_free(tempstr);
703
704 if ((!found) && (ldb_dn_compare_base(dn2, dn1) == 0)
705 && (ldb_dn_compare(dn2, dn1) != 0)) {
706 /* This is a referral candidate */
707 if (!l_found) {
708 printf("A required referral hasn't been found on onelevel scope (%s -> %s)!\n", partitions[j], partitions[i]);
709 talloc_free(ldb);
710 return false;
711 }
712 found = true;
713 } else {
714 /* This isn't a referral candidate */
715 if (l_found) {
716 printf("A unrequired referral has been found on onelevel scope (%s -> %s)!\n", partitions[j], partitions[i]);
717 talloc_free(ldb);
718 return false;
719 }
720 }
721
722 talloc_free(res);
723 talloc_free(dn2);
724 }
725
726 /* search using subtree scope */
727 found = false;
728 /* "partitions[j]" are the parent candidates */
729 for (j = str_list_length(partitions) - 1; j >= 0; --j) {
730 dn2 = ldb_dn_new(mem_ctx, ldb, partitions[j]);
731 if (dn2 == NULL) {
732 printf("Out of memory\n");
733 talloc_free(ldb);
734 return false;
735 }
736
737 ret = ldb_search(ldb, mem_ctx, &res, dn2,
738 LDB_SCOPE_SUBTREE, attrs,
739 "(foo=bar)");
740 if (ret != LDB_SUCCESS) {
741 printf("%s", ldb_errstring(ldb));
742 talloc_free(ldb);
743 return false;
744 }
745
746 tempstr = talloc_asprintf(mem_ctx, "/%s",
747 partitions[i]);
748 if (tempstr == NULL) {
749 printf("Out of memory\n");
750 talloc_free(ldb);
751 return false;
752 }
753
754 /* Try to find or find not a matching referral */
755 l_found = false;
756 for (k = 0; (!l_found) && (res->refs != NULL)
757 && (res->refs[k] != NULL); k++) {
758 if (strstr(res->refs[k], tempstr) != NULL) {
759 l_found = true;
760 }
761 }
762
763 talloc_free(tempstr);
764
765 if ((!found) && (ldb_dn_compare_base(dn2, dn1) == 0)
766 && (ldb_dn_compare(dn2, dn1) != 0)) {
767 /* This is a referral candidate */
768 if (!l_found) {
769 printf("A required referral hasn't been found on subtree scope (%s -> %s)!\n", partitions[j], partitions[i]);
770 talloc_free(ldb);
771 return false;
772 }
773 found = true;
774 } else {
775 /* This isn't a referral candidate */
776 if (l_found) {
777 printf("A unrequired referral has been found on subtree scope (%s -> %s)!\n", partitions[j], partitions[i]);
778 talloc_free(ldb);
779 return false;
780 }
781 }
782
783 talloc_free(res);
784 talloc_free(dn2);
785 }
786
787 talloc_free(dn1);
788 }
789
790 talloc_free(ldb);
791
792 return true;
793}
794
795static bool test_abandom_request(struct torture_context *tctx,
796 struct ldap_connection *conn, const char *basedn)
797{
798 struct ldap_message *msg;
799 struct ldap_request *req;
800 NTSTATUS status;
801
802 printf("Testing the AbandonRequest with an old message id!\n");
803
804 if (!basedn) {
805 return false;
806 }
807
808 msg = new_ldap_message(conn);
809 if (!msg) {
810 return false;
811 }
812
813 printf(" Try a AbandonRequest for an old message id\n");
814
815 msg->type = LDAP_TAG_AbandonRequest;
816 msg->r.AbandonRequest.messageid = 1;
817
818 req = ldap_request_send(conn, msg);
819 if (!req) {
820 return false;
821 }
822
823 status = ldap_request_wait(req);
824 if (!NT_STATUS_IS_OK(status)) {
825 printf("error in ldap abandon request - %s\n", nt_errstr(status));
826 return false;
827 }
828
829 return true;
830}
831
832
833bool torture_ldap_basic(struct torture_context *torture)
834{
835 NTSTATUS status;
836 struct ldap_connection *conn;
837 TALLOC_CTX *mem_ctx;
838 bool ret = true;
839 const char *host = torture_setting_string(torture, "host", NULL);
840 const char *userdn = torture_setting_string(torture, "ldap_userdn", NULL);
841 const char *secret = torture_setting_string(torture, "ldap_secret", NULL);
842 const char *url;
843 const char *basedn;
844 const char **partitions;
845
846 mem_ctx = talloc_init("torture_ldap_basic");
847
848 url = talloc_asprintf(mem_ctx, "ldap://%s/", host);
849
850 status = torture_ldap_connection(torture, &conn, url);
851 if (!NT_STATUS_IS_OK(status)) {
852 return false;
853 }
854
855 if (!test_search_rootDSE(conn, &basedn, &partitions)) {
856 ret = false;
857 }
858
859 /* other bind tests here */
860
861 if (!test_multibind(conn, userdn, secret)) {
862 ret = false;
863 }
864
865 if (!test_bind_sasl(torture, conn, cmdline_credentials)) {
866 ret = false;
867 }
868
869 if (!test_compare_sasl(conn, basedn)) {
870 ret = false;
871 }
872
873 /* error codes test here */
874
875 if (!test_error_codes(torture, conn, basedn)) {
876 ret = false;
877 }
878
879 /* referrals test here */
880
881 if (!test_referrals(torture, mem_ctx, url, basedn, partitions)) {
882 ret = false;
883 }
884
885 if (!test_abandom_request(torture, conn, basedn)) {
886 ret = false;
887 }
888
889 /* if there are no more tests we are closing */
890 torture_ldap_close(conn);
891 talloc_free(mem_ctx);
892
893 return ret;
894}
895
Note: See TracBrowser for help on using the repository browser.