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 connection 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_search_rootDSE_empty_substring(struct ldap_connection
*conn
)
162 struct ldap_message
*msg
, *result
;
163 struct ldap_request
*req
;
166 printf("Testing RootDSE Search with objectclass= substring filter\n");
168 msg
= new_ldap_message(conn
);
173 msg
->type
= LDAP_TAG_SearchRequest
;
174 msg
->r
.SearchRequest
.basedn
= "";
175 msg
->r
.SearchRequest
.scope
= LDAP_SEARCH_SCOPE_BASE
;
176 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
177 msg
->r
.SearchRequest
.timelimit
= 0;
178 msg
->r
.SearchRequest
.sizelimit
= 0;
179 msg
->r
.SearchRequest
.attributesonly
= false;
180 msg
->r
.SearchRequest
.tree
= ldb_parse_tree(msg
, "(objectclass=*)");
181 msg
->r
.SearchRequest
.tree
->operation
= LDB_OP_SUBSTRING
;
182 msg
->r
.SearchRequest
.tree
->u
.substring
.attr
= "objectclass";
183 msg
->r
.SearchRequest
.tree
->u
.substring
.start_with_wildcard
= 1;
184 msg
->r
.SearchRequest
.tree
->u
.substring
.end_with_wildcard
= 1;
185 msg
->r
.SearchRequest
.tree
->u
.substring
.chunks
= NULL
;
186 msg
->r
.SearchRequest
.num_attributes
= 0;
187 msg
->r
.SearchRequest
.attributes
= NULL
;
189 req
= ldap_request_send(conn
, msg
);
191 printf("Could not setup ldap search\n");
195 status
= ldap_result_one(req
, &result
, LDAP_TAG_SearchResultEntry
);
196 if (!NT_STATUS_IS_OK(status
)) {
197 printf("looking for search result reply failed - %s\n", nt_errstr(status
));
201 printf("received %d replies\n", req
->num_replies
);
206 static bool test_search_auth_empty_substring(struct ldap_connection
*conn
, const char *basedn
)
209 struct ldap_message
*msg
, *result
;
210 struct ldap_request
*req
;
212 struct ldap_Result
*r
;
214 printf("Testing authenticated base Search with objectclass= substring filter\n");
216 msg
= new_ldap_message(conn
);
221 msg
->type
= LDAP_TAG_SearchRequest
;
222 msg
->r
.SearchRequest
.basedn
= basedn
;
223 msg
->r
.SearchRequest
.scope
= LDAP_SEARCH_SCOPE_BASE
;
224 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
225 msg
->r
.SearchRequest
.timelimit
= 0;
226 msg
->r
.SearchRequest
.sizelimit
= 0;
227 msg
->r
.SearchRequest
.attributesonly
= false;
228 msg
->r
.SearchRequest
.tree
= ldb_parse_tree(msg
, "(objectclass=*)");
229 msg
->r
.SearchRequest
.tree
->operation
= LDB_OP_SUBSTRING
;
230 msg
->r
.SearchRequest
.tree
->u
.substring
.attr
= "objectclass";
231 msg
->r
.SearchRequest
.tree
->u
.substring
.start_with_wildcard
= 1;
232 msg
->r
.SearchRequest
.tree
->u
.substring
.end_with_wildcard
= 1;
233 msg
->r
.SearchRequest
.tree
->u
.substring
.chunks
= NULL
;
234 msg
->r
.SearchRequest
.num_attributes
= 0;
235 msg
->r
.SearchRequest
.attributes
= NULL
;
237 req
= ldap_request_send(conn
, msg
);
239 printf("Could not setup ldap search\n");
243 status
= ldap_result_one(req
, &result
, LDAP_TAG_SearchResultDone
);
244 if (!NT_STATUS_IS_OK(status
)) {
245 printf("looking for search result done failed - %s\n", nt_errstr(status
));
249 printf("received %d replies\n", req
->num_replies
);
251 r
= &result
->r
.SearchResultDone
;
253 if (r
->resultcode
!= LDAP_SUCCESS
) {
254 printf("search result done gave error - %s\n", ldb_strerror(r
->resultcode
));
261 static bool test_compare_sasl(struct ldap_connection
*conn
, const char *basedn
)
263 struct ldap_message
*msg
, *rep
;
264 struct ldap_request
*req
;
268 printf("Testing SASL Compare: %s\n", basedn
);
274 msg
= new_ldap_message(conn
);
279 msg
->type
= LDAP_TAG_CompareRequest
;
280 msg
->r
.CompareRequest
.dn
= basedn
;
281 msg
->r
.CompareRequest
.attribute
= talloc_strdup(msg
, "objectClass");
283 msg
->r
.CompareRequest
.value
= data_blob_talloc(msg
, val
, strlen(val
));
285 req
= ldap_request_send(conn
, msg
);
290 status
= ldap_result_one(req
, &rep
, LDAP_TAG_CompareResponse
);
291 if (!NT_STATUS_IS_OK(status
)) {
292 printf("error in ldap compare request - %s\n", nt_errstr(status
));
296 DEBUG(5,("Code: %d DN: [%s] ERROR:[%s] REFERRAL:[%s]\n",
297 rep
->r
.CompareResponse
.resultcode
,
298 rep
->r
.CompareResponse
.dn
,
299 rep
->r
.CompareResponse
.errormessage
,
300 rep
->r
.CompareResponse
.referral
));
306 * This takes an AD error message and splits it into the WERROR code
307 * (WERR_DS_GENERIC if none found) and the reason (remaining string).
309 static WERROR
ad_error(const char *err_msg
, char **reason
)
311 WERROR err
= W_ERROR(strtol(err_msg
, reason
, 16));
313 if ((reason
!= NULL
) && (*reason
[0] != ':')) {
314 return WERR_DS_GENERIC_ERROR
; /* not an AD std error message */
317 if (reason
!= NULL
) {
318 *reason
+= 2; /* skip ": " */
323 /* This has to be done using the LDAP API since the LDB API does only transmit
324 * the error code and not the error message. */
325 static bool test_error_codes(struct torture_context
*tctx
,
326 struct ldap_connection
*conn
, const char *basedn
)
328 struct ldap_message
*msg
, *rep
;
329 struct ldap_request
*req
;
330 const char *err_code_str
;
335 printf("Testing the most important error code -> error message conversions!\n");
341 msg
= new_ldap_message(conn
);
346 printf(" Try a wrong addition\n");
348 msg
->type
= LDAP_TAG_AddRequest
;
349 msg
->r
.AddRequest
.dn
= basedn
;
350 msg
->r
.AddRequest
.num_attributes
= 0;
351 msg
->r
.AddRequest
.attributes
= NULL
;
353 req
= ldap_request_send(conn
, msg
);
358 status
= ldap_result_one(req
, &rep
, LDAP_TAG_AddResponse
);
359 if (!NT_STATUS_IS_OK(status
)) {
360 printf("error in ldap add request - %s\n", nt_errstr(status
));
364 if ((rep
->r
.AddResponse
.resultcode
== 0)
365 || (rep
->r
.AddResponse
.errormessage
== NULL
)
366 || (strtol(rep
->r
.AddResponse
.errormessage
, &endptr
,16) <= 0)
367 || (*endptr
!= ':')) {
368 printf("Invalid error message!\n");
372 err
= ad_error(rep
->r
.AddResponse
.errormessage
, &endptr
);
373 err_code_str
= win_errstr(err
);
374 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
375 if ((!W_ERROR_EQUAL(err
, WERR_DS_REFERRAL
))
376 || (rep
->r
.AddResponse
.resultcode
!= LDAP_REFERRAL
)) {
379 if ((rep
->r
.AddResponse
.referral
== NULL
)
380 || (strstr(rep
->r
.AddResponse
.referral
, basedn
) == NULL
)) {
384 printf(" Try another wrong addition\n");
386 msg
->type
= LDAP_TAG_AddRequest
;
387 msg
->r
.AddRequest
.dn
= "";
388 msg
->r
.AddRequest
.num_attributes
= 0;
389 msg
->r
.AddRequest
.attributes
= NULL
;
391 req
= ldap_request_send(conn
, msg
);
396 status
= ldap_result_one(req
, &rep
, LDAP_TAG_AddResponse
);
397 if (!NT_STATUS_IS_OK(status
)) {
398 printf("error in ldap add request - %s\n", nt_errstr(status
));
402 if ((rep
->r
.AddResponse
.resultcode
== 0)
403 || (rep
->r
.AddResponse
.errormessage
== NULL
)
404 || (strtol(rep
->r
.AddResponse
.errormessage
, &endptr
,16) <= 0)
405 || (*endptr
!= ':')) {
406 printf("Invalid error message!\n");
410 err
= ad_error(rep
->r
.AddResponse
.errormessage
, &endptr
);
411 err_code_str
= win_errstr(err
);
412 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
413 if ((!W_ERROR_EQUAL(err
, WERR_DS_ROOT_MUST_BE_NC
) &&
414 !W_ERROR_EQUAL(err
, WERR_DS_NAMING_VIOLATION
))
415 || (rep
->r
.AddResponse
.resultcode
!= LDAP_NAMING_VIOLATION
)) {
419 printf(" Try a wrong modification\n");
421 msg
->type
= LDAP_TAG_ModifyRequest
;
422 msg
->r
.ModifyRequest
.dn
= basedn
;
423 msg
->r
.ModifyRequest
.num_mods
= 0;
424 msg
->r
.ModifyRequest
.mods
= NULL
;
426 req
= ldap_request_send(conn
, msg
);
431 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyResponse
);
432 if (!NT_STATUS_IS_OK(status
)) {
433 printf("error in ldap modifification request - %s\n", nt_errstr(status
));
437 if ((rep
->r
.ModifyResponse
.resultcode
== 0)
438 || (rep
->r
.ModifyResponse
.errormessage
== NULL
)
439 || (strtol(rep
->r
.ModifyResponse
.errormessage
, &endptr
,16) <= 0)
440 || (*endptr
!= ':')) {
441 printf("Invalid error message!\n");
445 err
= ad_error(rep
->r
.ModifyResponse
.errormessage
, &endptr
);
446 err_code_str
= win_errstr(err
);
447 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
448 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAM
) &&
449 !W_ERROR_EQUAL(err
, WERR_DS_UNWILLING_TO_PERFORM
))
450 || (rep
->r
.ModifyResponse
.resultcode
!= LDAP_UNWILLING_TO_PERFORM
)) {
454 printf(" Try another wrong modification\n");
456 msg
->type
= LDAP_TAG_ModifyRequest
;
457 msg
->r
.ModifyRequest
.dn
= "";
458 msg
->r
.ModifyRequest
.num_mods
= 0;
459 msg
->r
.ModifyRequest
.mods
= NULL
;
461 req
= ldap_request_send(conn
, msg
);
466 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyResponse
);
467 if (!NT_STATUS_IS_OK(status
)) {
468 printf("error in ldap modifification request - %s\n", nt_errstr(status
));
472 if ((rep
->r
.ModifyResponse
.resultcode
== 0)
473 || (rep
->r
.ModifyResponse
.errormessage
== NULL
)
474 || (strtol(rep
->r
.ModifyResponse
.errormessage
, &endptr
,16) <= 0)
475 || (*endptr
!= ':')) {
476 printf("Invalid error message!\n");
480 err
= ad_error(rep
->r
.ModifyResponse
.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_INVALID_PARAM
) &&
484 !W_ERROR_EQUAL(err
, WERR_DS_UNWILLING_TO_PERFORM
))
485 || (rep
->r
.ModifyResponse
.resultcode
!= LDAP_UNWILLING_TO_PERFORM
)) {
489 printf(" Try a wrong removal\n");
491 msg
->type
= LDAP_TAG_DelRequest
;
492 msg
->r
.DelRequest
.dn
= basedn
;
494 req
= ldap_request_send(conn
, msg
);
499 status
= ldap_result_one(req
, &rep
, LDAP_TAG_DelResponse
);
500 if (!NT_STATUS_IS_OK(status
)) {
501 printf("error in ldap removal request - %s\n", nt_errstr(status
));
505 if ((rep
->r
.DelResponse
.resultcode
== 0)
506 || (rep
->r
.DelResponse
.errormessage
== NULL
)
507 || (strtol(rep
->r
.DelResponse
.errormessage
, &endptr
,16) <= 0)
508 || (*endptr
!= ':')) {
509 printf("Invalid error message!\n");
513 err
= ad_error(rep
->r
.DelResponse
.errormessage
, &endptr
);
514 err_code_str
= win_errstr(err
);
515 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
516 if ((!W_ERROR_EQUAL(err
, WERR_DS_CANT_DELETE
) &&
517 !W_ERROR_EQUAL(err
, WERR_DS_UNWILLING_TO_PERFORM
))
518 || (rep
->r
.DelResponse
.resultcode
!= LDAP_UNWILLING_TO_PERFORM
)) {
522 printf(" Try another wrong removal\n");
524 msg
->type
= LDAP_TAG_DelRequest
;
525 msg
->r
.DelRequest
.dn
= "";
527 req
= ldap_request_send(conn
, msg
);
532 status
= ldap_result_one(req
, &rep
, LDAP_TAG_DelResponse
);
533 if (!NT_STATUS_IS_OK(status
)) {
534 printf("error in ldap removal request - %s\n", nt_errstr(status
));
538 if ((rep
->r
.DelResponse
.resultcode
== 0)
539 || (rep
->r
.DelResponse
.errormessage
== NULL
)
540 || (strtol(rep
->r
.DelResponse
.errormessage
, &endptr
,16) <= 0)
541 || (*endptr
!= ':')) {
542 printf("Invalid error message!\n");
546 err
= ad_error(rep
->r
.DelResponse
.errormessage
, &endptr
);
547 err_code_str
= win_errstr(err
);
548 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
549 if ((!W_ERROR_EQUAL(err
, WERR_DS_OBJ_NOT_FOUND
) &&
550 !W_ERROR_EQUAL(err
, WERR_DS_NO_SUCH_OBJECT
))
551 || (rep
->r
.DelResponse
.resultcode
!= LDAP_NO_SUCH_OBJECT
)) {
555 printf(" Try a wrong rename\n");
557 msg
->type
= LDAP_TAG_ModifyDNRequest
;
558 msg
->r
.ModifyDNRequest
.dn
= basedn
;
559 msg
->r
.ModifyDNRequest
.newrdn
= "dc=test";
560 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
561 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
563 req
= ldap_request_send(conn
, msg
);
568 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
569 if (!NT_STATUS_IS_OK(status
)) {
570 printf("error in ldap rename request - %s\n", nt_errstr(status
));
574 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
575 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
576 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
577 || (*endptr
!= ':')) {
578 printf("Invalid error message!\n");
582 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
583 err_code_str
= win_errstr(err
);
584 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
585 if ((!W_ERROR_EQUAL(err
, WERR_DS_NO_PARENT_OBJECT
) &&
586 !W_ERROR_EQUAL(err
, WERR_DS_GENERIC_ERROR
))
587 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_OTHER
)) {
591 printf(" Try another wrong rename\n");
593 msg
->type
= LDAP_TAG_ModifyDNRequest
;
594 msg
->r
.ModifyDNRequest
.dn
= basedn
;
595 msg
->r
.ModifyDNRequest
.newrdn
= basedn
;
596 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
597 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
599 req
= ldap_request_send(conn
, msg
);
604 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
605 if (!NT_STATUS_IS_OK(status
)) {
606 printf("error in ldap rename request - %s\n", nt_errstr(status
));
610 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
611 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
612 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
613 || (*endptr
!= ':')) {
614 printf("Invalid error message!\n");
618 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
619 err_code_str
= win_errstr(err
);
620 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
621 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAM
) &&
622 !W_ERROR_EQUAL(err
, WERR_DS_NAMING_VIOLATION
))
623 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_NAMING_VIOLATION
)) {
627 printf(" Try another wrong rename\n");
629 msg
->type
= LDAP_TAG_ModifyDNRequest
;
630 msg
->r
.ModifyDNRequest
.dn
= basedn
;
631 msg
->r
.ModifyDNRequest
.newrdn
= "";
632 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
633 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
635 req
= ldap_request_send(conn
, msg
);
640 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
641 if (!NT_STATUS_IS_OK(status
)) {
642 printf("error in ldap rename request - %s\n", nt_errstr(status
));
646 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
647 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
648 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
649 || (*endptr
!= ':')) {
650 printf("Invalid error message!\n");
654 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
655 err_code_str
= win_errstr(err
);
656 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
657 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAM
) &&
658 !W_ERROR_EQUAL(err
, WERR_DS_PROTOCOL_ERROR
))
659 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_PROTOCOL_ERROR
)) {
663 printf(" Try another wrong rename\n");
665 msg
->type
= LDAP_TAG_ModifyDNRequest
;
666 msg
->r
.ModifyDNRequest
.dn
= "";
667 msg
->r
.ModifyDNRequest
.newrdn
= "cn=temp";
668 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
669 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
671 req
= ldap_request_send(conn
, msg
);
676 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
677 if (!NT_STATUS_IS_OK(status
)) {
678 printf("error in ldap rename request - %s\n", nt_errstr(status
));
682 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
683 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
684 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
685 || (*endptr
!= ':')) {
686 printf("Invalid error message!\n");
690 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
691 err_code_str
= win_errstr(err
);
692 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
693 if ((!W_ERROR_EQUAL(err
, WERR_DS_OBJ_NOT_FOUND
) &&
694 !W_ERROR_EQUAL(err
, WERR_DS_NO_SUCH_OBJECT
))
695 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_NO_SUCH_OBJECT
)) {
702 static bool test_referrals(struct torture_context
*tctx
, TALLOC_CTX
*mem_ctx
,
703 const char *url
, const char *basedn
, const char **partitions
)
705 struct ldb_context
*ldb
;
706 struct ldb_result
*res
;
707 const char * const *attrs
= { NULL
};
708 struct ldb_dn
*dn1
, *dn2
;
714 printf("Testing referrals\n");
716 if (partitions
[0] == NULL
) {
717 printf("Partitions list empty!\n");
721 if (strcmp(partitions
[0], basedn
) != 0) {
722 printf("The first (root) partition DN should be the base DN!\n");
726 ldb
= ldb_wrap_connect(mem_ctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
727 NULL
, cmdline_credentials
, 0);
729 /* "partitions[i]" are the partitions for which we search the parents */
730 for (i
= 1; partitions
[i
] != NULL
; i
++) {
731 dn1
= ldb_dn_new(mem_ctx
, ldb
, partitions
[i
]);
733 printf("Out of memory\n");
738 /* search using base scope */
739 /* "partitions[j]" are the parent candidates */
740 for (j
= str_list_length(partitions
) - 1; j
>= 0; --j
) {
741 dn2
= ldb_dn_new(mem_ctx
, ldb
, partitions
[j
]);
743 printf("Out of memory\n");
748 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
749 LDB_SCOPE_BASE
, attrs
,
751 if (ret
!= LDB_SUCCESS
) {
752 printf("%s", ldb_errstring(ldb
));
757 if (res
->refs
!= NULL
) {
758 printf("There shouldn't be generated any referrals in the base scope!\n");
767 /* search using onelevel scope */
769 /* "partitions[j]" are the parent candidates */
770 for (j
= str_list_length(partitions
) - 1; j
>= 0; --j
) {
771 dn2
= ldb_dn_new(mem_ctx
, ldb
, partitions
[j
]);
773 printf("Out of memory\n");
778 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
779 LDB_SCOPE_ONELEVEL
, attrs
,
781 if (ret
!= LDB_SUCCESS
) {
782 printf("%s", ldb_errstring(ldb
));
787 tempstr
= talloc_asprintf(mem_ctx
, "/%s??base",
789 if (tempstr
== NULL
) {
790 printf("Out of memory\n");
795 /* Try to find or find not a matching referral */
797 for (k
= 0; (!l_found
) && (res
->refs
!= NULL
)
798 && (res
->refs
[k
] != NULL
); k
++) {
799 if (strstr(res
->refs
[k
], tempstr
) != NULL
) {
804 talloc_free(tempstr
);
806 if ((!found
) && (ldb_dn_compare_base(dn2
, dn1
) == 0)
807 && (ldb_dn_compare(dn2
, dn1
) != 0)) {
808 /* This is a referral candidate */
810 printf("A required referral hasn't been found on onelevel scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
816 /* This isn't a referral candidate */
818 printf("A unrequired referral has been found on onelevel scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
828 /* search using subtree scope */
830 /* "partitions[j]" are the parent candidates */
831 for (j
= str_list_length(partitions
) - 1; j
>= 0; --j
) {
832 dn2
= ldb_dn_new(mem_ctx
, ldb
, partitions
[j
]);
834 printf("Out of memory\n");
839 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
840 LDB_SCOPE_SUBTREE
, attrs
,
842 if (ret
!= LDB_SUCCESS
) {
843 printf("%s", ldb_errstring(ldb
));
848 tempstr
= talloc_asprintf(mem_ctx
, "/%s",
850 if (tempstr
== NULL
) {
851 printf("Out of memory\n");
856 /* Try to find or find not a matching referral */
858 for (k
= 0; (!l_found
) && (res
->refs
!= NULL
)
859 && (res
->refs
[k
] != NULL
); k
++) {
860 if (strstr(res
->refs
[k
], tempstr
) != NULL
) {
865 talloc_free(tempstr
);
867 if ((!found
) && (ldb_dn_compare_base(dn2
, dn1
) == 0)
868 && (ldb_dn_compare(dn2
, dn1
) != 0)) {
869 /* This is a referral candidate */
871 printf("A required referral hasn't been found on subtree scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
877 /* This isn't a referral candidate */
879 printf("A unrequired referral has been found on subtree scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
897 static bool test_abandon_request(struct torture_context
*tctx
,
898 struct ldap_connection
*conn
, const char *basedn
)
900 struct ldap_message
*msg
;
901 struct ldap_request
*req
;
904 printf("Testing the AbandonRequest with an old message id!\n");
910 msg
= new_ldap_message(conn
);
915 printf(" Try a AbandonRequest for an old message id\n");
917 msg
->type
= LDAP_TAG_AbandonRequest
;
918 msg
->r
.AbandonRequest
.messageid
= 1;
920 req
= ldap_request_send(conn
, msg
);
925 status
= ldap_request_wait(req
);
926 if (!NT_STATUS_IS_OK(status
)) {
927 printf("error in ldap abandon request - %s\n", nt_errstr(status
));
935 bool torture_ldap_basic(struct torture_context
*torture
)
938 struct ldap_connection
*conn
;
941 const char *host
= torture_setting_string(torture
, "host", NULL
);
942 const char *userdn
= torture_setting_string(torture
, "ldap_userdn", NULL
);
943 const char *secret
= torture_setting_string(torture
, "ldap_secret", NULL
);
946 const char **partitions
;
948 mem_ctx
= talloc_init("torture_ldap_basic");
950 url
= talloc_asprintf(mem_ctx
, "ldap://%s/", host
);
952 status
= torture_ldap_connection(torture
, &conn
, url
);
953 if (!NT_STATUS_IS_OK(status
)) {
957 if (!test_search_rootDSE(conn
, &basedn
, &partitions
)) {
961 if (!test_search_rootDSE_empty_substring(conn
)) {
965 /* other bind tests here */
967 if (!test_multibind(conn
, userdn
, secret
)) {
971 if (!test_bind_sasl(torture
, conn
, cmdline_credentials
)) {
975 if (!test_search_auth_empty_substring(conn
, basedn
)) {
979 if (!test_compare_sasl(conn
, basedn
)) {
983 /* error codes test here */
985 if (!test_error_codes(torture
, conn
, basedn
)) {
989 /* referrals test here */
991 if (!test_referrals(torture
, mem_ctx
, url
, basedn
, partitions
)) {
995 if (!test_abandon_request(torture
, conn
, basedn
)) {
999 /* if there are no more tests we are closing */
1000 torture_ldap_close(conn
);
1001 talloc_free(mem_ctx
);