2 Unix SMB/CIFS Implementation.
4 test CLDAP/LDAP netlogon operations
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Matthias Dieter Wallnöfer 2009
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/>.
25 #include "libcli/cldap/cldap.h"
26 #include "libcli/ldap/ldap_client.h"
27 #include "libcli/ldap/ldap_ndr.h"
28 #include "libcli/resolve/resolve.h"
29 #include "librpc/gen_ndr/netlogon.h"
30 #include "param/param.h"
31 #include "../lib/tsocket/tsocket.h"
33 #include "torture/torture.h"
34 #include "torture/ldap/proto.h"
36 #define CHECK_STATUS(status, correct) torture_assert_ntstatus_equal(tctx, status, correct, "incorrect status")
38 #define CHECK_VAL(v, correct) torture_assert_int_equal(tctx, (v), (correct), "incorrect value");
40 #define CHECK_STRING(v, correct) torture_assert_str_equal(tctx, v, correct, "incorrect value");
42 typedef NTSTATUS (*request_netlogon_t)(void *con,
44 struct cldap_netlogon *io);
46 typedef NTSTATUS (*request_rootdse_t)(void *con,
48 struct cldap_search *io);
51 test netlogon operations
53 static bool test_ldap_netlogon(struct torture_context *tctx,
54 request_netlogon_t request_netlogon,
59 struct cldap_netlogon search, empty_search;
60 struct netlogon_samlogon_response n1;
65 search.in.dest_address = NULL;
66 search.in.dest_port = 0;
67 search.in.acct_control = -1;
68 search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
69 search.in.map_response = true;
71 empty_search = search;
73 printf("Trying without any attributes\n");
74 search = empty_search;
75 status = request_netlogon(cldap, tctx, &search);
76 CHECK_STATUS(status, NT_STATUS_OK);
78 n1 = search.out.netlogon;
80 search.in.user = "Administrator";
81 search.in.realm = n1.data.nt5_ex.dns_domain;
82 search.in.host = "__cldap_torture__";
84 printf("Scanning for netlogon levels\n");
86 search.in.version = i;
87 printf("Trying netlogon level %d\n", i);
88 status = request_netlogon(cldap, tctx, &search);
89 CHECK_STATUS(status, NT_STATUS_OK);
92 printf("Scanning for netlogon level bits\n");
94 search.in.version = (1<<i);
95 printf("Trying netlogon level 0x%x\n", i);
96 status = request_netlogon(cldap, tctx, &search);
97 CHECK_STATUS(status, NT_STATUS_OK);
100 search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP;
101 status = request_netlogon(cldap, tctx, &search);
102 CHECK_STATUS(status, NT_STATUS_OK);
104 printf("Trying with User=NULL\n");
105 search.in.user = NULL;
106 status = request_netlogon(cldap, tctx, &search);
107 CHECK_STATUS(status, NT_STATUS_OK);
108 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
109 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
111 strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
112 "PDC name should not be in UNC form");
114 printf("Trying with User=Administrator\n");
115 search.in.user = "Administrator";
116 status = request_netlogon(cldap, tctx, &search);
117 CHECK_STATUS(status, NT_STATUS_OK);
118 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
119 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
121 strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
122 "PDC name should not be in UNC form");
124 search.in.version = NETLOGON_NT_VERSION_5;
125 status = request_netlogon(cldap, tctx, &search);
126 CHECK_STATUS(status, NT_STATUS_OK);
128 printf("Trying with User=NULL\n");
129 search.in.user = NULL;
130 status = request_netlogon(cldap, tctx, &search);
131 CHECK_STATUS(status, NT_STATUS_OK);
132 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);
133 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
135 strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
136 "PDC name should be in UNC form");
138 printf("Trying with User=Administrator\n");
139 search.in.user = "Administrator";
140 status = request_netlogon(cldap, tctx, &search);
141 CHECK_STATUS(status, NT_STATUS_OK);
142 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);
143 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
145 strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
146 "PDC name should be in UNC form");
148 search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
150 printf("Trying with a GUID\n");
151 search.in.realm = NULL;
152 search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
153 status = request_netlogon(cldap, tctx, &search);
154 CHECK_STATUS(status, NT_STATUS_OK);
155 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
156 CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid);
158 strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
159 "PDC name should not be in UNC form");
161 printf("Trying with a incorrect GUID\n");
162 guid = GUID_random();
163 search.in.user = NULL;
164 search.in.domain_guid = GUID_string(tctx, &guid);
165 status = request_netlogon(cldap, tctx, &search);
166 CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
168 printf("Trying with a AAC\n");
169 search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
170 search.in.realm = n1.data.nt5_ex.dns_domain;
171 status = request_netlogon(cldap, tctx, &search);
172 CHECK_STATUS(status, NT_STATUS_OK);
173 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
174 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
176 printf("Trying with a zero AAC\n");
177 search.in.acct_control = 0x0;
178 search.in.realm = n1.data.nt5_ex.dns_domain;
179 status = request_netlogon(cldap, tctx, &search);
180 CHECK_STATUS(status, NT_STATUS_OK);
181 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
182 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
184 printf("Trying with a zero AAC and user=Administrator\n");
185 search.in.acct_control = 0x0;
186 search.in.user = "Administrator";
187 search.in.realm = n1.data.nt5_ex.dns_domain;
188 status = request_netlogon(cldap, tctx, &search);
189 CHECK_STATUS(status, NT_STATUS_OK);
190 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
191 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator");
193 printf("Trying with a bad AAC\n");
194 search.in.user = NULL;
195 search.in.acct_control = 0xFF00FF00;
196 search.in.realm = n1.data.nt5_ex.dns_domain;
197 status = request_netlogon(cldap, tctx, &search);
198 CHECK_STATUS(status, NT_STATUS_OK);
199 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
200 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
202 printf("Trying with a user only\n");
203 search = empty_search;
204 search.in.user = "Administrator";
205 status = request_netlogon(cldap, tctx, &search);
206 CHECK_STATUS(status, NT_STATUS_OK);
207 CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
208 CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
209 CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
210 CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
211 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
212 CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
213 CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);
215 printf("Trying with just a bad username\n");
216 search.in.user = "___no_such_user___";
217 status = request_netlogon(cldap, tctx, &search);
218 CHECK_STATUS(status, NT_STATUS_OK);
219 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
220 CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
221 CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
222 CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
223 CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
224 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
225 CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
226 CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);
228 printf("Trying with just a bad domain\n");
229 search = empty_search;
230 search.in.realm = "___no_such_domain___";
231 status = request_netlogon(cldap, tctx, &search);
232 CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
234 printf("Trying with a incorrect domain and correct guid\n");
235 search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
236 status = request_netlogon(cldap, tctx, &search);
237 CHECK_STATUS(status, NT_STATUS_OK);
238 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
239 CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
240 CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
241 CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
242 CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
243 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
244 CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
245 CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);
247 printf("Trying with a incorrect domain and incorrect guid\n");
248 search.in.domain_guid = GUID_string(tctx, &guid);
249 status = request_netlogon(cldap, tctx, &search);
250 CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
251 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
252 CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
253 CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
254 CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
255 CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
256 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
257 CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
258 CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);
260 printf("Trying with a incorrect GUID and correct domain\n");
261 search.in.domain_guid = GUID_string(tctx, &guid);
262 search.in.realm = n1.data.nt5_ex.dns_domain;
263 status = request_netlogon(cldap, tctx, &search);
264 CHECK_STATUS(status, NT_STATUS_OK);
265 CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
266 CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
267 CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
268 CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
269 CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
270 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
271 CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
272 CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);
274 printf("Proof other results\n");
275 search.in.user = "Administrator";
276 status = request_netlogon(cldap, tctx, &search);
277 CHECK_STATUS(status, NT_STATUS_OK);
278 CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
279 CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
280 CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
281 CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
282 CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
283 CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
284 CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);
290 test cldap netlogon server type flags
292 static bool test_ldap_netlogon_flags(struct torture_context *tctx,
293 request_netlogon_t request_netlogon,
298 struct cldap_netlogon search;
299 struct netlogon_samlogon_response n1;
300 uint32_t server_type = 0;
302 printf("Printing out netlogon server type flags: %s\n", dest);
305 search.in.dest_address = NULL;
306 search.in.dest_port = 0;
307 search.in.acct_control = -1;
308 search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
309 search.in.map_response = true;
311 status = request_netlogon(cldap, tctx, &search);
312 CHECK_STATUS(status, NT_STATUS_OK);
314 n1 = search.out.netlogon;
315 if (n1.ntver == NETLOGON_NT_VERSION_5)
316 server_type = n1.data.nt5.server_type;
317 else if (n1.ntver == NETLOGON_NT_VERSION_5EX)
318 server_type = n1.data.nt5_ex.server_type;
320 printf("The word is: %i\n", server_type);
321 if (server_type & NBT_SERVER_PDC)
322 printf("NBT_SERVER_PDC ");
323 if (server_type & NBT_SERVER_GC)
324 printf("NBT_SERVER_GC ");
325 if (server_type & NBT_SERVER_LDAP)
326 printf("NBT_SERVER_LDAP ");
327 if (server_type & NBT_SERVER_DS)
328 printf("NBT_SERVER_DS ");
329 if (server_type & NBT_SERVER_KDC)
330 printf("NBT_SERVER_KDC ");
331 if (server_type & NBT_SERVER_TIMESERV)
332 printf("NBT_SERVER_TIMESERV ");
333 if (server_type & NBT_SERVER_CLOSEST)
334 printf("NBT_SERVER_CLOSEST ");
335 if (server_type & NBT_SERVER_WRITABLE)
336 printf("NBT_SERVER_WRITABLE ");
337 if (server_type & NBT_SERVER_GOOD_TIMESERV)
338 printf("NBT_SERVER_GOOD_TIMESERV ");
339 if (server_type & NBT_SERVER_NDNC)
340 printf("NBT_SERVER_NDNC ");
341 if (server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6)
342 printf("NBT_SERVER_SELECT_SECRET_DOMAIN_6");
343 if (server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6)
344 printf("NBT_SERVER_FULL_SECRET_DOMAIN_6");
345 if (server_type & NBT_SERVER_ADS_WEB_SERVICE)
346 printf("NBT_SERVER_ADS_WEB_SERVICE ");
347 if (server_type & NBT_SERVER_DS_8)
348 printf("NBT_SERVER_DS_8 ");
349 if (server_type & DS_DNS_CONTROLLER)
350 printf("DS_DNS_CONTROLLER ");
351 if (server_type & DS_DNS_DOMAIN)
352 printf("DS_DNS_DOMAIN ");
353 if (server_type & DS_DNS_FOREST_ROOT)
354 printf("DS_DNS_FOREST_ROOT ");
361 static NTSTATUS tcp_ldap_rootdse(void *data,
363 struct cldap_search *io)
365 struct ldap_connection *conn = talloc_get_type(data,
366 struct ldap_connection);
367 struct ldap_message *msg, *result;
368 struct ldap_request *req;
372 msg = new_ldap_message(mem_ctx);
374 return NT_STATUS_NO_MEMORY;
377 msg->type = LDAP_TAG_SearchRequest;
378 msg->r.SearchRequest.basedn = "";
379 msg->r.SearchRequest.scope = LDAP_SEARCH_SCOPE_BASE;
380 msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER;
381 msg->r.SearchRequest.timelimit = 0;
382 msg->r.SearchRequest.sizelimit = 0;
383 msg->r.SearchRequest.attributesonly = false;
384 msg->r.SearchRequest.tree = ldb_parse_tree(msg, io->in.filter);
385 msg->r.SearchRequest.num_attributes = str_list_length(io->in.attributes);
386 msg->r.SearchRequest.attributes = io->in.attributes;
388 req = ldap_request_send(conn, msg);
390 printf("Could not setup ldap search\n");
391 return NT_STATUS_UNSUCCESSFUL;
394 ZERO_STRUCT(io->out);
395 for (i = 0; i < 2; ++i) {
396 status = ldap_result_n(req, i, &result);
397 if (!NT_STATUS_IS_OK(status)) {
400 switch (result->type) {
401 case LDAP_TAG_SearchResultEntry:
403 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
405 io->out.response = &result->r.SearchResultEntry;
407 case LDAP_TAG_SearchResultDone:
408 io->out.result = &result->r.SearchResultDone;
409 if (io->out.result->resultcode != LDAP_SUCCESS) {
410 return NT_STATUS_LDAP(io->out.result->resultcode);
415 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
422 static NTSTATUS tcp_ldap_netlogon(void *conn,
424 struct cldap_netlogon *io)
426 struct cldap_search search;
427 struct ldap_SearchResEntry *res;
432 search.in.attributes = (const char *[]) { "netlogon", NULL };
433 search.in.filter = cldap_netlogon_create_filter(mem_ctx, io);
434 if (search.in.filter == NULL) {
435 return NT_STATUS_NO_MEMORY;
438 status = tcp_ldap_rootdse(conn, mem_ctx, &search);
439 if (!NT_STATUS_IS_OK(status)) {
443 res = search.out.response;
445 return NT_STATUS_NOT_FOUND;
448 if (res->num_attributes != 1 ||
449 strcasecmp(res->attributes[0].name, "netlogon") != 0 ||
450 res->attributes[0].num_values != 1 ||
451 res->attributes[0].values->length < 2) {
452 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
455 blob = res->attributes[0].values;
456 status = pull_netlogon_samlogon_response(blob, mem_ctx,
458 if (!NT_STATUS_IS_OK(status)) {
462 if (io->in.map_response) {
463 map_netlogon_samlogon_response(&io->out.netlogon);
469 static NTSTATUS udp_ldap_rootdse(void *data, TALLOC_CTX *mem_ctx,
470 struct cldap_search *io)
472 struct cldap_socket *cldap = talloc_get_type(data,
473 struct cldap_socket);
475 return cldap_search(cldap, mem_ctx, io);
478 static bool test_netlogon_extra_attrs(struct torture_context *tctx,
479 request_rootdse_t request_rootdse,
482 struct cldap_search io;
484 const char *attrs[] = {
486 "supportedCapabilities",
489 const char *attrs2[] = { "netlogon", "*", NULL };
490 struct ldb_message ldbmsg = { NULL, 0, NULL };
493 io.in.dest_address = NULL;
497 /* Additional attributes may be requested next to netlogon */
498 torture_comment(tctx, "Requesting netlogon with additional attribute\n");
500 talloc_asprintf(tctx, "(&"
502 /* Query for LDAP_CAP_ACTIVE_DIRECTORY_OID */
503 "(supportedCapabilities=1.2.840.113556.1.4.800)"
505 ldap_encode_ndr_uint32(tctx,
506 NETLOGON_NT_VERSION_5EX),
507 ldap_encode_ndr_uint32(tctx, 0));
508 torture_assert(tctx, io.in.filter != NULL, "OOM");
509 io.in.attributes = attrs;
510 status = request_rootdse(conn, tctx, &io);
511 CHECK_STATUS(status, NT_STATUS_OK);
512 torture_assert(tctx, io.out.response != NULL, "No Entries found.");
513 CHECK_VAL(io.out.response->num_attributes, 2);
515 /* netlogon + '*' attr return zero results */
516 torture_comment(tctx, "Requesting netlogon and '*' attributes\n");
517 io.in.attributes = attrs2;
518 status = request_rootdse(conn, tctx, &io);
519 CHECK_STATUS(status, NT_STATUS_OK);
520 torture_assert(tctx, io.out.response != NULL, "No Entries found.");
521 ldbmsg.num_elements = io.out.response->num_attributes;
522 ldbmsg.elements = io.out.response->attributes;
523 torture_assert(tctx, ldb_msg_find_element(&ldbmsg, "netlogon") != NULL,
524 "Attribute netlogon not found in Result Entry\n");
526 /* Wildcards are not allowed in filters when netlogon is requested. */
527 torture_comment(tctx, "Requesting netlogon with invalid attr filter\n");
529 talloc_asprintf(tctx,
530 "(&(NtVer=%s)(AAC=%s)(supportedCapabilities=*))",
531 ldap_encode_ndr_uint32(tctx,
532 NETLOGON_NT_VERSION_5EX),
533 ldap_encode_ndr_uint32(tctx, 0));
534 torture_assert(tctx, io.in.filter != NULL, "OOM");
535 io.in.attributes = attrs;
536 status = request_rootdse(conn, tctx, &io);
537 CHECK_STATUS(status, NT_STATUS_OK);
538 torture_assert(tctx, io.out.response == NULL,
539 "A wildcard filter should return no entries.");
545 Bug #11392: Huawei Unified Storage System S5500 V3 sends no NtVer
546 [MS-ADTS] Section 7.3.3.2 "Domain Controller Response to an LDAP Ping"
548 static bool test_netlogon_huawei(struct torture_context *tctx,
549 request_rootdse_t request_rootdse,
552 struct cldap_search io;
553 struct netlogon_samlogon_response n1;
555 const char *attrs[] = {
559 struct ldb_message ldbmsg = { NULL, 0, NULL };
562 io.in.dest_address = NULL;
567 torture_comment(tctx, "Requesting netlogon without NtVer filter\n");
568 io.in.filter = talloc_asprintf(tctx, "(&(DnsDomain=%s))",
569 lpcfg_dnsdomain(tctx->lp_ctx));
570 torture_assert(tctx, io.in.filter != NULL, "OOM");
571 io.in.attributes = attrs;
572 status = request_rootdse(conn, tctx, &io);
573 CHECK_STATUS(status, NT_STATUS_OK);
574 torture_assert(tctx, io.out.response != NULL, "No Entries found.");
575 CHECK_VAL(io.out.response->num_attributes, 1);
577 ldbmsg.num_elements = io.out.response->num_attributes;
578 ldbmsg.elements = io.out.response->attributes;
579 torture_assert(tctx, ldb_msg_find_element(&ldbmsg, "netlogon") != NULL,
580 "Attribute netlogon not found in Result Entry\n");
582 status = pull_netlogon_samlogon_response(
583 io.out.response->attributes[0].values,
586 CHECK_STATUS(status, NT_STATUS_OK);
587 CHECK_VAL(n1.ntver, NETLOGON_NT_VERSION_5);
592 bool torture_netlogon_tcp(struct torture_context *tctx)
594 const char *host = torture_setting_string(tctx, "host", NULL);
597 struct ldap_connection *conn;
601 mem_ctx = talloc_init("torture_ldap_netlogon");
603 url = talloc_asprintf(mem_ctx, "ldap://%s/", host);
605 status = torture_ldap_connection(tctx, &conn, url);
606 if (!NT_STATUS_IS_OK(status)) {
610 ret &= test_ldap_netlogon(tctx, tcp_ldap_netlogon, conn, host);
611 ret &= test_ldap_netlogon_flags(tctx, tcp_ldap_netlogon, conn, host);
612 ret &= test_netlogon_extra_attrs(tctx, tcp_ldap_rootdse, conn);
617 static NTSTATUS udp_ldap_netlogon(void *data,
619 struct cldap_netlogon *io)
621 struct cldap_socket *cldap = talloc_get_type(data,
622 struct cldap_socket);
624 return cldap_netlogon(cldap, mem_ctx, io);
627 bool torture_netlogon_udp(struct torture_context *tctx)
629 const char *host = torture_setting_string(tctx, "host", NULL);
631 struct nbt_name nbt_name;
634 struct cldap_socket *cldap;
636 struct tsocket_address *dest_addr;
638 make_nbt_name_server(&nbt_name, host);
640 status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
641 0, 0, &nbt_name, tctx, &ip, tctx->ev);
642 torture_assert_ntstatus_ok(tctx, status,
643 talloc_asprintf(tctx,"Failed to resolve %s: %s",
644 nbt_name.name, nt_errstr(status)));
646 r = tsocket_address_inet_from_strings(tctx, "ip",
648 lpcfg_cldap_port(tctx->lp_ctx),
652 /* cldap_socket_init should now know about the dest. address */
653 status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
654 CHECK_STATUS(status, NT_STATUS_OK);
656 ret &= test_ldap_netlogon(tctx, udp_ldap_netlogon, cldap, host);
657 ret &= test_ldap_netlogon_flags(tctx, udp_ldap_netlogon, cldap, host);
658 ret &= test_netlogon_extra_attrs(tctx, udp_ldap_rootdse, cldap);
659 ret &= test_netlogon_huawei(tctx, udp_ldap_rootdse, cldap);