2 Unix SMB/CIFS mplementation.
3 LDAP protocol helper functions for SAMBA
5 Copyright (C) Stefan Metzmacher 2004
6 Copyright (C) Simo Sorce 2004
7 Copyright (C) Matthias Dieter Wallnöfer 2009-2010
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.
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.
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/>.
26 #include "libcli/ldap/ldap_client.h"
27 #include "lib/cmdline/popt_common.h"
29 #include "torture/torture.h"
30 #include "torture/ldap/proto.h"
33 static bool test_bind_simple(struct ldap_connection
*conn
, const char *userdn
, const char *password
)
38 status
= torture_ldap_bind(conn
, userdn
, password
);
39 if (!NT_STATUS_IS_OK(status
)) {
46 static bool test_bind_sasl(struct torture_context
*tctx
,
47 struct ldap_connection
*conn
, struct cli_credentials
*creds
)
52 printf("Testing sasl bind as user\n");
54 status
= torture_ldap_bind_sasl(conn
, creds
, tctx
->lp_ctx
);
55 if (!NT_STATUS_IS_OK(status
)) {
62 static bool test_multibind(struct ldap_connection
*conn
, const char *userdn
, const char *password
)
66 printf("Testing multiple binds on a single connnection as anonymous and user\n");
68 ret
= test_bind_simple(conn
, NULL
, NULL
);
70 printf("1st bind as anonymous failed\n");
74 ret
= test_bind_simple(conn
, userdn
, password
);
76 printf("2nd bind as authenticated user failed\n");
82 static bool test_search_rootDSE(struct ldap_connection
*conn
, const char **basedn
,
83 const char ***partitions
)
86 struct ldap_message
*msg
, *result
;
87 struct ldap_request
*req
;
89 struct ldap_SearchResEntry
*r
;
92 printf("Testing RootDSE Search\n");
96 if (partitions
!= NULL
) {
97 *partitions
= const_str_list(str_list_make_empty(conn
));
100 msg
= new_ldap_message(conn
);
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
;
116 req
= ldap_request_send(conn
, msg
);
118 printf("Could not setup ldap search\n");
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
));
128 printf("received %d replies\n", req
->num_replies
);
130 r
= &result
->r
.SearchResultEntry
;
132 DEBUG(1,("\tdn: %s\n", r
->dn
));
133 for (i
=0; i
<r
->num_attributes
; i
++) {
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
));
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
);
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
);
159 static bool test_compare_sasl(struct ldap_connection
*conn
, const char *basedn
)
161 struct ldap_message
*msg
, *rep
;
162 struct ldap_request
*req
;
166 printf("Testing SASL Compare: %s\n", basedn
);
172 msg
= new_ldap_message(conn
);
177 msg
->type
= LDAP_TAG_CompareRequest
;
178 msg
->r
.CompareRequest
.dn
= basedn
;
179 msg
->r
.CompareRequest
.attribute
= talloc_strdup(msg
, "objectClass");
181 msg
->r
.CompareRequest
.value
= data_blob_talloc(msg
, val
, strlen(val
));
183 req
= ldap_request_send(conn
, msg
);
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
));
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
));
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).
207 static WERROR
ad_error(const char *err_msg
, char **reason
)
209 WERROR err
= W_ERROR(strtol(err_msg
, reason
, 16));
211 if ((reason
!= NULL
) && (*reason
[0] != ':')) {
212 return WERR_DS_GENERIC_ERROR
; /* not an AD std error message */
215 if (reason
!= NULL
) {
216 *reason
+= 2; /* skip ": " */
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. */
223 static bool test_error_codes(struct torture_context
*tctx
,
224 struct ldap_connection
*conn
, const char *basedn
)
226 struct ldap_message
*msg
, *rep
;
227 struct ldap_request
*req
;
228 const char *err_code_str
;
233 printf("Testing the most important error code -> error message conversions!\n");
239 msg
= new_ldap_message(conn
);
244 printf(" Try a wrong addition\n");
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
;
251 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
277 if ((rep
->r
.AddResponse
.referral
== NULL
)
278 || (strstr(rep
->r
.AddResponse
.referral
, basedn
) == NULL
)) {
282 printf(" Try another wrong addition\n");
284 msg
->type
= LDAP_TAG_AddRequest
;
285 msg
->r
.AddRequest
.dn
= "";
286 msg
->r
.AddRequest
.num_attributes
= 0;
287 msg
->r
.AddRequest
.attributes
= NULL
;
289 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
317 printf(" Try a wrong modification\n");
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
;
324 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
352 printf(" Try another wrong modification\n");
354 msg
->type
= LDAP_TAG_ModifyRequest
;
355 msg
->r
.ModifyRequest
.dn
= "";
356 msg
->r
.ModifyRequest
.num_mods
= 0;
357 msg
->r
.ModifyRequest
.mods
= NULL
;
359 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
387 printf(" Try a wrong removal\n");
389 msg
->type
= LDAP_TAG_DelRequest
;
390 msg
->r
.DelRequest
.dn
= basedn
;
392 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
420 printf(" Try another wrong removal\n");
422 msg
->type
= LDAP_TAG_DelRequest
;
423 msg
->r
.DelRequest
.dn
= "";
425 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
453 printf(" Try a wrong rename\n");
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
;
461 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
489 printf(" Try another wrong rename\n");
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
;
497 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
525 printf(" Try another wrong rename\n");
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
;
533 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
561 printf(" Try another wrong rename\n");
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
;
569 req
= ldap_request_send(conn
, msg
);
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
));
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");
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
)) {
600 static bool test_referrals(struct torture_context
*tctx
, TALLOC_CTX
*mem_ctx
,
601 const char *url
, const char *basedn
, const char **partitions
)
603 struct ldb_context
*ldb
;
604 struct ldb_result
*res
;
605 const char * const *attrs
= { NULL
};
606 struct ldb_dn
*dn1
, *dn2
;
612 printf("Testing referrals\n");
614 if (partitions
[0] == NULL
) {
615 printf("Partitions list empty!\n");
619 if (strcmp(partitions
[0], basedn
) != 0) {
620 printf("The first (root) partition DN should be the base DN!\n");
624 ldb
= ldb_wrap_connect(mem_ctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
625 NULL
, cmdline_credentials
, 0);
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
]);
631 printf("Out of memory\n");
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
]);
641 printf("Out of memory\n");
646 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
647 LDB_SCOPE_BASE
, attrs
,
649 if (ret
!= LDB_SUCCESS
) {
650 printf("%s", ldb_errstring(ldb
));
655 if (res
->refs
!= NULL
) {
656 printf("There shouldn't be generated any referrals in the base scope!\n");
665 /* search using onelevel scope */
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
]);
671 printf("Out of memory\n");
676 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
677 LDB_SCOPE_ONELEVEL
, attrs
,
679 if (ret
!= LDB_SUCCESS
) {
680 printf("%s", ldb_errstring(ldb
));
685 tempstr
= talloc_asprintf(mem_ctx
, "/%s??base",
687 if (tempstr
== NULL
) {
688 printf("Out of memory\n");
693 /* Try to find or find not a matching referral */
695 for (k
= 0; (!l_found
) && (res
->refs
!= NULL
)
696 && (res
->refs
[k
] != NULL
); k
++) {
697 if (strstr(res
->refs
[k
], tempstr
) != NULL
) {
702 talloc_free(tempstr
);
704 if ((!found
) && (ldb_dn_compare_base(dn2
, dn1
) == 0)
705 && (ldb_dn_compare(dn2
, dn1
) != 0)) {
706 /* This is a referral candidate */
708 printf("A required referral hasn't been found on onelevel scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
714 /* This isn't a referral candidate */
716 printf("A unrequired referral has been found on onelevel scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
726 /* search using subtree scope */
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
]);
732 printf("Out of memory\n");
737 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
738 LDB_SCOPE_SUBTREE
, attrs
,
740 if (ret
!= LDB_SUCCESS
) {
741 printf("%s", ldb_errstring(ldb
));
746 tempstr
= talloc_asprintf(mem_ctx
, "/%s",
748 if (tempstr
== NULL
) {
749 printf("Out of memory\n");
754 /* Try to find or find not a matching referral */
756 for (k
= 0; (!l_found
) && (res
->refs
!= NULL
)
757 && (res
->refs
[k
] != NULL
); k
++) {
758 if (strstr(res
->refs
[k
], tempstr
) != NULL
) {
763 talloc_free(tempstr
);
765 if ((!found
) && (ldb_dn_compare_base(dn2
, dn1
) == 0)
766 && (ldb_dn_compare(dn2
, dn1
) != 0)) {
767 /* This is a referral candidate */
769 printf("A required referral hasn't been found on subtree scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
775 /* This isn't a referral candidate */
777 printf("A unrequired referral has been found on subtree scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
795 static bool test_abandom_request(struct torture_context
*tctx
,
796 struct ldap_connection
*conn
, const char *basedn
)
798 struct ldap_message
*msg
;
799 struct ldap_request
*req
;
802 printf("Testing the AbandonRequest with an old message id!\n");
808 msg
= new_ldap_message(conn
);
813 printf(" Try a AbandonRequest for an old message id\n");
815 msg
->type
= LDAP_TAG_AbandonRequest
;
816 msg
->r
.AbandonRequest
.messageid
= 1;
818 req
= ldap_request_send(conn
, msg
);
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
));
833 bool torture_ldap_basic(struct torture_context
*torture
)
836 struct ldap_connection
*conn
;
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
);
844 const char **partitions
;
846 mem_ctx
= talloc_init("torture_ldap_basic");
848 url
= talloc_asprintf(mem_ctx
, "ldap://%s/", host
);
850 status
= torture_ldap_connection(torture
, &conn
, url
);
851 if (!NT_STATUS_IS_OK(status
)) {
855 if (!test_search_rootDSE(conn
, &basedn
, &partitions
)) {
859 /* other bind tests here */
861 if (!test_multibind(conn
, userdn
, secret
)) {
865 if (!test_bind_sasl(torture
, conn
, cmdline_credentials
)) {
869 if (!test_compare_sasl(conn
, basedn
)) {
873 /* error codes test here */
875 if (!test_error_codes(torture
, conn
, basedn
)) {
879 /* referrals test here */
881 if (!test_referrals(torture
, mem_ctx
, url
, basedn
, partitions
)) {
885 if (!test_abandom_request(torture
, conn
, basedn
)) {
889 /* if there are no more tests we are closing */
890 torture_ldap_close(conn
);
891 talloc_free(mem_ctx
);