2 Unix SMB/CIFS Implementation.
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_sasl(struct torture_context
*tctx
,
34 struct ldap_connection
*conn
, struct cli_credentials
*creds
)
39 printf("Testing sasl bind as user\n");
41 status
= torture_ldap_bind_sasl(conn
, creds
, tctx
->lp_ctx
);
42 if (!NT_STATUS_IS_OK(status
)) {
49 static bool test_multibind(struct ldap_connection
*conn
, const char *userdn
, const char *password
)
51 NTSTATUS status
, expected
;
54 printf("Testing multiple binds on a single connection as anonymous and user\n");
56 status
= torture_ldap_bind(conn
, NULL
, NULL
);
57 if (!NT_STATUS_IS_OK(status
)) {
58 printf("1st bind as anonymous failed with %s\n",
63 expected
= NT_STATUS_LDAP(LDAP_STRONG_AUTH_REQUIRED
);
64 status
= torture_ldap_bind(conn
, userdn
, password
);
66 ok
= NT_STATUS_EQUAL(status
, expected
);
68 printf("2nd bind as authenticated user should have "
69 "failed with: %s, got %s\n",
78 static bool test_search_rootDSE(struct ldap_connection
*conn
, const char **basedn
,
79 const char ***partitions
)
82 struct ldap_message
*msg
, *result
;
83 struct ldap_request
*req
;
85 struct ldap_SearchResEntry
*r
;
88 printf("Testing RootDSE Search\n");
92 if (partitions
!= NULL
) {
93 *partitions
= const_str_list(str_list_make_empty(conn
));
96 msg
= new_ldap_message(conn
);
101 msg
->type
= LDAP_TAG_SearchRequest
;
102 msg
->r
.SearchRequest
.basedn
= "";
103 msg
->r
.SearchRequest
.scope
= LDAP_SEARCH_SCOPE_BASE
;
104 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
105 msg
->r
.SearchRequest
.timelimit
= 0;
106 msg
->r
.SearchRequest
.sizelimit
= 0;
107 msg
->r
.SearchRequest
.attributesonly
= false;
108 msg
->r
.SearchRequest
.tree
= ldb_parse_tree(msg
, "(objectclass=*)");
109 msg
->r
.SearchRequest
.num_attributes
= 0;
110 msg
->r
.SearchRequest
.attributes
= NULL
;
112 req
= ldap_request_send(conn
, msg
);
114 printf("Could not setup ldap search\n");
118 status
= ldap_result_one(req
, &result
, LDAP_TAG_SearchResultEntry
);
119 if (!NT_STATUS_IS_OK(status
)) {
120 printf("search failed - %s\n", nt_errstr(status
));
124 printf("received %d replies\n", req
->num_replies
);
126 r
= &result
->r
.SearchResultEntry
;
128 DEBUG(1,("\tdn: %s\n", r
->dn
));
129 for (i
=0; i
<r
->num_attributes
; i
++) {
131 for (j
=0; j
<r
->attributes
[i
].num_values
; j
++) {
132 DEBUG(1,("\t%s: %d %.*s\n", r
->attributes
[i
].name
,
133 (int)r
->attributes
[i
].values
[j
].length
,
134 (int)r
->attributes
[i
].values
[j
].length
,
135 (char *)r
->attributes
[i
].values
[j
].data
));
137 strcasecmp("defaultNamingContext",r
->attributes
[i
].name
)==0) {
138 *basedn
= talloc_asprintf(conn
, "%.*s",
139 (int)r
->attributes
[i
].values
[j
].length
,
140 (char *)r
->attributes
[i
].values
[j
].data
);
142 if ((partitions
!= NULL
) &&
143 (strcasecmp("namingContexts", r
->attributes
[i
].name
) == 0)) {
144 char *entry
= talloc_asprintf(conn
, "%.*s",
145 (int)r
->attributes
[i
].values
[j
].length
,
146 (char *)r
->attributes
[i
].values
[j
].data
);
147 *partitions
= str_list_add(*partitions
, entry
);
155 static bool test_search_rootDSE_empty_substring(struct ldap_connection
*conn
)
158 struct ldap_message
*msg
, *result
;
159 struct ldap_request
*req
;
162 printf("Testing RootDSE Search with objectclass= substring filter\n");
164 msg
= new_ldap_message(conn
);
169 msg
->type
= LDAP_TAG_SearchRequest
;
170 msg
->r
.SearchRequest
.basedn
= "";
171 msg
->r
.SearchRequest
.scope
= LDAP_SEARCH_SCOPE_BASE
;
172 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
173 msg
->r
.SearchRequest
.timelimit
= 0;
174 msg
->r
.SearchRequest
.sizelimit
= 0;
175 msg
->r
.SearchRequest
.attributesonly
= false;
176 msg
->r
.SearchRequest
.tree
= ldb_parse_tree(msg
, "(objectclass=*)");
177 msg
->r
.SearchRequest
.tree
->operation
= LDB_OP_SUBSTRING
;
178 msg
->r
.SearchRequest
.tree
->u
.substring
.attr
= "objectclass";
179 msg
->r
.SearchRequest
.tree
->u
.substring
.start_with_wildcard
= 1;
180 msg
->r
.SearchRequest
.tree
->u
.substring
.end_with_wildcard
= 1;
181 msg
->r
.SearchRequest
.tree
->u
.substring
.chunks
= NULL
;
182 msg
->r
.SearchRequest
.num_attributes
= 0;
183 msg
->r
.SearchRequest
.attributes
= NULL
;
185 req
= ldap_request_send(conn
, msg
);
187 printf("Could not setup ldap search\n");
191 status
= ldap_result_one(req
, &result
, LDAP_TAG_SearchResultEntry
);
192 if (!NT_STATUS_IS_OK(status
)) {
193 printf("looking for search result reply failed - %s\n", nt_errstr(status
));
197 printf("received %d replies\n", req
->num_replies
);
202 static bool test_search_auth_empty_substring(struct ldap_connection
*conn
, const char *basedn
)
205 struct ldap_message
*msg
, *result
;
206 struct ldap_request
*req
;
208 struct ldap_Result
*r
;
210 printf("Testing authenticated base Search with objectclass= substring filter\n");
212 msg
= new_ldap_message(conn
);
217 msg
->type
= LDAP_TAG_SearchRequest
;
218 msg
->r
.SearchRequest
.basedn
= basedn
;
219 msg
->r
.SearchRequest
.scope
= LDAP_SEARCH_SCOPE_BASE
;
220 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
221 msg
->r
.SearchRequest
.timelimit
= 0;
222 msg
->r
.SearchRequest
.sizelimit
= 0;
223 msg
->r
.SearchRequest
.attributesonly
= false;
224 msg
->r
.SearchRequest
.tree
= ldb_parse_tree(msg
, "(objectclass=*)");
225 msg
->r
.SearchRequest
.tree
->operation
= LDB_OP_SUBSTRING
;
226 msg
->r
.SearchRequest
.tree
->u
.substring
.attr
= "objectclass";
227 msg
->r
.SearchRequest
.tree
->u
.substring
.start_with_wildcard
= 1;
228 msg
->r
.SearchRequest
.tree
->u
.substring
.end_with_wildcard
= 1;
229 msg
->r
.SearchRequest
.tree
->u
.substring
.chunks
= NULL
;
230 msg
->r
.SearchRequest
.num_attributes
= 0;
231 msg
->r
.SearchRequest
.attributes
= NULL
;
233 req
= ldap_request_send(conn
, msg
);
235 printf("Could not setup ldap search\n");
239 status
= ldap_result_one(req
, &result
, LDAP_TAG_SearchResultDone
);
240 if (!NT_STATUS_IS_OK(status
)) {
241 printf("looking for search result done failed - %s\n", nt_errstr(status
));
245 printf("received %d replies\n", req
->num_replies
);
247 r
= &result
->r
.SearchResultDone
;
249 if (r
->resultcode
!= LDAP_SUCCESS
) {
250 printf("search result done gave error - %s\n", ldb_strerror(r
->resultcode
));
257 static bool test_compare_sasl(struct ldap_connection
*conn
, const char *basedn
)
259 struct ldap_message
*msg
, *rep
;
260 struct ldap_request
*req
;
264 printf("Testing SASL Compare: %s\n", basedn
);
270 msg
= new_ldap_message(conn
);
275 msg
->type
= LDAP_TAG_CompareRequest
;
276 msg
->r
.CompareRequest
.dn
= basedn
;
277 msg
->r
.CompareRequest
.attribute
= talloc_strdup(msg
, "objectClass");
279 msg
->r
.CompareRequest
.value
= data_blob_talloc(msg
, val
, strlen(val
));
281 req
= ldap_request_send(conn
, msg
);
286 status
= ldap_result_one(req
, &rep
, LDAP_TAG_CompareResponse
);
287 if (!NT_STATUS_IS_OK(status
)) {
288 printf("error in ldap compare request - %s\n", nt_errstr(status
));
292 DEBUG(5,("Code: %d DN: [%s] ERROR:[%s] REFERRAL:[%s]\n",
293 rep
->r
.CompareResponse
.resultcode
,
294 rep
->r
.CompareResponse
.dn
,
295 rep
->r
.CompareResponse
.errormessage
,
296 rep
->r
.CompareResponse
.referral
));
302 * This takes an AD error message and splits it into the WERROR code
303 * (WERR_DS_GENERIC if none found) and the reason (remaining string).
305 static WERROR
ad_error(const char *err_msg
, char **reason
)
307 WERROR err
= W_ERROR(strtol(err_msg
, reason
, 16));
309 if ((reason
!= NULL
) && (*reason
[0] != ':')) {
310 return WERR_DS_GENERIC_ERROR
; /* not an AD std error message */
313 if (reason
!= NULL
) {
314 *reason
+= 2; /* skip ": " */
319 /* This has to be done using the LDAP API since the LDB API does only transmit
320 * the error code and not the error message. */
321 static bool test_error_codes(struct torture_context
*tctx
,
322 struct ldap_connection
*conn
, const char *basedn
)
324 struct ldap_message
*msg
, *rep
;
325 struct ldap_request
*req
;
326 const char *err_code_str
;
331 printf("Testing the most important error code -> error message conversions!\n");
337 msg
= new_ldap_message(conn
);
342 printf(" Try a wrong addition\n");
344 msg
->type
= LDAP_TAG_AddRequest
;
345 msg
->r
.AddRequest
.dn
= basedn
;
346 msg
->r
.AddRequest
.num_attributes
= 0;
347 msg
->r
.AddRequest
.attributes
= NULL
;
349 req
= ldap_request_send(conn
, msg
);
354 status
= ldap_result_one(req
, &rep
, LDAP_TAG_AddResponse
);
355 if (!NT_STATUS_IS_OK(status
)) {
356 printf("error in ldap add request - %s\n", nt_errstr(status
));
360 if ((rep
->r
.AddResponse
.resultcode
== 0)
361 || (rep
->r
.AddResponse
.errormessage
== NULL
)
362 || (strtol(rep
->r
.AddResponse
.errormessage
, &endptr
,16) <= 0)
363 || (*endptr
!= ':')) {
364 printf("Invalid error message!\n");
368 err
= ad_error(rep
->r
.AddResponse
.errormessage
, &endptr
);
369 err_code_str
= win_errstr(err
);
370 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
371 if ((!W_ERROR_EQUAL(err
, WERR_DS_REFERRAL
))
372 || (rep
->r
.AddResponse
.resultcode
!= LDAP_REFERRAL
)) {
375 if ((rep
->r
.AddResponse
.referral
== NULL
)
376 || (strstr(rep
->r
.AddResponse
.referral
, basedn
) == NULL
)) {
380 printf(" Try another wrong addition\n");
382 msg
->type
= LDAP_TAG_AddRequest
;
383 msg
->r
.AddRequest
.dn
= "";
384 msg
->r
.AddRequest
.num_attributes
= 0;
385 msg
->r
.AddRequest
.attributes
= NULL
;
387 req
= ldap_request_send(conn
, msg
);
392 status
= ldap_result_one(req
, &rep
, LDAP_TAG_AddResponse
);
393 if (!NT_STATUS_IS_OK(status
)) {
394 printf("error in ldap add request - %s\n", nt_errstr(status
));
398 if ((rep
->r
.AddResponse
.resultcode
== 0)
399 || (rep
->r
.AddResponse
.errormessage
== NULL
)
400 || (strtol(rep
->r
.AddResponse
.errormessage
, &endptr
,16) <= 0)
401 || (*endptr
!= ':')) {
402 printf("Invalid error message!\n");
406 err
= ad_error(rep
->r
.AddResponse
.errormessage
, &endptr
);
407 err_code_str
= win_errstr(err
);
408 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
409 if ((!W_ERROR_EQUAL(err
, WERR_DS_ROOT_MUST_BE_NC
) &&
410 !W_ERROR_EQUAL(err
, WERR_DS_NAMING_VIOLATION
))
411 || (rep
->r
.AddResponse
.resultcode
!= LDAP_NAMING_VIOLATION
)) {
415 printf(" Try a wrong modification\n");
417 msg
->type
= LDAP_TAG_ModifyRequest
;
418 msg
->r
.ModifyRequest
.dn
= basedn
;
419 msg
->r
.ModifyRequest
.num_mods
= 0;
420 msg
->r
.ModifyRequest
.mods
= NULL
;
422 req
= ldap_request_send(conn
, msg
);
427 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyResponse
);
428 if (!NT_STATUS_IS_OK(status
)) {
429 printf("error in ldap modifification request - %s\n", nt_errstr(status
));
433 if ((rep
->r
.ModifyResponse
.resultcode
== 0)
434 || (rep
->r
.ModifyResponse
.errormessage
== NULL
)
435 || (strtol(rep
->r
.ModifyResponse
.errormessage
, &endptr
,16) <= 0)
436 || (*endptr
!= ':')) {
437 printf("Invalid error message!\n");
441 err
= ad_error(rep
->r
.ModifyResponse
.errormessage
, &endptr
);
442 err_code_str
= win_errstr(err
);
443 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
444 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAMETER
) &&
445 !W_ERROR_EQUAL(err
, WERR_DS_UNWILLING_TO_PERFORM
))
446 || (rep
->r
.ModifyResponse
.resultcode
!= LDAP_UNWILLING_TO_PERFORM
)) {
450 printf(" Try another wrong modification\n");
452 msg
->type
= LDAP_TAG_ModifyRequest
;
453 msg
->r
.ModifyRequest
.dn
= "";
454 msg
->r
.ModifyRequest
.num_mods
= 0;
455 msg
->r
.ModifyRequest
.mods
= NULL
;
457 req
= ldap_request_send(conn
, msg
);
462 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyResponse
);
463 if (!NT_STATUS_IS_OK(status
)) {
464 printf("error in ldap modifification request - %s\n", nt_errstr(status
));
468 if ((rep
->r
.ModifyResponse
.resultcode
== 0)
469 || (rep
->r
.ModifyResponse
.errormessage
== NULL
)
470 || (strtol(rep
->r
.ModifyResponse
.errormessage
, &endptr
,16) <= 0)
471 || (*endptr
!= ':')) {
472 printf("Invalid error message!\n");
476 err
= ad_error(rep
->r
.ModifyResponse
.errormessage
, &endptr
);
477 err_code_str
= win_errstr(err
);
478 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
479 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAMETER
) &&
480 !W_ERROR_EQUAL(err
, WERR_DS_UNWILLING_TO_PERFORM
))
481 || (rep
->r
.ModifyResponse
.resultcode
!= LDAP_UNWILLING_TO_PERFORM
)) {
485 printf(" Try a wrong removal\n");
487 msg
->type
= LDAP_TAG_DelRequest
;
488 msg
->r
.DelRequest
.dn
= basedn
;
490 req
= ldap_request_send(conn
, msg
);
495 status
= ldap_result_one(req
, &rep
, LDAP_TAG_DelResponse
);
496 if (!NT_STATUS_IS_OK(status
)) {
497 printf("error in ldap removal request - %s\n", nt_errstr(status
));
501 if ((rep
->r
.DelResponse
.resultcode
== 0)
502 || (rep
->r
.DelResponse
.errormessage
== NULL
)
503 || (strtol(rep
->r
.DelResponse
.errormessage
, &endptr
,16) <= 0)
504 || (*endptr
!= ':')) {
505 printf("Invalid error message!\n");
509 err
= ad_error(rep
->r
.DelResponse
.errormessage
, &endptr
);
510 err_code_str
= win_errstr(err
);
511 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
512 if ((!W_ERROR_EQUAL(err
, WERR_DS_CANT_DELETE
) &&
513 !W_ERROR_EQUAL(err
, WERR_DS_UNWILLING_TO_PERFORM
))
514 || (rep
->r
.DelResponse
.resultcode
!= LDAP_UNWILLING_TO_PERFORM
)) {
518 printf(" Try another wrong removal\n");
520 msg
->type
= LDAP_TAG_DelRequest
;
521 msg
->r
.DelRequest
.dn
= "";
523 req
= ldap_request_send(conn
, msg
);
528 status
= ldap_result_one(req
, &rep
, LDAP_TAG_DelResponse
);
529 if (!NT_STATUS_IS_OK(status
)) {
530 printf("error in ldap removal request - %s\n", nt_errstr(status
));
534 if ((rep
->r
.DelResponse
.resultcode
== 0)
535 || (rep
->r
.DelResponse
.errormessage
== NULL
)
536 || (strtol(rep
->r
.DelResponse
.errormessage
, &endptr
,16) <= 0)
537 || (*endptr
!= ':')) {
538 printf("Invalid error message!\n");
542 err
= ad_error(rep
->r
.DelResponse
.errormessage
, &endptr
);
543 err_code_str
= win_errstr(err
);
544 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
545 if ((!W_ERROR_EQUAL(err
, WERR_DS_OBJ_NOT_FOUND
) &&
546 !W_ERROR_EQUAL(err
, WERR_DS_NO_SUCH_OBJECT
))
547 || (rep
->r
.DelResponse
.resultcode
!= LDAP_NO_SUCH_OBJECT
)) {
551 printf(" Try a wrong rename\n");
553 msg
->type
= LDAP_TAG_ModifyDNRequest
;
554 msg
->r
.ModifyDNRequest
.dn
= basedn
;
555 msg
->r
.ModifyDNRequest
.newrdn
= "dc=test";
556 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
557 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
559 req
= ldap_request_send(conn
, msg
);
564 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
565 if (!NT_STATUS_IS_OK(status
)) {
566 printf("error in ldap rename request - %s\n", nt_errstr(status
));
570 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
571 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
572 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
573 || (*endptr
!= ':')) {
574 printf("Invalid error message!\n");
578 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
579 err_code_str
= win_errstr(err
);
580 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
581 if ((!W_ERROR_EQUAL(err
, WERR_DS_NO_PARENT_OBJECT
) &&
582 !W_ERROR_EQUAL(err
, WERR_DS_GENERIC_ERROR
))
583 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_OTHER
)) {
587 printf(" Try another wrong rename\n");
589 msg
->type
= LDAP_TAG_ModifyDNRequest
;
590 msg
->r
.ModifyDNRequest
.dn
= basedn
;
591 msg
->r
.ModifyDNRequest
.newrdn
= basedn
;
592 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
593 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
595 req
= ldap_request_send(conn
, msg
);
600 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
601 if (!NT_STATUS_IS_OK(status
)) {
602 printf("error in ldap rename request - %s\n", nt_errstr(status
));
606 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
607 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
608 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
609 || (*endptr
!= ':')) {
610 printf("Invalid error message!\n");
614 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
615 err_code_str
= win_errstr(err
);
616 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
617 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAMETER
) &&
618 !W_ERROR_EQUAL(err
, WERR_DS_NAMING_VIOLATION
))
619 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_NAMING_VIOLATION
)) {
623 printf(" Try another wrong rename\n");
625 msg
->type
= LDAP_TAG_ModifyDNRequest
;
626 msg
->r
.ModifyDNRequest
.dn
= basedn
;
627 msg
->r
.ModifyDNRequest
.newrdn
= "";
628 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
629 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
631 req
= ldap_request_send(conn
, msg
);
636 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
637 if (!NT_STATUS_IS_OK(status
)) {
638 printf("error in ldap rename request - %s\n", nt_errstr(status
));
642 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
643 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
644 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
645 || (*endptr
!= ':')) {
646 printf("Invalid error message!\n");
650 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
651 err_code_str
= win_errstr(err
);
652 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
653 if ((!W_ERROR_EQUAL(err
, WERR_INVALID_PARAMETER
) &&
654 !W_ERROR_EQUAL(err
, WERR_DS_PROTOCOL_ERROR
))
655 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_PROTOCOL_ERROR
)) {
659 printf(" Try another wrong rename\n");
661 msg
->type
= LDAP_TAG_ModifyDNRequest
;
662 msg
->r
.ModifyDNRequest
.dn
= "";
663 msg
->r
.ModifyDNRequest
.newrdn
= "cn=temp";
664 msg
->r
.ModifyDNRequest
.deleteolddn
= true;
665 msg
->r
.ModifyDNRequest
.newsuperior
= NULL
;
667 req
= ldap_request_send(conn
, msg
);
672 status
= ldap_result_one(req
, &rep
, LDAP_TAG_ModifyDNResponse
);
673 if (!NT_STATUS_IS_OK(status
)) {
674 printf("error in ldap rename request - %s\n", nt_errstr(status
));
678 if ((rep
->r
.ModifyDNResponse
.resultcode
== 0)
679 || (rep
->r
.ModifyDNResponse
.errormessage
== NULL
)
680 || (strtol(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
,16) <= 0)
681 || (*endptr
!= ':')) {
682 printf("Invalid error message!\n");
686 err
= ad_error(rep
->r
.ModifyDNResponse
.errormessage
, &endptr
);
687 err_code_str
= win_errstr(err
);
688 printf(" - Errorcode: %s; Reason: %s\n", err_code_str
, endptr
);
689 if ((!W_ERROR_EQUAL(err
, WERR_DS_OBJ_NOT_FOUND
) &&
690 !W_ERROR_EQUAL(err
, WERR_DS_NO_SUCH_OBJECT
))
691 || (rep
->r
.ModifyDNResponse
.resultcode
!= LDAP_NO_SUCH_OBJECT
)) {
698 static bool test_referrals(struct torture_context
*tctx
, TALLOC_CTX
*mem_ctx
,
699 const char *url
, const char *basedn
, const char **partitions
)
701 struct ldb_context
*ldb
;
702 struct ldb_result
*res
;
703 const char * const *attrs
= { NULL
};
704 struct ldb_dn
*dn1
, *dn2
;
710 printf("Testing referrals\n");
712 if (partitions
[0] == NULL
) {
713 printf("Partitions list empty!\n");
717 if (strcmp(partitions
[0], basedn
) != 0) {
718 printf("The first (root) partition DN should be the base DN!\n");
722 ldb
= ldb_wrap_connect(mem_ctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
723 NULL
, popt_get_cmdline_credentials(), 0);
725 /* "partitions[i]" are the partitions for which we search the parents */
726 for (i
= 1; partitions
[i
] != NULL
; i
++) {
727 dn1
= ldb_dn_new(mem_ctx
, ldb
, partitions
[i
]);
729 printf("Out of memory\n");
734 /* search using base scope */
735 /* "partitions[j]" are the parent candidates */
736 for (j
= str_list_length(partitions
) - 1; j
>= 0; --j
) {
737 dn2
= ldb_dn_new(mem_ctx
, ldb
, partitions
[j
]);
739 printf("Out of memory\n");
744 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
745 LDB_SCOPE_BASE
, attrs
,
747 if (ret
!= LDB_SUCCESS
) {
748 printf("%s", ldb_errstring(ldb
));
753 if (res
->refs
!= NULL
) {
754 printf("There shouldn't be generated any referrals in the base scope!\n");
763 /* search using onelevel scope */
765 /* "partitions[j]" are the parent candidates */
766 for (j
= str_list_length(partitions
) - 1; j
>= 0; --j
) {
767 dn2
= ldb_dn_new(mem_ctx
, ldb
, partitions
[j
]);
769 printf("Out of memory\n");
774 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
775 LDB_SCOPE_ONELEVEL
, attrs
,
777 if (ret
!= LDB_SUCCESS
) {
778 printf("%s", ldb_errstring(ldb
));
783 tempstr
= talloc_asprintf(mem_ctx
, "/%s??base",
785 if (tempstr
== NULL
) {
786 printf("Out of memory\n");
791 /* Try to find or find not a matching referral */
793 for (k
= 0; (!l_found
) && (res
->refs
!= NULL
)
794 && (res
->refs
[k
] != NULL
); k
++) {
795 if (strstr(res
->refs
[k
], tempstr
) != NULL
) {
800 talloc_free(tempstr
);
802 if ((!found
) && (ldb_dn_compare_base(dn2
, dn1
) == 0)
803 && (ldb_dn_compare(dn2
, dn1
) != 0)) {
804 /* This is a referral candidate */
806 printf("A required referral hasn't been found on onelevel scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
812 /* This isn't a referral candidate */
814 printf("A unrequired referral has been found on onelevel scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
824 /* search using subtree scope */
826 /* "partitions[j]" are the parent candidates */
827 for (j
= str_list_length(partitions
) - 1; j
>= 0; --j
) {
828 dn2
= ldb_dn_new(mem_ctx
, ldb
, partitions
[j
]);
830 printf("Out of memory\n");
835 ret
= ldb_search(ldb
, mem_ctx
, &res
, dn2
,
836 LDB_SCOPE_SUBTREE
, attrs
,
838 if (ret
!= LDB_SUCCESS
) {
839 printf("%s", ldb_errstring(ldb
));
844 tempstr
= talloc_asprintf(mem_ctx
, "/%s",
846 if (tempstr
== NULL
) {
847 printf("Out of memory\n");
852 /* Try to find or find not a matching referral */
854 for (k
= 0; (!l_found
) && (res
->refs
!= NULL
)
855 && (res
->refs
[k
] != NULL
); k
++) {
856 if (strstr(res
->refs
[k
], tempstr
) != NULL
) {
861 talloc_free(tempstr
);
863 if ((!found
) && (ldb_dn_compare_base(dn2
, dn1
) == 0)
864 && (ldb_dn_compare(dn2
, dn1
) != 0)) {
865 /* This is a referral candidate */
867 printf("A required referral hasn't been found on subtree scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
873 /* This isn't a referral candidate */
875 printf("A unrequired referral has been found on subtree scope (%s -> %s)!\n", partitions
[j
], partitions
[i
]);
893 static bool test_abandon_request(struct torture_context
*tctx
,
894 struct ldap_connection
*conn
, const char *basedn
)
896 struct ldap_message
*msg
;
897 struct ldap_request
*req
;
900 printf("Testing the AbandonRequest with an old message id!\n");
906 msg
= new_ldap_message(conn
);
911 printf(" Try a AbandonRequest for an old message id\n");
913 msg
->type
= LDAP_TAG_AbandonRequest
;
914 msg
->r
.AbandonRequest
.messageid
= 1;
916 req
= ldap_request_send(conn
, msg
);
921 status
= ldap_request_wait(req
);
922 if (!NT_STATUS_IS_OK(status
)) {
923 printf("error in ldap abandon request - %s\n", nt_errstr(status
));
931 bool torture_ldap_basic(struct torture_context
*torture
)
934 struct ldap_connection
*conn
;
937 const char *host
= torture_setting_string(torture
, "host", NULL
);
938 const char *userdn
= torture_setting_string(torture
, "ldap_userdn", NULL
);
939 const char *secret
= torture_setting_string(torture
, "ldap_secret", NULL
);
942 const char **partitions
;
944 mem_ctx
= talloc_init("torture_ldap_basic");
946 url
= talloc_asprintf(mem_ctx
, "ldap://%s/", host
);
948 status
= torture_ldap_connection(torture
, &conn
, url
);
949 if (!NT_STATUS_IS_OK(status
)) {
953 if (!test_search_rootDSE(conn
, &basedn
, &partitions
)) {
957 if (!test_search_rootDSE_empty_substring(conn
)) {
961 /* other bind tests here */
963 if (!test_multibind(conn
, userdn
, secret
)) {
967 if (!test_bind_sasl(torture
, conn
, popt_get_cmdline_credentials())) {
971 if (!test_search_auth_empty_substring(conn
, basedn
)) {
975 if (!test_compare_sasl(conn
, basedn
)) {
979 /* error codes test here */
981 if (!test_error_codes(torture
, conn
, basedn
)) {
985 /* referrals test here */
987 if (!test_referrals(torture
, mem_ctx
, url
, basedn
, partitions
)) {
991 if (!test_abandon_request(torture
, conn
, basedn
)) {
995 /* if there are no more tests we are closing */
996 torture_ldap_close(conn
);
997 talloc_free(mem_ctx
);
999 torture_assert(torture
, ret
, "torture_ldap_basic failed");