2 Unix SMB/CIFS implementation.
6 Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "lib/cmdline/popt_common.h"
26 #include "torture/torture.h"
28 #define torture_assert_res(torture_ctx,expr,cmt,_res) \
30 torture_result(torture_ctx, TORTURE_FAIL, __location__": Expression `%s' failed: %s", __STRING(expr), cmt); \
35 struct nested_search_context
{
36 struct torture_context
*tctx
;
37 struct ldb_dn
*root_dn
;
38 struct ldb_context
*ldb
;
39 struct ldb_result
*ldb_res
;
43 * ldb_search handler - used to executed a nested
44 * ldap search request during LDB_REPLY_ENTRY handling
46 static int nested_search_callback(struct ldb_request
*req
,
47 struct ldb_reply
*ares
)
51 struct nested_search_context
*sctx
;
52 struct ldb_result
*ldb_res
;
53 struct ldb_message
*ldb_msg
;
54 static const char *attrs
[] = {
55 "rootDomainNamingContext",
56 "configurationNamingContext",
57 "schemaNamingContext",
58 "defaultNamingContext",
62 sctx
= talloc_get_type(req
->context
, struct nested_search_context
);
67 torture_comment(sctx
->tctx
, "nested_search_callback: LDB_REPLY_ENTRY\n");
68 ldb_msg
= ares
->message
;
69 torture_assert_res(sctx
->tctx
, ldb_msg
, "ares->message is NULL!", LDB_ERR_OPERATIONS_ERROR
);
70 torture_assert_res(sctx
->tctx
, ldb_msg
->num_elements
, "No elements returned!", LDB_ERR_OPERATIONS_ERROR
);
71 torture_assert_res(sctx
->tctx
, ldb_msg
->elements
, "elements member is NULL!", LDB_ERR_OPERATIONS_ERROR
);
74 torture_comment(sctx
->tctx
, "nested_search_callback: LDB_REPLY_DONE\n");
76 case LDB_REPLY_REFERRAL
:
77 torture_comment(sctx
->tctx
, "nested_search_callback: LDB_REPLY_REFERRAL\n");
81 /* switch context and let default handler do its job */
82 req
->context
= sctx
->ldb_res
;
83 res
= ldb_search_default_callback(req
, ares
);
85 if (res
!= LDB_SUCCESS
) {
89 /* not a search reply, then get out */
90 if (ares
->type
!= LDB_REPLY_ENTRY
) {
95 res
= ldb_search(sctx
->ldb
, sctx
, &ldb_res
, sctx
->root_dn
, LDB_SCOPE_BASE
, attrs
, "(objectClass=*)");
96 if (res
!= LDB_SUCCESS
) {
97 torture_warning(sctx
->tctx
,
98 "Search on RootDSE failed in search_entry handler: %s",
99 ldb_errstring(sctx
->ldb
));
103 torture_assert_res(sctx
->tctx
, ldb_res
->count
== 1, "One message expected here", LDB_ERR_OPERATIONS_ERROR
);
105 ldb_msg
= ldb_res
->msgs
[0];
106 torture_assert_res(sctx
->tctx
, ldb_msg
->num_elements
== (ARRAY_SIZE(attrs
)-1),
107 "Search returned different number of elts than requested", LDB_ERR_OPERATIONS_ERROR
);
108 for (i
= 0; i
< ldb_msg
->num_elements
; i
++) {
110 struct ldb_message_element
*elt1
;
111 struct ldb_message_element
*elt2
;
113 elt2
= &ldb_msg
->elements
[i
];
114 msg
= talloc_asprintf(sctx
, "Processing element: %s", elt2
->name
);
115 elt1
= ldb_msg_find_element(sctx
->ldb_res
->msgs
[0], elt2
->name
);
116 torture_assert_res(sctx
->tctx
, elt1
, msg
, LDB_ERR_OPERATIONS_ERROR
);
118 /* compare elements */
119 torture_assert_res(sctx
->tctx
, elt2
->flags
== elt1
->flags
, "", LDB_ERR_OPERATIONS_ERROR
);
120 torture_assert_res(sctx
->tctx
, elt2
->num_values
== elt1
->num_values
, "", LDB_ERR_OPERATIONS_ERROR
);
122 /* TODO: check returned result */
128 * Test nested search execution against RootDSE
129 * on remote LDAP server.
131 bool test_ldap_nested_search(struct torture_context
*tctx
)
135 const char *host
= torture_setting_string(tctx
, "host", NULL
);
136 struct ldb_request
*req
;
137 struct nested_search_context
*sctx
;
138 static const char *attrs
[] = {
140 "rootDomainNamingContext",
141 "configurationNamingContext",
142 "schemaNamingContext",
143 "defaultNamingContext",
149 sctx
= talloc_zero(tctx
, struct nested_search_context
);
150 torture_assert(tctx
, sctx
, "Not enough memory");
153 url
= talloc_asprintf(sctx
, "ldap://%s/", host
);
155 torture_assert(tctx
, url
, "Not enough memory");
158 torture_comment(tctx
, "Connecting to: %s\n", url
);
159 sctx
->ldb
= ldb_wrap_connect(sctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
163 torture_assert(tctx
, sctx
->ldb
, "Failed to create ldb connection");
165 /* prepare context for searching */
166 sctx
->root_dn
= ldb_dn_new(sctx
, sctx
->ldb
, NULL
);
167 sctx
->ldb_res
= talloc_zero(sctx
, struct ldb_result
);
169 /* build search request */
170 ret
= ldb_build_search_req(&req
,
173 sctx
->root_dn
, LDB_SCOPE_BASE
,
174 "(objectClass=*)", attrs
, NULL
,
175 sctx
, nested_search_callback
,
177 if (ret
!= LDB_SUCCESS
) {
178 torture_result(tctx
, TORTURE_FAIL
,
179 __location__
": Allocating request failed: %s", ldb_errstring(sctx
->ldb
));
183 ret
= ldb_request(sctx
->ldb
, req
);
184 if (ret
!= LDB_SUCCESS
) {
185 torture_result(tctx
, TORTURE_FAIL
,
186 __location__
": Search failed: %s", ldb_errstring(sctx
->ldb
));
190 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
191 if (ret
!= LDB_SUCCESS
) {
192 torture_result(tctx
, TORTURE_FAIL
,
193 __location__
": Search error: %s", ldb_errstring(sctx
->ldb
));
197 /* TODO: check returned result */