2 Unix SMB/CIFS implementation.
3 SMB torture tester - winbind struct based protocol
4 Copyright (C) Stefan Metzmacher 2007
5 Copyright (C) Michael Adam 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "torture/torture.h"
23 #include "nsswitch/libwbclient/wbclient.h"
24 #include "nsswitch/winbind_nss_config.h"
25 #include "nsswitch/winbind_struct_protocol.h"
26 #include "nsswitch/libwbclient/wbclient_internal.h"
27 #include "libcli/security/security.h"
28 #include "librpc/gen_ndr/netlogon.h"
29 #include "param/param.h"
30 #include "../libcli/auth/pam_errors.h"
31 #include "torture/winbind/proto.h"
32 #include "lib/util/string_wrappers.h"
34 #define DO_STRUCT_REQ_REP_EXT(op,req,rep,expected,strict,warnaction,cmt) do { \
35 const char *__cmt = (cmt); \
36 wbcErr __wbc_status = WBC_ERR_UNKNOWN_FAILURE; \
37 NSS_STATUS __got, __expected = (expected); \
38 __wbc_status = wbcRequestResponse(NULL, op, req, rep); \
39 switch (__wbc_status) { \
40 case WBC_ERR_SUCCESS: \
41 __got = NSS_STATUS_SUCCESS; \
43 case WBC_ERR_WINBIND_NOT_AVAILABLE: \
44 __got = NSS_STATUS_UNAVAIL; \
46 case WBC_ERR_DOMAIN_NOT_FOUND: \
47 __got = NSS_STATUS_NOTFOUND; \
50 torture_result(torture, TORTURE_FAIL, \
51 __location__ ": " __STRING(op) \
52 " returned unmapped %s, expected nss %d%s%s", \
53 wbcErrorString(__wbc_status), __expected, \
54 (__cmt) ? ": " : "", \
55 (__cmt) ? (__cmt) : ""); \
58 if (__got != __expected) { \
60 torture_result(torture, TORTURE_FAIL, \
61 __location__ ": " __STRING(op) \
62 " returned %s, got %d , expected %d%s%s", \
63 wbcErrorString(__wbc_status), __got, __expected, \
64 (__cmt) ? ": " : "", \
65 (__cmt) ? (__cmt) : ""); \
68 torture_warning(torture, \
69 __location__ ": " __STRING(op) \
70 " returned %s, got %d , expected %d%s%s", \
71 wbcErrorString(__wbc_status), __got, __expected, \
72 (__cmt) ? ": " : "", \
73 (__cmt) ? (__cmt) : ""); \
80 #define _STRUCT_NOOP do {} while(0);
81 #define DO_STRUCT_REQ_REP(op,req,rep) do { \
82 DO_STRUCT_REQ_REP_EXT(op,req,rep,NSS_STATUS_SUCCESS,true, _STRUCT_NOOP, NULL); \
85 static bool torture_winbind_struct_interface_version(struct torture_context
*torture
)
87 struct winbindd_request req
;
88 struct winbindd_response rep
;
93 torture_comment(torture
, "Running WINBINDD_INTERFACE_VERSION (struct based)\n");
95 DO_STRUCT_REQ_REP(WINBINDD_INTERFACE_VERSION
, &req
, &rep
);
97 torture_assert_int_equal(torture
,
98 rep
.data
.interface_version
,
99 WINBIND_INTERFACE_VERSION
,
100 "winbind server and client doesn't match");
105 static bool torture_winbind_struct_ping(struct torture_context
*torture
)
107 struct timeval tv
= timeval_current();
108 int timelimit
= torture_setting_int(torture
, "timelimit", 5);
111 torture_comment(torture
,
112 "Running WINBINDD_PING (struct based) for %d seconds\n",
115 while (timeval_elapsed(&tv
) < timelimit
) {
116 DO_STRUCT_REQ_REP(WINBINDD_PING
, NULL
, NULL
);
120 torture_comment(torture
,
121 "%u (%.1f/s) WINBINDD_PING (struct based)\n",
122 total
, total
/ timeval_elapsed(&tv
));
128 static char winbind_separator(struct torture_context
*torture
)
130 struct winbindd_response rep
;
134 DO_STRUCT_REQ_REP(WINBINDD_INFO
, NULL
, &rep
);
136 return rep
.data
.info
.winbind_separator
;
139 static bool torture_winbind_struct_info(struct torture_context
*torture
)
141 struct winbindd_response rep
;
142 const char *separator
;
146 torture_comment(torture
, "Running WINBINDD_INFO (struct based)\n");
148 DO_STRUCT_REQ_REP(WINBINDD_INFO
, NULL
, &rep
);
150 separator
= torture_setting_string(torture
,
151 "winbindd_separator",
152 lpcfg_winbind_separator(torture
->lp_ctx
));
154 torture_assert_int_equal(torture
,
155 rep
.data
.info
.winbind_separator
,
157 "winbind separator doesn't match");
159 torture_comment(torture
, "Samba Version '%s'\n",
160 rep
.data
.info
.samba_version
);
165 static bool torture_winbind_struct_priv_pipe_dir(struct torture_context
*torture
)
167 struct winbindd_response rep
;
172 torture_comment(torture
, "Running WINBINDD_PRIV_PIPE_DIR (struct based)\n");
174 DO_STRUCT_REQ_REP(WINBINDD_PRIV_PIPE_DIR
, NULL
, &rep
);
176 got_dir
= (const char *)rep
.extra_data
.data
;
178 torture_assert(torture
, got_dir
, "NULL WINBINDD_PRIV_PIPE_DIR\n");
180 SAFE_FREE(rep
.extra_data
.data
);
184 static bool torture_winbind_struct_netbios_name(struct torture_context
*torture
)
186 struct winbindd_response rep
;
187 const char *expected
;
191 torture_comment(torture
, "Running WINBINDD_NETBIOS_NAME (struct based)\n");
193 DO_STRUCT_REQ_REP(WINBINDD_NETBIOS_NAME
, NULL
, &rep
);
195 expected
= torture_setting_string(torture
,
196 "winbindd_netbios_name",
197 lpcfg_netbios_name(torture
->lp_ctx
));
198 expected
= strupper_talloc(torture
, expected
);
200 torture_assert_str_equal(torture
,
201 rep
.data
.netbios_name
, expected
,
202 "winbindd's netbios name doesn't match");
207 static bool get_winbind_domain(struct torture_context
*torture
, char **domain
)
209 struct winbindd_response rep
;
213 DO_STRUCT_REQ_REP(WINBINDD_DOMAIN_NAME
, NULL
, &rep
);
215 *domain
= talloc_strdup(torture
, rep
.data
.domain_name
);
216 torture_assert(torture
, domain
, "talloc error");
221 static bool torture_winbind_struct_domain_name(struct torture_context
*torture
)
223 const char *expected
;
226 torture_comment(torture
, "Running WINBINDD_DOMAIN_NAME (struct based)\n");
228 expected
= torture_setting_string(torture
,
229 "winbindd_netbios_domain",
230 lpcfg_workgroup(torture
->lp_ctx
));
232 get_winbind_domain(torture
, &domain
);
234 torture_assert_str_equal(torture
, domain
, expected
,
235 "winbindd's netbios domain doesn't match");
240 static bool torture_winbind_struct_check_machacc(struct torture_context
*torture
)
243 bool strict
= torture_setting_bool(torture
, "strict mode", false);
244 struct winbindd_response rep
;
248 torture_comment(torture
, "Running WINBINDD_CHECK_MACHACC (struct based)\n");
251 DO_STRUCT_REQ_REP_EXT(WINBINDD_CHECK_MACHACC
, NULL
, &rep
,
252 NSS_STATUS_SUCCESS
, strict
, ok
= false,
253 "WINBINDD_CHECK_MACHACC");
256 torture_assert(torture
,
257 strlen(rep
.data
.auth
.nt_status_string
)>0,
258 "Failed with empty nt_status_string");
260 torture_warning(torture
,"%s:%s:%s:%d\n",
261 nt_errstr(NT_STATUS(rep
.data
.auth
.nt_status
)),
262 rep
.data
.auth
.nt_status_string
,
263 rep
.data
.auth
.error_string
,
264 rep
.data
.auth
.pam_error
);
268 torture_assert_ntstatus_ok(torture
,
269 NT_STATUS(rep
.data
.auth
.nt_status
),
270 "WINBINDD_CHECK_MACHACC ok: nt_status");
272 torture_assert_str_equal(torture
,
273 rep
.data
.auth
.nt_status_string
,
274 nt_errstr(NT_STATUS_OK
),
275 "WINBINDD_CHECK_MACHACC ok:nt_status_string");
277 torture_assert_str_equal(torture
,
278 rep
.data
.auth
.error_string
,
279 get_friendly_nt_error_msg(NT_STATUS_OK
),
280 "WINBINDD_CHECK_MACHACC ok: error_string");
282 torture_assert_int_equal(torture
,
283 rep
.data
.auth
.pam_error
,
284 nt_status_to_pam(NT_STATUS_OK
),
285 "WINBINDD_CHECK_MACHACC ok: pam_error");
290 struct torture_trust_domain
{
291 const char *netbios_name
;
292 const char *dns_name
;
296 static bool get_trusted_domains(struct torture_context
*torture
,
297 struct torture_trust_domain
**_d
)
299 struct winbindd_request req
;
300 struct winbindd_response rep
;
301 struct torture_trust_domain
*d
= NULL
;
304 const char *extra_data
;
309 DO_STRUCT_REQ_REP(WINBINDD_LIST_TRUSTDOM
, &req
, &rep
);
311 extra_data
= (char *)rep
.extra_data
.data
;
312 torture_assert(torture
, extra_data
!= NULL
,
313 "Trust list was NULL: the list of trusted domain "
314 "should be returned, with at least 2 entries "
315 "(BUILTIN, and the local domain)");
317 while (next_token(&extra_data
, line
, "\n", sizeof(line
))) {
320 d
= talloc_realloc(torture
, d
,
321 struct torture_trust_domain
,
323 ZERO_STRUCT(d
[dcount
+1]);
326 p
= strchr(lp
, '\\');
327 torture_assert(torture
, p
, "missing 1st '\\' in line");
329 d
[dcount
].netbios_name
= talloc_strdup(d
, lp
);
330 torture_assert(torture
, strlen(d
[dcount
].netbios_name
) > 0,
331 "empty netbios_name");
334 p
= strchr(lp
, '\\');
335 torture_assert(torture
, p
, "missing 2nd '\\' in line");
337 d
[dcount
].dns_name
= talloc_strdup(d
, lp
);
338 /* it's ok to have an empty dns_name */
341 d
[dcount
].sid
= dom_sid_parse_talloc(d
, lp
);
342 torture_assert(torture
, d
[dcount
].sid
,
343 "failed to parse sid");
347 SAFE_FREE(rep
.extra_data
.data
);
349 torture_assert(torture
, dcount
>= 2,
350 "The list of trusted domain should contain 2 entries "
351 "(BUILTIN, and the local domain)");
357 static bool torture_winbind_struct_list_trustdom(struct torture_context
*torture
)
359 struct winbindd_request req
;
360 struct winbindd_response rep
;
364 struct torture_trust_domain
*listd
= NULL
;
367 torture_comment(torture
, "Running WINBINDD_LIST_TRUSTDOM (struct based)\n");
372 req
.data
.list_all_domains
= false;
374 DO_STRUCT_REQ_REP(WINBINDD_LIST_TRUSTDOM
, &req
, &rep
);
376 list1
= (char *)rep
.extra_data
.data
;
378 torture_comment(torture
, "%s\n", list1
);
383 req
.data
.list_all_domains
= true;
385 DO_STRUCT_REQ_REP(WINBINDD_LIST_TRUSTDOM
, &req
, &rep
);
387 list2
= (char *)rep
.extra_data
.data
;
390 * The list_all_domains parameter should be ignored
392 torture_assert_str_equal(torture
, list2
, list1
, "list_all_domains not ignored");
397 ok
= get_trusted_domains(torture
, &listd
);
398 torture_assert(torture
, ok
, "failed to get trust list");
400 for (i
=0; listd
&& listd
[i
].netbios_name
; i
++) {
402 struct dom_sid
*builtin_sid
;
404 builtin_sid
= dom_sid_parse_talloc(torture
, SID_BUILTIN
);
406 torture_assert_str_equal(torture
,
407 listd
[i
].netbios_name
,
409 "first domain should be 'BUILTIN'");
411 torture_assert_str_equal(torture
,
414 "BUILTIN domain should not have a dns name");
416 ok
= dom_sid_equal(builtin_sid
,
418 torture_assert(torture
, ok
, "BUILTIN domain should have S-1-5-32");
424 * TODO: verify the content of the 2nd and 3rd (in member server mode)
432 static bool torture_winbind_struct_domain_info(struct torture_context
*torture
)
435 struct torture_trust_domain
*listd
= NULL
;
438 torture_comment(torture
, "Running WINBINDD_DOMAIN_INFO (struct based)\n");
440 ok
= get_trusted_domains(torture
, &listd
);
441 torture_assert(torture
, ok
, "failed to get trust list");
443 for (i
=0; listd
&& listd
[i
].netbios_name
; i
++) {
444 torture_comment(torture
, "LIST[%u] '%s' => '%s' [%s]\n",
446 listd
[i
].netbios_name
,
448 dom_sid_string(torture
, listd
[i
].sid
));
451 for (i
=0; listd
&& listd
[i
].netbios_name
; i
++) {
452 struct winbindd_request req
;
453 struct winbindd_response rep
;
455 char *flagstr
= talloc_strdup(torture
," ");
460 fstrcpy(req
.domain_name
, listd
[i
].netbios_name
);
462 DO_STRUCT_REQ_REP(WINBINDD_DOMAIN_INFO
, &req
, &rep
);
464 if (rep
.data
.domain_info
.primary
) {
465 flagstr
= talloc_strdup_append(flagstr
, "PR ");
468 if (rep
.data
.domain_info
.active_directory
) {
469 torture_assert(torture
,
470 strlen(rep
.data
.domain_info
.alt_name
)>0,
471 "Active Directory without DNS name");
472 flagstr
= talloc_strdup_append(flagstr
, "AD ");
475 if (rep
.data
.domain_info
.native_mode
) {
476 torture_assert(torture
,
477 rep
.data
.domain_info
.active_directory
,
478 "Native-Mode, but no Active Directory");
479 flagstr
= talloc_strdup_append(flagstr
, "NA ");
482 torture_comment(torture
, "DOMAIN[%u] '%s' => '%s' [%s] [%s]\n",
484 rep
.data
.domain_info
.name
,
485 rep
.data
.domain_info
.alt_name
,
487 rep
.data
.domain_info
.sid
);
489 sid
= dom_sid_parse_talloc(torture
, rep
.data
.domain_info
.sid
);
490 torture_assert(torture
, sid
, "Failed to parse SID");
492 ok
= dom_sid_equal(listd
[i
].sid
, sid
);
493 torture_assert(torture
, ok
, talloc_asprintf(torture
, "SID's doesn't match [%s] != [%s]",
494 dom_sid_string(torture
, listd
[i
].sid
),
495 dom_sid_string(torture
, sid
)));
497 torture_assert_str_equal(torture
,
498 rep
.data
.domain_info
.name
,
499 listd
[i
].netbios_name
,
500 "Netbios domain name doesn't match");
502 torture_assert_str_equal(torture
,
503 rep
.data
.domain_info
.alt_name
,
505 "DNS domain name doesn't match");
511 static bool torture_winbind_struct_getdcname(struct torture_context
*torture
)
514 bool strict
= torture_setting_bool(torture
, "strict mode", false);
515 const char *domain_name
= torture_setting_string(torture
,
516 "winbindd_netbios_domain",
517 lpcfg_workgroup(torture
->lp_ctx
));
518 struct torture_trust_domain
*listd
= NULL
;
519 uint32_t i
, count
= 0;
521 torture_comment(torture
, "Running WINBINDD_GETDCNAME (struct based)\n");
523 ok
= get_trusted_domains(torture
, &listd
);
524 torture_assert(torture
, ok
, "failed to get trust list");
526 for (i
=0; listd
&& listd
[i
].netbios_name
; i
++) {
527 struct winbindd_request req
;
528 struct winbindd_response rep
;
530 /* getdcname is not expected to work on "BUILTIN" or our own
532 if (strequal(listd
[i
].netbios_name
, "BUILTIN") ||
533 strequal(listd
[i
].netbios_name
, domain_name
)) {
540 fstrcpy(req
.domain_name
, listd
[i
].netbios_name
);
543 DO_STRUCT_REQ_REP_EXT(WINBINDD_GETDCNAME
, &req
, &rep
,
545 (i
<2 || strict
), ok
= false,
546 talloc_asprintf(torture
, "DOMAIN '%s'",
550 /* TODO: check rep.data.dc_name; */
551 torture_comment(torture
, "DOMAIN '%s' => DCNAME '%s'\n",
552 req
.domain_name
, rep
.data
.dc_name
);
557 torture_assert(torture
, count
> 0,
558 "WiNBINDD_GETDCNAME was not tested");
563 static bool torture_winbind_struct_dsgetdcname(struct torture_context
*torture
)
566 bool strict
= torture_setting_bool(torture
, "strict mode", false);
567 struct torture_trust_domain
*listd
= NULL
;
571 torture_comment(torture
, "Running WINBINDD_DSGETDCNAME (struct based)\n");
573 ok
= get_trusted_domains(torture
, &listd
);
574 torture_assert(torture
, ok
, "failed to get trust list");
576 for (i
=0; listd
&& listd
[i
].netbios_name
; i
++) {
577 struct winbindd_request req
;
578 struct winbindd_response rep
;
583 if (strlen(listd
[i
].dns_name
) == 0) continue;
586 * TODO: remove this and let winbindd give no dns name
589 if (strcmp(listd
[i
].dns_name
, listd
[i
].netbios_name
) == 0) {
593 fstrcpy(req
.domain_name
, listd
[i
].dns_name
);
595 /* TODO: test more flag combinations */
596 req
.flags
= DS_DIRECTORY_SERVICE_REQUIRED
;
599 DO_STRUCT_REQ_REP_EXT(WINBINDD_DSGETDCNAME
, &req
, &rep
,
602 talloc_asprintf(torture
, "DOMAIN '%s'",
606 /* TODO: check rep.data.dc_name; */
607 torture_comment(torture
, "DOMAIN '%s' => DCNAME '%s'\n",
608 req
.domain_name
, rep
.data
.dc_name
);
614 torture_warning(torture
, "WINBINDD_DSGETDCNAME"
615 " was not tested with %d non-AD domains",
620 torture_assert(torture
, count
> 0,
621 "WiNBINDD_DSGETDCNAME was not tested");
627 static bool get_user_list(struct torture_context
*torture
, char ***users
)
629 struct winbindd_request req
;
630 struct winbindd_response rep
;
634 const char *extra_data
;
639 DO_STRUCT_REQ_REP(WINBINDD_LIST_USERS
, &req
, &rep
);
641 extra_data
= (char *)rep
.extra_data
.data
;
642 torture_assert(torture
, extra_data
, "NULL extra data");
645 next_token(&extra_data
, name
, ",", sizeof(name
));
648 u
= talloc_realloc(torture
, u
, char *, count
+ 2);
650 u
[count
] = talloc_strdup(u
, name
);
653 SAFE_FREE(rep
.extra_data
.data
);
659 static bool torture_winbind_struct_list_users(struct torture_context
*torture
)
665 torture_comment(torture
, "Running WINBINDD_LIST_USERS (struct based)\n");
667 ok
= get_user_list(torture
, &users
);
668 torture_assert(torture
, ok
, "failed to get user list");
670 for (count
= 0; users
[count
]; count
++) { }
672 torture_comment(torture
, "got %d users\n", count
);
677 static bool get_group_list(struct torture_context
*torture
,
678 unsigned int *num_entries
,
681 struct winbindd_request req
;
682 struct winbindd_response rep
;
686 const char *extra_data
;
691 DO_STRUCT_REQ_REP(WINBINDD_LIST_GROUPS
, &req
, &rep
);
692 extra_data
= (char *)rep
.extra_data
.data
;
694 *num_entries
= rep
.data
.num_entries
;
696 if (*num_entries
== 0) {
697 torture_assert(torture
, extra_data
== NULL
,
698 "extra data is null for >0 reported entries\n");
703 torture_assert(torture
, extra_data
, "NULL extra data");
706 next_token(&extra_data
, name
, ",", sizeof(name
));
709 g
= talloc_realloc(torture
, g
, char *, count
+ 2);
711 g
[count
] = talloc_strdup(g
, name
);
714 SAFE_FREE(rep
.extra_data
.data
);
716 torture_assert_int_equal(torture
, *num_entries
, count
,
717 "Wrong number of group entries reported.");
723 static bool torture_winbind_struct_list_groups(struct torture_context
*torture
)
729 torture_comment(torture
, "Running WINBINDD_LIST_GROUPS (struct based)\n");
731 ok
= get_group_list(torture
, &count
, &groups
);
732 torture_assert(torture
, ok
, "failed to get group list");
734 torture_comment(torture
, "got %d groups\n", count
);
739 struct torture_domain_sequence
{
740 const char *netbios_name
;
744 static bool get_sequence_numbers(struct torture_context
*torture
,
745 struct torture_domain_sequence
**seqs
)
747 struct winbindd_request req
;
748 struct winbindd_response rep
;
749 const char *extra_data
;
752 struct torture_domain_sequence
*s
= NULL
;
757 DO_STRUCT_REQ_REP(WINBINDD_SHOW_SEQUENCE
, &req
, &rep
);
759 extra_data
= (char *)rep
.extra_data
.data
;
760 torture_assert(torture
, extra_data
, "NULL sequence list");
762 while (next_token(&extra_data
, line
, "\n", sizeof(line
))) {
766 s
= talloc_realloc(torture
, s
, struct torture_domain_sequence
,
768 ZERO_STRUCT(s
[count
+1]);
772 torture_assert(torture
, p
, "invalid line format");
774 s
[count
].netbios_name
= talloc_strdup(s
, lp
);
777 torture_assert(torture
, strncmp(lp
, ": ", 2) == 0,
778 "invalid line format");
780 if (strcmp(lp
, "DISCONNECTED") == 0) {
783 seq
= (uint32_t)strtol(lp
, &p
, 10);
784 torture_assert(torture
, (*p
== '\0'),
785 "invalid line format");
786 torture_assert(torture
, (seq
!= (uint32_t)-1),
787 "sequence number -1 encountered");
793 SAFE_FREE(rep
.extra_data
.data
);
795 torture_assert(torture
, count
>= 2, "The list of domain sequence "
796 "numbers should contain 2 entries");
802 static bool torture_winbind_struct_show_sequence(struct torture_context
*torture
)
806 struct torture_trust_domain
*domlist
= NULL
;
807 struct torture_domain_sequence
*s
= NULL
;
809 torture_comment(torture
, "Running WINBINDD_SHOW_SEQUENCE (struct based)\n");
811 ok
= get_sequence_numbers(torture
, &s
);
812 torture_assert(torture
, ok
, "failed to get list of sequence numbers");
814 ok
= get_trusted_domains(torture
, &domlist
);
815 torture_assert(torture
, ok
, "failed to get trust list");
817 for (i
=0; domlist
[i
].netbios_name
; i
++) {
818 struct winbindd_request req
;
819 struct winbindd_response rep
;
822 torture_assert(torture
, s
[i
].netbios_name
,
823 "more domains received in second run");
824 torture_assert_str_equal(torture
, domlist
[i
].netbios_name
,
826 "inconsistent order of domain lists");
830 fstrcpy(req
.domain_name
, domlist
[i
].netbios_name
);
833 DO_STRUCT_REQ_REP_EXT(WINBINDD_SHOW_SEQUENCE
, &req
, &rep
,
836 "WINBINDD_SHOW_SEQUENCE");
838 torture_warning(torture
,
839 "WINBINDD_SHOW_SEQUENCE on "
840 "domain %s failed\n",
844 * Only fail for the first two domain that we
845 * check specially below, otherwise we fail on
846 * trusts generated by the LSA torture test
847 * that do not really exist.
851 * Do not confirm the sequence numbers
857 torture_comment(torture
,
858 "Full trust list for "
859 "WINBINDD_SHOW_SEQUENCE "
861 for (i
=0; domlist
[i
].netbios_name
; i
++) {
862 torture_comment(torture
,
864 domlist
[i
].netbios_name
);
870 seq
= rep
.data
.sequence_number
;
873 torture_assert(torture
, (seq
!= (uint32_t)-1),
874 "BUILTIN domain disconnected");
876 torture_assert(torture
, (seq
!= (uint32_t)-1),
877 "local domain disconnected");
881 if (seq
== (uint32_t)-1) {
882 torture_comment(torture
, " * %s : DISCONNECTED\n",
885 torture_comment(torture
, " * %s : %d\n",
886 req
.domain_name
, seq
);
888 torture_assert(torture
, (seq
>= s
[i
].seq
),
889 "illegal sequence number encountered");
895 static bool torture_winbind_struct_setpwent(struct torture_context
*torture
)
897 struct winbindd_request req
;
898 struct winbindd_response rep
;
900 torture_comment(torture
, "Running WINBINDD_SETPWENT (struct based)\n");
905 DO_STRUCT_REQ_REP(WINBINDD_SETPWENT
, &req
, &rep
);
910 static bool torture_winbind_struct_getpwent(struct torture_context
*torture
)
912 struct winbindd_request req
;
913 struct winbindd_response rep
;
914 struct winbindd_pw
*pwent
;
916 torture_comment(torture
, "Running WINBINDD_GETPWENT (struct based)\n");
918 torture_comment(torture
, " - Running WINBINDD_SETPWENT first\n");
921 DO_STRUCT_REQ_REP(WINBINDD_SETPWENT
, &req
, &rep
);
923 torture_comment(torture
, " - Running WINBINDD_GETPWENT now\n");
926 req
.data
.num_entries
= 1;
927 if (torture_setting_bool(torture
, "samba3", false)) {
928 DO_STRUCT_REQ_REP_EXT(WINBINDD_GETPWENT
, &req
, &rep
,
929 NSS_STATUS_SUCCESS
, false, _STRUCT_NOOP
,
932 DO_STRUCT_REQ_REP(WINBINDD_GETPWENT
, &req
, &rep
);
934 pwent
= (struct winbindd_pw
*)rep
.extra_data
.data
;
935 if (!torture_setting_bool(torture
, "samba3", false)) {
936 torture_assert(torture
, (pwent
!= NULL
), "NULL pwent");
939 torture_comment(torture
, "name: %s, uid: %d, gid: %d, shell: %s\n",
940 pwent
->pw_name
, pwent
->pw_uid
, pwent
->pw_gid
,
947 static bool torture_winbind_struct_endpwent(struct torture_context
*torture
)
949 struct winbindd_request req
;
950 struct winbindd_response rep
;
952 torture_comment(torture
, "Running WINBINDD_ENDPWENT (struct based)\n");
957 DO_STRUCT_REQ_REP(WINBINDD_ENDPWENT
, &req
, &rep
);
962 /* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
963 form DOMAIN/user into a domain and a user */
965 static bool parse_domain_user(struct torture_context
*torture
,
966 const char *domuser
, fstring domain
,
969 char *p
= strchr(domuser
, winbind_separator(torture
));
973 /* Maybe it was a UPN? */
974 if ((p
= strchr(domuser
, '@')) != NULL
) {
976 fstrcpy(user
, domuser
);
980 fstrcpy(user
, domuser
);
981 get_winbind_domain(torture
, &dom
);
982 fstrcpy(domain
, dom
);
987 fstrcpy(domain
, domuser
);
988 domain
[PTR_DIFF(p
, domuser
)] = 0;
993 static bool lookup_name_sid_list(struct torture_context
*torture
, char **list
)
997 for (count
= 0; list
[count
]; count
++) {
998 struct winbindd_request req
;
999 struct winbindd_response rep
;
1002 const char *domain_name
= torture_setting_string(torture
,
1003 "winbindd_domain_without_prefix",
1009 parse_domain_user(torture
, list
[count
], req
.data
.name
.dom_name
,
1010 req
.data
.name
.name
);
1012 DO_STRUCT_REQ_REP(WINBINDD_LOOKUPNAME
, &req
, &rep
);
1014 sid
= talloc_strdup(torture
, rep
.data
.sid
.sid
);
1019 fstrcpy(req
.data
.sid
, sid
);
1021 DO_STRUCT_REQ_REP(WINBINDD_LOOKUPSID
, &req
, &rep
);
1023 if (domain_name
!= NULL
&&
1024 strequal(rep
.data
.name
.dom_name
, domain_name
))
1026 name
= talloc_asprintf(torture
, "%s",
1027 rep
.data
.name
.name
);
1029 name
= talloc_asprintf(torture
, "%s%c%s",
1030 rep
.data
.name
.dom_name
,
1031 winbind_separator(torture
),
1032 rep
.data
.name
.name
);
1035 torture_assert_casestr_equal(torture
, list
[count
], name
,
1036 "LOOKUP_SID after LOOKUP_NAME != id");
1039 torture_comment(torture
, " %s -> %s -> %s\n", list
[count
],
1050 static bool name_is_in_list(const char *name
, char **list
)
1054 for (count
= 0; list
&& list
[count
]; count
++) {
1055 if (strequal(name
, list
[count
])) {
1062 static bool torture_winbind_struct_lookup_name_sid(struct torture_context
*torture
)
1064 struct winbindd_request req
;
1065 struct winbindd_response rep
;
1066 const char *invalid_sid
= "S-0-0-7";
1067 char *domain
= NULL
;
1068 const char *invalid_user
= "no one";
1070 bool strict
= torture_setting_bool(torture
, "strict mode", false);
1073 uint32_t count
, num_groups
;
1076 torture_comment(torture
, "Running WINBINDD_LOOKUP_NAME_SID (struct based)\n");
1078 ok
= get_user_list(torture
, &users
);
1079 torture_assert(torture
, ok
, "failed to retrieve list of users");
1080 lookup_name_sid_list(torture
, users
);
1082 ok
= get_group_list(torture
, &num_groups
, &groups
);
1083 torture_assert(torture
, ok
, "failed to retrieve list of groups");
1084 if (num_groups
> 0) {
1085 lookup_name_sid_list(torture
, groups
);
1091 fstrcpy(req
.data
.sid
, invalid_sid
);
1094 DO_STRUCT_REQ_REP_EXT(WINBINDD_LOOKUPSID
, &req
, &rep
,
1095 NSS_STATUS_NOTFOUND
,
1098 talloc_asprintf(torture
,
1099 "invalid sid %s was resolved",
1105 /* try to find an invalid name... */
1108 get_winbind_domain(torture
, &domain
);
1111 invalid_name
= talloc_asprintf(torture
, "%s/%s%u",
1113 invalid_user
, count
);
1114 } while(name_is_in_list(invalid_name
, users
) ||
1115 name_is_in_list(invalid_name
, groups
));
1117 fstrcpy(req
.data
.name
.dom_name
, domain
);
1118 fstrcpy(req
.data
.name
.name
,
1119 talloc_asprintf(torture
, "%s%u", invalid_user
,
1123 DO_STRUCT_REQ_REP_EXT(WINBINDD_LOOKUPNAME
, &req
, &rep
,
1124 NSS_STATUS_NOTFOUND
,
1127 talloc_asprintf(torture
,
1128 "invalid name %s was resolved",
1132 talloc_free(groups
);
1137 static bool torture_winbind_struct_lookup_sids_invalid(
1138 struct torture_context
*torture
)
1140 struct winbindd_request req
= {0};
1141 struct winbindd_response rep
= {0};
1142 bool strict
= torture_setting_bool(torture
, "strict mode", false);
1145 torture_comment(torture
,
1146 "Running WINBINDD_LOOKUP_SIDS (struct based)\n");
1149 DO_STRUCT_REQ_REP_EXT(WINBINDD_LOOKUPSIDS
, &req
, &rep
,
1150 NSS_STATUS_NOTFOUND
,
1155 "invalid lookupsids succeeded"));
1160 struct torture_suite
*torture_winbind_struct_init(TALLOC_CTX
*ctx
)
1162 struct torture_suite
*suite
= torture_suite_create(ctx
, "struct");
1164 torture_suite_add_simple_test(suite
, "interface_version", torture_winbind_struct_interface_version
);
1165 torture_suite_add_simple_test(suite
, "ping", torture_winbind_struct_ping
);
1166 torture_suite_add_simple_test(suite
, "info", torture_winbind_struct_info
);
1167 torture_suite_add_simple_test(suite
, "priv_pipe_dir", torture_winbind_struct_priv_pipe_dir
);
1168 torture_suite_add_simple_test(suite
, "netbios_name", torture_winbind_struct_netbios_name
);
1169 torture_suite_add_simple_test(suite
, "domain_name", torture_winbind_struct_domain_name
);
1170 torture_suite_add_simple_test(suite
, "check_machacc", torture_winbind_struct_check_machacc
);
1171 torture_suite_add_simple_test(suite
, "list_trustdom", torture_winbind_struct_list_trustdom
);
1172 torture_suite_add_simple_test(suite
, "domain_info", torture_winbind_struct_domain_info
);
1173 torture_suite_add_simple_test(suite
, "getdcname", torture_winbind_struct_getdcname
);
1174 torture_suite_add_simple_test(suite
, "dsgetdcname", torture_winbind_struct_dsgetdcname
);
1175 torture_suite_add_simple_test(suite
, "list_users", torture_winbind_struct_list_users
);
1176 torture_suite_add_simple_test(suite
, "list_groups", torture_winbind_struct_list_groups
);
1177 torture_suite_add_simple_test(suite
, "show_sequence", torture_winbind_struct_show_sequence
);
1178 torture_suite_add_simple_test(suite
, "setpwent", torture_winbind_struct_setpwent
);
1179 torture_suite_add_simple_test(suite
, "getpwent", torture_winbind_struct_getpwent
);
1180 torture_suite_add_simple_test(suite
, "endpwent", torture_winbind_struct_endpwent
);
1181 torture_suite_add_simple_test(suite
, "lookup_name_sid", torture_winbind_struct_lookup_name_sid
);
1182 torture_suite_add_simple_test(
1184 "lookup_sids_invalid",
1185 torture_winbind_struct_lookup_sids_invalid
);
1187 suite
->description
= talloc_strdup(suite
, "WINBIND - struct based protocol tests");