subunit: Support formatting compatible with upstream subunit, for consistency.
[kai/samba-autobuild/.git] / source4 / torture / rpc / wkssvc.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for wkssvc rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Günther Deschner 2007
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
25 #include "torture/rpc/rpc.h"
26 #include "lib/cmdline/popt_common.h"
27 #include "param/param.h"
28 #include "../lib/crypto/crypto.h"
29 #include "libcli/auth/libcli_auth.h"
30
31 #define SMBTORTURE_MACHINE_NAME "smbtrt_name"
32 #define SMBTORTURE_ALTERNATE_NAME "smbtrt_altname"
33 #define SMBTORTURE_TRANSPORT_NAME "\\Device\\smbtrt_transport_name"
34 #define SMBTORTURE_USE_NAME "S:"
35 #define SMBTORTURE_MESSAGE "You are currently tortured by Samba"
36
37 static bool test_NetWkstaGetInfo(struct torture_context *tctx,
38                                  struct dcerpc_pipe *p)
39 {
40         NTSTATUS status;
41         struct wkssvc_NetWkstaGetInfo r;
42         union wkssvc_NetWkstaInfo info;
43         uint16_t levels[] = {100, 101, 102, 502};
44         int i;
45         struct dcerpc_binding_handle *b = p->binding_handle;
46
47         r.in.server_name = dcerpc_server_name(p);
48         r.out.info = &info;
49
50         for (i=0;i<ARRAY_SIZE(levels);i++) {
51                 r.in.level = levels[i];
52                 torture_comment(tctx, "Testing NetWkstaGetInfo level %u\n",
53                                 r.in.level);
54                 status = dcerpc_wkssvc_NetWkstaGetInfo_r(b, tctx, &r);
55                 torture_assert_ntstatus_ok(tctx, status,
56                         talloc_asprintf(tctx, "NetWkstaGetInfo level %u failed",
57                                         r.in.level));
58                 torture_assert_werr_ok(tctx, r.out.result,
59                         talloc_asprintf(tctx, "NetWkstaGetInfo level %u failed",
60                                         r.in.level));
61         }
62
63         return true;
64 }
65
66 static bool test_NetWkstaTransportEnum(struct torture_context *tctx,
67                                        struct dcerpc_pipe *p)
68 {
69         NTSTATUS status;
70         struct wkssvc_NetWkstaTransportEnum r;
71         uint32_t resume_handle = 0;
72         struct wkssvc_NetWkstaTransportInfo info;
73         union wkssvc_NetWkstaTransportCtr ctr;
74         struct wkssvc_NetWkstaTransportCtr0 ctr0;
75         uint32_t total_entries = 0;
76         struct dcerpc_binding_handle *b = p->binding_handle;
77
78         ZERO_STRUCT(ctr0);
79         ctr.ctr0 = &ctr0;
80
81         info.level = 0;
82         info.ctr = ctr;
83
84         r.in.server_name = dcerpc_server_name(p);
85         r.in.info = &info;
86         r.in.max_buffer = (uint32_t)-1;
87         r.in.resume_handle = &resume_handle;
88         r.out.total_entries = &total_entries;
89         r.out.info = &info;
90         r.out.resume_handle = &resume_handle;
91
92         torture_comment(tctx, "Testing NetWkstaTransportEnum level 0\n");
93
94         status = dcerpc_wkssvc_NetWkstaTransportEnum_r(b, tctx, &r);
95         torture_assert_ntstatus_ok(tctx, status,
96                                    "NetWkstaTransportEnum failed");
97         torture_assert_werr_ok(tctx, r.out.result, talloc_asprintf(tctx,
98                                "NetWkstaTransportEnum level %u failed",
99                                info.level));
100
101         return true;
102 }
103
104 static bool test_NetrWkstaTransportAdd(struct torture_context *tctx,
105                                        struct dcerpc_pipe *p)
106 {
107         NTSTATUS status;
108         struct wkssvc_NetrWkstaTransportAdd r;
109         struct wkssvc_NetWkstaTransportInfo0 info0;
110         uint32_t parm_err = 0;
111         struct dcerpc_binding_handle *b = p->binding_handle;
112
113         ZERO_STRUCT(info0);
114
115         info0.quality_of_service = 0xffff;
116         info0.vc_count = 0;
117         info0.name = SMBTORTURE_TRANSPORT_NAME;
118         info0.address = "000000000000";
119         info0.wan_link = 0x400;
120
121         r.in.server_name = dcerpc_server_name(p);
122         r.in.level = 0;
123         r.in.info0 = &info0;
124         r.in.parm_err = r.out.parm_err = &parm_err;
125
126         torture_comment(tctx, "Testing NetrWkstaTransportAdd level 0\n");
127
128         status = dcerpc_wkssvc_NetrWkstaTransportAdd_r(b, tctx, &r);
129         torture_assert_ntstatus_ok(tctx, status,
130                                    "NetrWkstaTransportAdd failed");
131         torture_assert_werr_equal(tctx, r.out.result,
132                                   WERR_INVALID_PARAM,
133                                   "NetrWkstaTransportAdd level 0 failed");
134
135         return true;
136 }
137
138 static bool test_NetrWkstaTransportDel(struct torture_context *tctx,
139                                        struct dcerpc_pipe *p)
140 {
141         NTSTATUS status;
142         struct wkssvc_NetrWkstaTransportDel r;
143         struct dcerpc_binding_handle *b = p->binding_handle;
144
145         r.in.server_name = dcerpc_server_name(p);
146         r.in.transport_name = SMBTORTURE_TRANSPORT_NAME;
147         r.in.unknown3 = 0;
148
149         torture_comment(tctx, "Testing NetrWkstaTransportDel\n");
150
151         status = dcerpc_wkssvc_NetrWkstaTransportDel_r(b, tctx, &r);
152         torture_assert_ntstatus_ok(tctx, status,
153                                    "NetrWkstaTransportDel failed");
154         torture_assert_werr_ok(tctx, r.out.result,
155                                "NetrWkstaTransportDel");
156
157         return true;
158 }
159
160 static bool test_NetWkstaEnumUsers(struct torture_context *tctx,
161                                    struct dcerpc_pipe *p)
162 {
163         NTSTATUS status;
164         struct wkssvc_NetWkstaEnumUsers r;
165         uint32_t handle = 0;
166         uint32_t entries_read = 0;
167         struct wkssvc_NetWkstaEnumUsersInfo info;
168         struct wkssvc_NetWkstaEnumUsersCtr0 *user0;
169         struct wkssvc_NetWkstaEnumUsersCtr1 *user1;
170         uint32_t levels[] = { 0, 1 };
171         int i;
172         struct dcerpc_binding_handle *b = p->binding_handle;
173
174         for (i=0; i<ARRAY_SIZE(levels); i++) {
175
176                 ZERO_STRUCT(info);
177
178                 info.level = levels[i];
179                 switch (info.level) {
180                 case 0:
181                         user0 = talloc_zero(tctx,
182                                             struct wkssvc_NetWkstaEnumUsersCtr0);
183                         info.ctr.user0 = user0;
184                         break;
185                 case 1:
186                         user1 = talloc_zero(tctx,
187                                             struct wkssvc_NetWkstaEnumUsersCtr1);
188                         info.ctr.user1 = user1;
189                         break;
190                 default:
191                         break;
192                 }
193
194                 r.in.server_name = dcerpc_server_name(p);
195                 r.in.prefmaxlen = (uint32_t)-1;
196                 r.in.info = r.out.info = &info;
197                 r.in.resume_handle = r.out.resume_handle = &handle;
198
199                 r.out.entries_read = &entries_read;
200
201                 torture_comment(tctx, "Testing NetWkstaEnumUsers level %u\n",
202                                 levels[i]);
203
204                 status = dcerpc_wkssvc_NetWkstaEnumUsers_r(b, tctx, &r);
205                 torture_assert_ntstatus_ok(tctx, status,
206                                            "NetWkstaEnumUsers failed");
207                 torture_assert_werr_ok(tctx, r.out.result,
208                                        "NetWkstaEnumUsers failed");
209         }
210
211         return true;
212 }
213
214 static bool test_NetrWkstaUserGetInfo(struct torture_context *tctx,
215                                       struct dcerpc_pipe *p)
216 {
217         NTSTATUS status;
218         struct wkssvc_NetrWkstaUserGetInfo r;
219         union wkssvc_NetrWkstaUserInfo info;
220         const char *dom = lp_workgroup(tctx->lp_ctx);
221         struct cli_credentials *creds = cmdline_credentials;
222         const char *user = cli_credentials_get_username(creds);
223         int i;
224         struct dcerpc_binding_handle *b = p->binding_handle;
225
226         const struct {
227                 const char *unknown;
228                 uint32_t level;
229                 WERROR result;
230         } tests[] = {
231                 { NULL, 0, WERR_NO_SUCH_LOGON_SESSION },
232                 { NULL, 1, WERR_NO_SUCH_LOGON_SESSION },
233                 { NULL, 1101, WERR_OK },
234                 { dom, 0, WERR_INVALID_PARAM },
235                 { dom, 1, WERR_INVALID_PARAM },
236                 { dom, 1101, WERR_INVALID_PARAM },
237                 { user, 0, WERR_INVALID_PARAM },
238                 { user, 1, WERR_INVALID_PARAM },
239                 { user, 1101, WERR_INVALID_PARAM },
240         };
241
242         for (i=0; i<ARRAY_SIZE(tests); i++) {
243                 r.in.unknown = tests[i].unknown;
244                 r.in.level = tests[i].level;
245                 r.out.info = &info;
246
247                 torture_comment(tctx, "Testing NetrWkstaUserGetInfo level %u\n",
248                                 r.in.level);
249
250                 status = dcerpc_wkssvc_NetrWkstaUserGetInfo_r(b, tctx, &r);
251                 torture_assert_ntstatus_ok(tctx, status,
252                                            "NetrWkstaUserGetInfo failed");
253                 torture_assert_werr_equal(tctx, r.out.result,
254                                           tests[i].result,
255                                           "NetrWkstaUserGetInfo failed");
256         }
257
258         return true;
259 }
260
261 static bool test_NetrUseEnum(struct torture_context *tctx,
262                              struct dcerpc_pipe *p)
263 {
264         NTSTATUS status;
265         struct wkssvc_NetrUseEnum r;
266         uint32_t handle = 0;
267         uint32_t entries_read = 0;
268         struct wkssvc_NetrUseEnumInfo info;
269         struct wkssvc_NetrUseEnumCtr0 *use0;
270         struct wkssvc_NetrUseEnumCtr1 *use1;
271         struct wkssvc_NetrUseEnumCtr2 *use2;
272         uint32_t levels[] = { 0, 1, 2 };
273         int i;
274         struct dcerpc_binding_handle *b = p->binding_handle;
275
276         for (i=0; i<ARRAY_SIZE(levels); i++) {
277
278                 ZERO_STRUCT(info);
279
280                 info.level = levels[i];
281                 switch (info.level) {
282                 case 0:
283                         use0 = talloc_zero(tctx, struct wkssvc_NetrUseEnumCtr0);
284                         info.ctr.ctr0 = use0;
285                         break;
286                 case 1:
287                         use1 = talloc_zero(tctx, struct wkssvc_NetrUseEnumCtr1);
288                         info.ctr.ctr1 = use1;
289                         break;
290                 case 2:
291                         use2 = talloc_zero(tctx, struct wkssvc_NetrUseEnumCtr2);
292                         info.ctr.ctr2 = use2;
293                         break;
294                 default:
295                         break;
296                 }
297
298                 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
299                 r.in.prefmaxlen = (uint32_t)-1;
300                 r.in.info = r.out.info = &info;
301                 r.in.resume_handle = r.out.resume_handle = &handle;
302
303                 r.out.entries_read = &entries_read;
304
305                 torture_comment(tctx, "Testing NetrUseEnum level %u\n",
306                                 levels[i]);
307
308                 status = dcerpc_wkssvc_NetrUseEnum_r(b, tctx, &r);
309                 torture_assert_ntstatus_ok(tctx, status,
310                                            "NetrUseEnum failed");
311                 torture_assert_werr_ok(tctx, r.out.result,
312                                        "NetrUseEnum failed");
313         }
314
315         return true;
316 }
317
318 static bool test_NetrUseAdd(struct torture_context *tctx,
319                             struct dcerpc_pipe *p)
320 {
321         NTSTATUS status;
322         struct wkssvc_NetrUseAdd r;
323         struct wkssvc_NetrUseInfo0 info0;
324         struct wkssvc_NetrUseInfo1 info1;
325         union wkssvc_NetrUseGetInfoCtr *ctr;
326         uint32_t parm_err = 0;
327         struct dcerpc_binding_handle *b = p->binding_handle;
328
329         ctr = talloc(tctx, union wkssvc_NetrUseGetInfoCtr);
330
331         ZERO_STRUCT(info0);
332
333         info0.local = SMBTORTURE_USE_NAME;
334         info0.remote = "\\\\localhost\\c$";
335
336         ctr->info0 = &info0;
337
338         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
339         r.in.level = 0;
340         r.in.ctr = ctr;
341         r.in.parm_err = r.out.parm_err = &parm_err;
342
343         torture_comment(tctx, "Testing NetrUseAdd level %u\n",
344                         r.in.level);
345
346         status = dcerpc_wkssvc_NetrUseAdd_r(b, tctx, &r);
347         torture_assert_ntstatus_ok(tctx, status,
348                                    "NetrUseAdd failed");
349         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
350                                "NetrUseAdd failed");
351
352         ZERO_STRUCT(r);
353         ZERO_STRUCT(info1);
354
355         info1.local = SMBTORTURE_USE_NAME;
356         info1.remote = "\\\\localhost\\sysvol";
357         info1.password = NULL;
358
359         ctr->info1 = &info1;
360
361         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
362         r.in.level = 1;
363         r.in.ctr = ctr;
364         r.in.parm_err = r.out.parm_err = &parm_err;
365
366         torture_comment(tctx, "Testing NetrUseAdd level %u\n",
367                         r.in.level);
368
369         status = dcerpc_wkssvc_NetrUseAdd_r(b, tctx, &r);
370         torture_assert_ntstatus_ok(tctx, status,
371                                    "NetrUseAdd failed");
372         torture_assert_werr_ok(tctx, r.out.result,
373                                "NetrUseAdd failed");
374
375         return true;
376 }
377
378 static bool test_NetrUseDel(struct torture_context *tctx,
379                             struct dcerpc_pipe *p)
380 {
381         NTSTATUS status;
382         struct wkssvc_NetrUseDel r;
383         struct dcerpc_binding_handle *b = p->binding_handle;
384
385         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
386         r.in.use_name = SMBTORTURE_USE_NAME;
387         r.in.force_cond = 0;
388
389         torture_comment(tctx, "Testing NetrUseDel\n");
390
391         status = dcerpc_wkssvc_NetrUseDel_r(b, tctx, &r);
392         torture_assert_ntstatus_ok(tctx, status,
393                                    "NetrUseDel failed");
394         torture_assert_werr_ok(tctx, r.out.result,
395                                "NetrUseDel failed");
396         return true;
397 }
398
399 static bool test_NetrUseGetInfo_level(struct torture_context *tctx,
400                                       struct dcerpc_pipe *p,
401                                       const char *use_name,
402                                       uint32_t level,
403                                       WERROR werr)
404 {
405         NTSTATUS status;
406         struct wkssvc_NetrUseGetInfo r;
407         union wkssvc_NetrUseGetInfoCtr ctr;
408         struct dcerpc_binding_handle *b = p->binding_handle;
409
410         ZERO_STRUCT(ctr);
411
412         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
413         r.in.use_name = use_name;
414         r.in.level = level;
415         r.out.ctr = &ctr;
416         status = dcerpc_wkssvc_NetrUseGetInfo_r(b, tctx, &r);
417
418         torture_assert_ntstatus_ok(tctx, status,
419                                    "NetrUseGetInfo failed");
420         torture_assert_werr_equal(tctx, r.out.result, werr,
421                                   "NetrUseGetInfo failed");
422         return true;
423 }
424
425 static bool test_NetrUseGetInfo(struct torture_context *tctx,
426                                 struct dcerpc_pipe *p)
427 {
428         NTSTATUS status;
429         struct wkssvc_NetrUseEnum r;
430         uint32_t handle = 0;
431         uint32_t entries_read = 0;
432         struct wkssvc_NetrUseEnumInfo info;
433         struct wkssvc_NetrUseEnumCtr0 *use0;
434         uint32_t levels[] = { 0, 1, 2 };
435         const char *use_name = NULL;
436         int i, k;
437         struct dcerpc_binding_handle *b = p->binding_handle;
438
439         ZERO_STRUCT(info);
440
441         info.level = 0;
442         use0 = talloc_zero(tctx, struct wkssvc_NetrUseEnumCtr0);
443         info.ctr.ctr0 = use0;
444
445         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
446         r.in.prefmaxlen = (uint32_t)-1;
447         r.in.info = r.out.info = &info;
448         r.in.resume_handle = r.out.resume_handle = &handle;
449         r.out.entries_read = &entries_read;
450
451         status = dcerpc_wkssvc_NetrUseEnum_r(b, tctx, &r);
452         torture_assert_ntstatus_ok(tctx, status,
453                                    "NetrUseEnum failed");
454         torture_assert_werr_ok(tctx, r.out.result,
455                                "NetrUseEnum failed");
456
457         for (k=0; k < r.out.info->ctr.ctr0->count; k++) {
458
459                 use_name = r.out.info->ctr.ctr0->array[k].local;
460
461                 for (i=0; i<ARRAY_SIZE(levels); i++) {
462
463                         if (!test_NetrUseGetInfo_level(tctx, p, use_name,
464                                                        levels[i],
465                                                        WERR_OK))
466                         {
467                                 if (levels[i] != 0) {
468                                         return false;
469                                 }
470                         }
471                 }
472
473                 use_name = r.out.info->ctr.ctr0->array[k].remote;
474
475                 for (i=0; i<ARRAY_SIZE(levels); i++) {
476
477                         if (!test_NetrUseGetInfo_level(tctx, p, use_name,
478                                                        levels[i],
479                                                        WERR_NOT_CONNECTED))
480                         {
481                                 if (levels[i] != 0) {
482                                         return false;
483                                 }
484                         }
485                 }
486         }
487
488         return true;
489 }
490
491 static bool test_NetrLogonDomainNameAdd(struct torture_context *tctx,
492                                         struct dcerpc_pipe *p)
493 {
494         NTSTATUS status;
495         struct wkssvc_NetrLogonDomainNameAdd r;
496         struct dcerpc_binding_handle *b = p->binding_handle;
497
498         r.in.domain_name = lp_workgroup(tctx->lp_ctx);
499
500         torture_comment(tctx, "Testing NetrLogonDomainNameAdd\n");
501
502         status = dcerpc_wkssvc_NetrLogonDomainNameAdd_r(b, tctx, &r);
503         torture_assert_ntstatus_ok(tctx, status,
504                                    "NetrLogonDomainNameAdd failed");
505         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
506                                   "NetrLogonDomainNameAdd failed");
507         return true;
508 }
509
510 static bool test_NetrLogonDomainNameDel(struct torture_context *tctx,
511                                         struct dcerpc_pipe *p)
512 {
513         NTSTATUS status;
514         struct wkssvc_NetrLogonDomainNameDel r;
515         struct dcerpc_binding_handle *b = p->binding_handle;
516
517         r.in.domain_name = lp_workgroup(tctx->lp_ctx);
518
519         torture_comment(tctx, "Testing NetrLogonDomainNameDel\n");
520
521         status = dcerpc_wkssvc_NetrLogonDomainNameDel_r(b, tctx, &r);
522         torture_assert_ntstatus_ok(tctx, status,
523                                    "NetrLogonDomainNameDel failed");
524         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
525                                   "NetrLogonDomainNameDel failed");
526         return true;
527 }
528
529 static bool test_NetrEnumerateComputerNames_level(struct torture_context *tctx,
530                                                   struct dcerpc_pipe *p,
531                                                   uint16_t level,
532                                                   const char ***names,
533                                                   int *num_names)
534 {
535         NTSTATUS status;
536         struct wkssvc_NetrEnumerateComputerNames r;
537         struct wkssvc_ComputerNamesCtr *ctr;
538         int i;
539         struct dcerpc_binding_handle *b = p->binding_handle;
540
541         ctr = talloc_zero(tctx, struct wkssvc_ComputerNamesCtr);
542
543         r.in.server_name = dcerpc_server_name(p);
544         r.in.name_type = level;
545         r.in.Reserved = 0;
546         r.out.ctr = &ctr;
547
548         torture_comment(tctx, "Testing NetrEnumerateComputerNames level %u\n",
549                         r.in.name_type);
550
551         status = dcerpc_wkssvc_NetrEnumerateComputerNames_r(b, tctx, &r);
552         torture_assert_ntstatus_ok(tctx, status,
553                                    "NetrEnumerateComputerNames failed");
554         torture_assert_werr_ok(tctx, r.out.result,
555                                "NetrEnumerateComputerNames failed");
556
557         if ((level == NetPrimaryComputerName) && ctr->count != 1) {
558                 torture_comment(tctx,
559                                 "NetrEnumerateComputerNames did not return one "
560                                 "name but %u\n", ctr->count);
561                 return false;
562         }
563
564         if (names && num_names) {
565                 *num_names = 0;
566                 *names = NULL;
567                 for (i=0; i<ctr->count; i++) {
568                         if (!add_string_to_array(tctx,
569                                                  ctr->computer_name[i].string,
570                                                  names,
571                                                  num_names))
572                         {
573                                 return false;
574                         }
575                 }
576         }
577
578         return true;
579 }
580
581 static bool test_NetrEnumerateComputerNames(struct torture_context *tctx,
582                                             struct dcerpc_pipe *p)
583 {
584         uint16_t levels[] = {0,1,2};
585         int i;
586
587         for (i=0; i<ARRAY_SIZE(levels); i++) {
588
589                 if (!test_NetrEnumerateComputerNames_level(tctx,
590                                                            p,
591                                                            levels[i],
592                                                            NULL, NULL))
593                 {
594                         return false;
595                 }
596         }
597
598         return true;
599 }
600
601 static bool test_NetrValidateName(struct torture_context *tctx,
602                                   struct dcerpc_pipe *p)
603 {
604         NTSTATUS status;
605         struct wkssvc_NetrValidateName r;
606         uint16_t levels[] = {0,1,2,3,4,5};
607         int i;
608         struct dcerpc_binding_handle *b = p->binding_handle;
609
610         for (i=0; i<ARRAY_SIZE(levels); i++) {
611
612                 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
613                 r.in.name = lp_workgroup(tctx->lp_ctx);
614                 r.in.Account = NULL;
615                 r.in.Password = NULL;
616                 r.in.name_type = levels[i];
617
618                 torture_comment(tctx, "Testing NetrValidateName level %u\n",
619                                 r.in.name_type);
620
621                 status = dcerpc_wkssvc_NetrValidateName_r(b, tctx, &r);
622                 torture_assert_ntstatus_ok(tctx, status,
623                                            "NetrValidateName failed");
624                 torture_assert_werr_equal(tctx, r.out.result,
625                                           WERR_NOT_SUPPORTED,
626                                           "NetrValidateName failed");
627         }
628
629         return true;
630 }
631
632 static bool test_NetrValidateName2(struct torture_context *tctx,
633                                    struct dcerpc_pipe *p)
634 {
635         NTSTATUS status;
636         struct wkssvc_NetrValidateName2 r;
637         uint16_t levels[] = {0,1,2,3,4,5};
638         int i;
639         struct dcerpc_binding_handle *b = p->binding_handle;
640
641         for (i=0; i<ARRAY_SIZE(levels); i++) {
642
643                 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
644                 r.in.name = lp_workgroup(tctx->lp_ctx);
645                 r.in.Account = NULL;
646                 r.in.EncryptedPassword = NULL;
647                 r.in.name_type = levels[i];
648
649                 torture_comment(tctx, "Testing NetrValidateName2 level %u\n",
650                                 r.in.name_type);
651
652                 status = dcerpc_wkssvc_NetrValidateName2_r(b, tctx, &r);
653                 torture_assert_ntstatus_ok(tctx, status,
654                                            "NetrValidateName2 failed");
655                 torture_assert_werr_equal(tctx, r.out.result,
656                                           WERR_RPC_E_REMOTE_DISABLED,
657                                           "NetrValidateName2 failed");
658         }
659
660         return true;
661 }
662
663 static bool test_NetrAddAlternateComputerName(struct torture_context *tctx,
664                                               struct dcerpc_pipe *p)
665 {
666         NTSTATUS status;
667         struct wkssvc_NetrAddAlternateComputerName r;
668         const char **names = NULL;
669         int num_names = 0;
670         int i;
671         struct dcerpc_binding_handle *b = p->binding_handle;
672
673         r.in.server_name = dcerpc_server_name(p);
674         r.in.NewAlternateMachineName = SMBTORTURE_ALTERNATE_NAME;
675         r.in.Account = NULL;
676         r.in.EncryptedPassword = NULL;
677         r.in.Reserved = 0;
678
679         torture_comment(tctx, "Testing NetrAddAlternateComputerName\n");
680
681         status = dcerpc_wkssvc_NetrAddAlternateComputerName_r(b, tctx, &r);
682         torture_assert_ntstatus_ok(tctx, status,
683                                    "NetrAddAlternateComputerName failed");
684         torture_assert_werr_ok(tctx, r.out.result,
685                                "NetrAddAlternateComputerName failed");
686
687         if (!test_NetrEnumerateComputerNames_level(tctx, p,
688                                                    NetAlternateComputerNames,
689                                                    &names, &num_names))
690         {
691                 return false;
692         }
693
694         for (i=0; i<num_names; i++) {
695                 if (strequal(names[i], SMBTORTURE_ALTERNATE_NAME)) {
696                         return true;
697                 }
698         }
699
700         torture_comment(tctx, "new alternate name not set\n");
701
702         return false;
703 }
704
705 static bool test_NetrRemoveAlternateComputerName(struct torture_context *tctx,
706                                                  struct dcerpc_pipe *p)
707 {
708         NTSTATUS status;
709         struct wkssvc_NetrRemoveAlternateComputerName r;
710         const char **names = NULL;
711         int num_names = 0;
712         int i;
713         struct dcerpc_binding_handle *b = p->binding_handle;
714
715         r.in.server_name = dcerpc_server_name(p);
716         r.in.AlternateMachineNameToRemove = SMBTORTURE_ALTERNATE_NAME;
717         r.in.Account = NULL;
718         r.in.EncryptedPassword = NULL;
719         r.in.Reserved = 0;
720
721         torture_comment(tctx, "Testing NetrRemoveAlternateComputerName\n");
722
723         status = dcerpc_wkssvc_NetrRemoveAlternateComputerName_r(b, tctx, &r);
724         torture_assert_ntstatus_ok(tctx, status,
725                                    "NetrRemoveAlternateComputerName failed");
726         torture_assert_werr_ok(tctx, r.out.result,
727                                "NetrRemoveAlternateComputerName failed");
728
729         if (!test_NetrEnumerateComputerNames_level(tctx, p,
730                                                    NetAlternateComputerNames,
731                                                    &names, &num_names))
732         {
733                 return false;
734         }
735
736         for (i=0; i<num_names; i++) {
737                 if (strequal(names[i], SMBTORTURE_ALTERNATE_NAME)) {
738                         return false;
739                 }
740         }
741
742         return true;
743 }
744
745 static bool test_NetrSetPrimaryComputername_name(struct torture_context *tctx,
746                                                  struct dcerpc_pipe *p,
747                                                  const char *name)
748 {
749         NTSTATUS status;
750         struct wkssvc_NetrSetPrimaryComputername r;
751         struct dcerpc_binding_handle *b = p->binding_handle;
752
753         r.in.server_name = dcerpc_server_name(p);
754         r.in.primary_name = name;
755         r.in.Account = NULL;
756         r.in.EncryptedPassword = NULL;
757         r.in.Reserved = 0;
758
759         status = dcerpc_wkssvc_NetrSetPrimaryComputername_r(b, tctx, &r);
760         torture_assert_ntstatus_ok(tctx, status,
761                                    "NetrSetPrimaryComputername failed");
762         torture_assert_werr_ok(tctx, r.out.result,
763                                "NetrSetPrimaryComputername failed");
764         return true;
765 }
766
767
768 static bool test_NetrSetPrimaryComputername(struct torture_context *tctx,
769                                             struct dcerpc_pipe *p)
770 {
771         /*
772           add alternate,
773           check if there
774           store old primary
775           set new primary (alternate)
776           check if there
777           later: check if del is possible
778           set primary back to origin
779           check if there
780           del alternate
781         */
782
783         const char **names_o = NULL, **names = NULL;
784         int num_names_o = 0, num_names = 0;
785
786         torture_comment(tctx, "Testing NetrSetPrimaryComputername\n");
787
788         if (!test_NetrAddAlternateComputerName(tctx, p)) {
789                 return false;
790         }
791
792         if (!test_NetrEnumerateComputerNames_level(tctx, p,
793                                                    NetPrimaryComputerName,
794                                                    &names_o, &num_names_o))
795         {
796                 return false;
797         }
798
799         if (num_names_o != 1) {
800                 return false;
801         }
802
803         if (!test_NetrSetPrimaryComputername_name(tctx, p,
804                                                   SMBTORTURE_ALTERNATE_NAME))
805         {
806                 return false;
807         }
808
809         if (!test_NetrEnumerateComputerNames_level(tctx, p,
810                                                    NetPrimaryComputerName,
811                                                    &names, &num_names))
812         {
813                 return false;
814         }
815
816         if (num_names != 1) {
817                 return false;
818         }
819
820         if (!strequal(names[0], SMBTORTURE_ALTERNATE_NAME)) {
821                 torture_comment(tctx,
822                                 "name mismatch (%s != %s) after NetrSetPrimaryComputername!\n",
823                                 names[0], SMBTORTURE_ALTERNATE_NAME);
824                 /*return false */;
825         }
826
827         if (!test_NetrSetPrimaryComputername_name(tctx, p,
828                                                   names_o[0]))
829         {
830                 return false;
831         }
832
833         if (!test_NetrRemoveAlternateComputerName(tctx, p)) {
834                 return false;
835         }
836
837
838         return true;
839 }
840
841 static bool test_NetrRenameMachineInDomain(struct torture_context *tctx,
842                                            struct dcerpc_pipe *p)
843 {
844         NTSTATUS status;
845         struct wkssvc_NetrRenameMachineInDomain r;
846         struct dcerpc_binding_handle *b = p->binding_handle;
847
848         r.in.server_name = dcerpc_server_name(p);
849         r.in.NewMachineName = SMBTORTURE_MACHINE_NAME;
850         r.in.Account = NULL;
851         r.in.password = NULL;
852         r.in.RenameOptions = 0;
853
854         torture_comment(tctx, "Testing NetrRenameMachineInDomain\n");
855
856         status = dcerpc_wkssvc_NetrRenameMachineInDomain_r(b, tctx, &r);
857         torture_assert_ntstatus_ok(tctx, status,
858                                    "NetrRenameMachineInDomain failed");
859         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
860                                   "NetrRenameMachineInDomain failed");
861         return true;
862 }
863
864 static bool test_NetrRenameMachineInDomain2_name(struct torture_context *tctx,
865                                                  struct dcerpc_pipe *p,
866                                                  const char *new_name)
867 {
868         NTSTATUS status;
869         struct wkssvc_NetrRenameMachineInDomain2 r;
870         struct dcerpc_binding_handle *b = p->binding_handle;
871
872         r.in.server_name = dcerpc_server_name(p);
873         r.in.NewMachineName = new_name;
874         r.in.Account = NULL;
875         r.in.EncryptedPassword = NULL;
876         r.in.RenameOptions = 0;
877
878         status = dcerpc_wkssvc_NetrRenameMachineInDomain2_r(b, tctx, &r);
879         torture_assert_ntstatus_ok(tctx, status,
880                                    "NetrRenameMachineInDomain2 failed");
881         torture_assert_werr_ok(tctx, r.out.result,
882                                "NetrRenameMachineInDomain2 failed");
883         return true;
884 }
885
886 static bool test_NetrRenameMachineInDomain2(struct torture_context *tctx,
887                                             struct dcerpc_pipe *p)
888 {
889         const char **names_o = NULL, **names = NULL;
890         int num_names_o = 0, num_names = 0;
891
892         torture_comment(tctx, "Testing NetrRenameMachineInDomain2\n");
893
894         if (!test_NetrEnumerateComputerNames_level(tctx, p,
895                                                    NetPrimaryComputerName,
896                                                    &names_o, &num_names_o))
897         {
898                 return false;
899         }
900
901         if (num_names_o != 1) {
902                 return false;
903         }
904
905         if (!test_NetrRenameMachineInDomain2_name(tctx, p,
906                                                   SMBTORTURE_MACHINE_NAME))
907         {
908                 return false;
909         }
910
911         if (!test_NetrEnumerateComputerNames_level(tctx, p,
912                                                    NetPrimaryComputerName,
913                                                    &names, &num_names))
914         {
915                 return false;
916         }
917
918         if (num_names != 1) {
919                 return false;
920         }
921
922         if (strequal(names[0], names_o[0])) {
923                 test_NetrRenameMachineInDomain2_name(tctx, p, names_o[0]);
924                 return false;
925         }
926
927         if (!strequal(names[0], SMBTORTURE_MACHINE_NAME)) {
928                 test_NetrRenameMachineInDomain2_name(tctx, p, names_o[0]);
929                 return false;
930         }
931
932         if (!test_NetrRenameMachineInDomain2_name(tctx, p, names_o[0]))
933         {
934                 return false;
935         }
936
937         if (!test_NetrEnumerateComputerNames_level(tctx, p,
938                                                    NetPrimaryComputerName,
939                                                    &names, &num_names))
940         {
941                 return false;
942         }
943
944         if (num_names != 1) {
945                 return false;
946         }
947
948         if (!strequal(names[0], names_o[0])) {
949                 return false;
950         }
951
952         return true;
953 }
954
955 static bool test_NetrWorkstationStatisticsGet(struct torture_context *tctx,
956                                               struct dcerpc_pipe *p)
957 {
958         NTSTATUS status;
959         struct wkssvc_NetrWorkstationStatisticsGet r;
960         struct wkssvc_NetrWorkstationStatistics *info;
961         struct dcerpc_binding_handle *b = p->binding_handle;
962
963         ZERO_STRUCT(r);
964
965         info = talloc_zero(tctx, struct wkssvc_NetrWorkstationStatistics);
966
967         r.in.server_name = dcerpc_server_name(p);
968         r.out.info = &info;
969
970         torture_comment(tctx, "Testing NetrWorkstationStatisticsGet\n");
971
972         status = dcerpc_wkssvc_NetrWorkstationStatisticsGet_r(b, tctx, &r);
973         torture_assert_ntstatus_ok(tctx, status,
974                                    "NetrWorkstationStatisticsGet failed");
975         torture_assert_werr_ok(tctx, r.out.result,
976                                "NetrWorkstationStatisticsGet failed");
977         return true;
978 }
979
980 /* only succeeds as long as the local messenger service is running - Guenther */
981
982 static bool test_NetrMessageBufferSend(struct torture_context *tctx,
983                                        struct dcerpc_pipe *p)
984 {
985         NTSTATUS status;
986         struct wkssvc_NetrMessageBufferSend r;
987         const char *message = SMBTORTURE_MESSAGE;
988         size_t size;
989         uint16_t *msg;
990         struct dcerpc_binding_handle *b = p->binding_handle;
991
992         if (!push_ucs2_talloc(tctx, &msg, message, &size)) {
993                 return false;
994         }
995
996         r.in.server_name = dcerpc_server_name(p);
997         r.in.message_name = dcerpc_server_name(p);
998         r.in.message_sender_name = dcerpc_server_name(p);
999         r.in.message_buffer = (uint8_t *)msg;
1000         r.in.message_size = size;
1001
1002         torture_comment(tctx, "Testing NetrMessageBufferSend\n");
1003
1004         status = dcerpc_wkssvc_NetrMessageBufferSend_r(b, tctx, &r);
1005         torture_assert_ntstatus_ok(tctx, status,
1006                                    "NetrMessageBufferSend failed");
1007         torture_assert_werr_ok(tctx, r.out.result,
1008                                "NetrMessageBufferSend failed");
1009         return true;
1010 }
1011
1012 static bool test_NetrGetJoinInformation(struct torture_context *tctx,
1013                                         struct dcerpc_pipe *p)
1014 {
1015         NTSTATUS status;
1016         struct wkssvc_NetrGetJoinInformation r;
1017         enum wkssvc_NetJoinStatus join_status;
1018         const char *name_buffer = "";
1019         struct dcerpc_binding_handle *b = p->binding_handle;
1020
1021         r.in.server_name = dcerpc_server_name(p);
1022         r.in.name_buffer = r.out.name_buffer = &name_buffer;
1023         r.out.name_type = &join_status;
1024
1025         torture_comment(tctx, "Testing NetrGetJoinInformation\n");
1026
1027         status = dcerpc_wkssvc_NetrGetJoinInformation_r(b, tctx, &r);
1028         torture_assert_ntstatus_ok(tctx, status,
1029                                    "NetrGetJoinInformation failed");
1030         torture_assert_werr_ok(tctx, r.out.result,
1031                                "NetrGetJoinInformation failed");
1032         return true;
1033 }
1034
1035 static bool test_GetJoinInformation(struct torture_context *tctx,
1036                                     struct dcerpc_pipe *p,
1037                                     enum wkssvc_NetJoinStatus *join_status_p,
1038                                     const char **name)
1039 {
1040         NTSTATUS status;
1041         struct wkssvc_NetrGetJoinInformation r;
1042         enum wkssvc_NetJoinStatus join_status;
1043         const char *name_buffer = "";
1044         struct dcerpc_binding_handle *b = p->binding_handle;
1045
1046         r.in.server_name = dcerpc_server_name(p);
1047         r.in.name_buffer = r.out.name_buffer = &name_buffer;
1048         r.out.name_type = &join_status;
1049
1050         status = dcerpc_wkssvc_NetrGetJoinInformation_r(b, tctx, &r);
1051         torture_assert_ntstatus_ok(tctx, status,
1052                                    "NetrGetJoinInformation failed");
1053         torture_assert_werr_ok(tctx, r.out.result,
1054                                "NetrGetJoinInformation failed");
1055
1056         if (join_status_p) {
1057                 *join_status_p = join_status;
1058         }
1059
1060         if (*name) {
1061                 *name = talloc_strdup(tctx, name_buffer);
1062         }
1063
1064         return true;
1065
1066 }
1067
1068 static bool test_NetrGetJoinableOus(struct torture_context *tctx,
1069                                     struct dcerpc_pipe *p)
1070 {
1071         NTSTATUS status;
1072         struct wkssvc_NetrGetJoinableOus r;
1073         uint32_t num_ous = 0;
1074         const char **ous = NULL;
1075         struct dcerpc_binding_handle *b = p->binding_handle;
1076
1077         r.in.server_name = dcerpc_server_name(p);
1078         r.in.domain_name = lp_workgroup(tctx->lp_ctx);
1079         r.in.Account = NULL;
1080         r.in.unknown = NULL;
1081         r.in.num_ous = r.out.num_ous = &num_ous;
1082         r.out.ous = &ous;
1083
1084         torture_comment(tctx, "Testing NetrGetJoinableOus\n");
1085
1086         status = dcerpc_wkssvc_NetrGetJoinableOus_r(b, tctx, &r);
1087         torture_assert_ntstatus_ok(tctx, status, "NetrGetJoinableOus failed");
1088         torture_assert_werr_equal(tctx, r.out.result,
1089                                   WERR_NOT_SUPPORTED,
1090                                   "NetrGetJoinableOus failed");
1091
1092         return true;
1093 }
1094
1095 static bool test_NetrGetJoinableOus2(struct torture_context *tctx,
1096                                      struct dcerpc_pipe *p)
1097 {
1098         NTSTATUS status;
1099         struct wkssvc_NetrGetJoinableOus2 r;
1100         uint32_t num_ous = 0;
1101         const char **ous = NULL;
1102         struct dcerpc_binding_handle *b = p->binding_handle;
1103
1104         r.in.server_name = dcerpc_server_name(p);
1105         r.in.domain_name = lp_workgroup(tctx->lp_ctx);
1106         r.in.Account = NULL;
1107         r.in.EncryptedPassword = NULL;
1108         r.in.num_ous = r.out.num_ous = &num_ous;
1109         r.out.ous = &ous;
1110
1111         torture_comment(tctx, "Testing NetrGetJoinableOus2\n");
1112
1113         status = dcerpc_wkssvc_NetrGetJoinableOus2_r(b, tctx, &r);
1114         torture_assert_ntstatus_ok(tctx, status, "NetrGetJoinableOus2 failed");
1115         torture_assert_werr_equal(tctx, r.out.result,
1116                                   WERR_RPC_E_REMOTE_DISABLED,
1117                                   "NetrGetJoinableOus2 failed");
1118
1119         return true;
1120 }
1121
1122 static bool test_NetrUnjoinDomain(struct torture_context *tctx,
1123                                   struct dcerpc_pipe *p)
1124 {
1125         NTSTATUS status;
1126         struct wkssvc_NetrUnjoinDomain r;
1127         struct cli_credentials *creds = cmdline_credentials;
1128         const char *user = cli_credentials_get_username(creds);
1129         const char *admin_account = NULL;
1130         struct dcerpc_binding_handle *b = p->binding_handle;
1131
1132         admin_account = talloc_asprintf(tctx, "%s\\%s",
1133                                         lp_workgroup(tctx->lp_ctx),
1134                                         user);
1135
1136         r.in.server_name = dcerpc_server_name(p);
1137         r.in.Account = admin_account;
1138         r.in.password = NULL;
1139         r.in.unjoin_flags = 0;
1140
1141         torture_comment(tctx, "Testing NetrUnjoinDomain\n");
1142
1143         status = dcerpc_wkssvc_NetrUnjoinDomain_r(b, tctx, &r);
1144         torture_assert_ntstatus_ok(tctx, status,
1145                                    "NetrUnjoinDomain failed");
1146         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1147                                   "NetrUnjoinDomain failed");
1148         return true;
1149 }
1150
1151 static bool test_NetrJoinDomain(struct torture_context *tctx,
1152                                 struct dcerpc_pipe *p)
1153 {
1154         NTSTATUS status;
1155         struct wkssvc_NetrJoinDomain r;
1156         struct cli_credentials *creds = cmdline_credentials;
1157         const char *user = cli_credentials_get_username(creds);
1158         const char *admin_account = NULL;
1159         struct dcerpc_binding_handle *b = p->binding_handle;
1160
1161         admin_account = talloc_asprintf(tctx, "%s\\%s",
1162                                         lp_workgroup(tctx->lp_ctx),
1163                                         user);
1164
1165         r.in.server_name = dcerpc_server_name(p);
1166         r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
1167         r.in.account_ou = NULL;
1168         r.in.Account = admin_account;
1169         r.in.password = NULL;
1170         r.in.join_flags = 0;
1171
1172         torture_comment(tctx, "Testing NetrJoinDomain\n");
1173
1174         status = dcerpc_wkssvc_NetrJoinDomain_r(b, tctx, &r);
1175         torture_assert_ntstatus_ok(tctx, status,
1176                                    "NetrJoinDomain failed");
1177         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1178                                   "NetrJoinDomain failed");
1179         return true;
1180 }
1181
1182 /*
1183  * prerequisites for remotely joining an unjoined XP SP2 workstation:
1184  * - firewall needs to be disabled (or open for ncacn_np access)
1185  * - HKLM\System\CurrentControlSet\Control\Lsa\forceguest needs to 0
1186  * see also:
1187  * http://support.microsoft.com/kb/294355/EN-US/ and
1188  * http://support.microsoft.com/kb/290403/EN-US/
1189  */
1190
1191 static bool test_NetrJoinDomain2(struct torture_context *tctx,
1192                                  struct dcerpc_pipe *p)
1193 {
1194         NTSTATUS status;
1195         struct wkssvc_NetrJoinDomain2 r;
1196         const char *domain_admin_account = NULL;
1197         const char *domain_admin_password = NULL;
1198         const char *domain_name = NULL;
1199         struct wkssvc_PasswordBuffer *pwd_buf;
1200         enum wkssvc_NetJoinStatus join_status;
1201         const char *join_name = NULL;
1202         WERROR expected_err;
1203         DATA_BLOB session_key;
1204         struct dcerpc_binding_handle *b = p->binding_handle;
1205
1206         /* FIXME: this test assumes to join workstations / servers and does not
1207          * handle DCs (WERR_SETUP_DOMAIN_CONTROLLER) */
1208
1209         if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
1210         {
1211                 return false;
1212         }
1213
1214         switch (join_status) {
1215                 case NET_SETUP_DOMAIN_NAME:
1216                         expected_err = WERR_SETUP_ALREADY_JOINED;
1217                         break;
1218                 case NET_SETUP_UNKNOWN_STATUS:
1219                 case NET_SETUP_UNJOINED:
1220                 case NET_SETUP_WORKGROUP_NAME:
1221                 default:
1222                         expected_err = WERR_OK;
1223                         break;
1224         }
1225
1226         domain_admin_account = torture_setting_string(tctx, "domain_admin_account", NULL);
1227
1228         domain_admin_password = torture_setting_string(tctx, "domain_admin_password", NULL);
1229
1230         domain_name = torture_setting_string(tctx, "domain_name", NULL);
1231
1232         if ((domain_admin_account == NULL) ||
1233             (domain_admin_password == NULL) ||
1234             (domain_name == NULL)) {
1235                 torture_comment(tctx, "not enough input parameter\n");
1236                 return false;
1237         }
1238
1239         status = dcerpc_fetch_session_key(p, &session_key);
1240         if (!NT_STATUS_IS_OK(status)) {
1241                 return false;
1242         }
1243
1244         encode_wkssvc_join_password_buffer(tctx, domain_admin_password,
1245                                            &session_key, &pwd_buf);
1246
1247         r.in.server_name = dcerpc_server_name(p);
1248         r.in.domain_name = domain_name;
1249         r.in.account_ou = NULL;
1250         r.in.admin_account = domain_admin_account;
1251         r.in.encrypted_password = pwd_buf;
1252         r.in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
1253                           WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
1254
1255         torture_comment(tctx, "Testing NetrJoinDomain2 (assuming non-DC)\n");
1256
1257         status = dcerpc_wkssvc_NetrJoinDomain2_r(b, tctx, &r);
1258         torture_assert_ntstatus_ok(tctx, status,
1259                                    "NetrJoinDomain2 failed");
1260         torture_assert_werr_equal(tctx, r.out.result, expected_err,
1261                                   "NetrJoinDomain2 failed");
1262
1263         if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
1264         {
1265                 return false;
1266         }
1267
1268         if (join_status != NET_SETUP_DOMAIN_NAME) {
1269                 torture_comment(tctx,
1270                                 "Join verify failed: got %d\n", join_status);
1271                 return false;
1272         }
1273
1274         return true;
1275 }
1276
1277 static bool test_NetrUnjoinDomain2(struct torture_context *tctx,
1278                                    struct dcerpc_pipe *p)
1279 {
1280         NTSTATUS status;
1281         struct wkssvc_NetrUnjoinDomain2 r;
1282         const char *domain_admin_account = NULL;
1283         const char *domain_admin_password = NULL;
1284         struct wkssvc_PasswordBuffer *pwd_buf;
1285         enum wkssvc_NetJoinStatus join_status;
1286         const char *join_name = NULL;
1287         WERROR expected_err;
1288         DATA_BLOB session_key;
1289         struct dcerpc_binding_handle *b = p->binding_handle;
1290
1291         /* FIXME: this test assumes to join workstations / servers and does not
1292          * handle DCs (WERR_SETUP_DOMAIN_CONTROLLER) */
1293
1294         if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
1295         {
1296                 return false;
1297         }
1298
1299         switch (join_status) {
1300                 case NET_SETUP_UNJOINED:
1301                         expected_err = WERR_SETUP_NOT_JOINED;
1302                         break;
1303                 case NET_SETUP_DOMAIN_NAME:
1304                 case NET_SETUP_UNKNOWN_STATUS:
1305                 case NET_SETUP_WORKGROUP_NAME:
1306                 default:
1307                         expected_err = WERR_OK;
1308                         break;
1309         }
1310
1311         domain_admin_account = torture_setting_string(tctx, "domain_admin_account", NULL);
1312
1313         domain_admin_password = torture_setting_string(tctx, "domain_admin_password", NULL);
1314
1315         if ((domain_admin_account == NULL) ||
1316             (domain_admin_password == NULL)) {
1317                 torture_comment(tctx, "not enough input parameter\n");
1318                 return false;
1319         }
1320
1321         status = dcerpc_fetch_session_key(p, &session_key);
1322         if (!NT_STATUS_IS_OK(status)) {
1323                 return false;
1324         }
1325
1326         encode_wkssvc_join_password_buffer(tctx, domain_admin_password,
1327                                            &session_key, &pwd_buf);
1328
1329         r.in.server_name = dcerpc_server_name(p);
1330         r.in.account = domain_admin_account;
1331         r.in.encrypted_password = pwd_buf;
1332         r.in.unjoin_flags = 0;
1333
1334         torture_comment(tctx, "Testing NetrUnjoinDomain2 (assuming non-DC)\n");
1335
1336         status = dcerpc_wkssvc_NetrUnjoinDomain2_r(b, tctx, &r);
1337         torture_assert_ntstatus_ok(tctx, status,
1338                                    "NetrUnjoinDomain2 failed");
1339         torture_assert_werr_equal(tctx, r.out.result, expected_err,
1340                                   "NetrUnjoinDomain2 failed");
1341
1342         if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
1343         {
1344                 return false;
1345         }
1346
1347         switch (join_status) {
1348                 case NET_SETUP_UNJOINED:
1349                 case NET_SETUP_WORKGROUP_NAME:
1350                         break;
1351                 case NET_SETUP_UNKNOWN_STATUS:
1352                 case NET_SETUP_DOMAIN_NAME:
1353                 default:
1354                         torture_comment(tctx,
1355                                 "Unjoin verify failed: got %d\n", join_status);
1356                         return false;
1357         }
1358
1359         return true;
1360 }
1361
1362
1363 struct torture_suite *torture_rpc_wkssvc(TALLOC_CTX *mem_ctx)
1364 {
1365         struct torture_suite *suite;
1366         struct torture_rpc_tcase *tcase;
1367         struct torture_test *test;
1368
1369         suite = torture_suite_create(mem_ctx, "WKSSVC");
1370         tcase = torture_suite_add_rpc_iface_tcase(suite, "wkssvc",
1371                                                   &ndr_table_wkssvc);
1372
1373         torture_rpc_tcase_add_test(tcase, "NetWkstaGetInfo",
1374                                    test_NetWkstaGetInfo);
1375
1376         torture_rpc_tcase_add_test(tcase, "NetWkstaTransportEnum",
1377                                    test_NetWkstaTransportEnum);
1378         torture_rpc_tcase_add_test(tcase, "NetrWkstaTransportDel",
1379                                    test_NetrWkstaTransportDel);
1380         torture_rpc_tcase_add_test(tcase, "NetrWkstaTransportAdd",
1381                                    test_NetrWkstaTransportAdd);
1382
1383         torture_rpc_tcase_add_test(tcase, "NetWkstaEnumUsers",
1384                                    test_NetWkstaEnumUsers);
1385         torture_rpc_tcase_add_test(tcase, "NetrWkstaUserGetInfo",
1386                                    test_NetrWkstaUserGetInfo);
1387
1388         torture_rpc_tcase_add_test(tcase, "NetrUseDel",
1389                                    test_NetrUseDel);
1390         torture_rpc_tcase_add_test(tcase, "NetrUseGetInfo",
1391                                    test_NetrUseGetInfo);
1392         torture_rpc_tcase_add_test(tcase, "NetrUseEnum",
1393                                    test_NetrUseEnum);
1394         torture_rpc_tcase_add_test(tcase, "NetrUseAdd",
1395                                    test_NetrUseAdd);
1396
1397         torture_rpc_tcase_add_test(tcase, "NetrValidateName",
1398                                    test_NetrValidateName);
1399         torture_rpc_tcase_add_test(tcase, "NetrValidateName2",
1400                                    test_NetrValidateName2);
1401         torture_rpc_tcase_add_test(tcase, "NetrLogonDomainNameDel",
1402                                    test_NetrLogonDomainNameDel);
1403         torture_rpc_tcase_add_test(tcase, "NetrLogonDomainNameAdd",
1404                                    test_NetrLogonDomainNameAdd);
1405         torture_rpc_tcase_add_test(tcase, "NetrRemoveAlternateComputerName",
1406                                    test_NetrRemoveAlternateComputerName);
1407         torture_rpc_tcase_add_test(tcase, "NetrAddAlternateComputerName",
1408                                    test_NetrAddAlternateComputerName);
1409         test = torture_rpc_tcase_add_test(tcase, "NetrSetPrimaryComputername",
1410                                           test_NetrSetPrimaryComputername);
1411         test->dangerous = true;
1412         test = torture_rpc_tcase_add_test(tcase, "NetrRenameMachineInDomain",
1413                                           test_NetrRenameMachineInDomain);
1414         test->dangerous = true;
1415         test = torture_rpc_tcase_add_test(tcase, "NetrRenameMachineInDomain2",
1416                                           test_NetrRenameMachineInDomain2);
1417         test->dangerous = true;
1418         torture_rpc_tcase_add_test(tcase, "NetrEnumerateComputerNames",
1419                                    test_NetrEnumerateComputerNames);
1420
1421         test = torture_rpc_tcase_add_test(tcase, "NetrJoinDomain2",
1422                                           test_NetrJoinDomain2);
1423         test->dangerous = true;
1424         test = torture_rpc_tcase_add_test(tcase, "NetrUnjoinDomain2",
1425                                           test_NetrUnjoinDomain2);
1426         test->dangerous = true;
1427
1428         torture_rpc_tcase_add_test(tcase, "NetrJoinDomain",
1429                                    test_NetrJoinDomain);
1430         test->dangerous = true;
1431         torture_rpc_tcase_add_test(tcase, "NetrUnjoinDomain",
1432                                    test_NetrUnjoinDomain);
1433         test->dangerous = true;
1434         torture_rpc_tcase_add_test(tcase, "NetrGetJoinInformation",
1435                                    test_NetrGetJoinInformation);
1436         torture_rpc_tcase_add_test(tcase, "NetrGetJoinableOus",
1437                                    test_NetrGetJoinableOus);
1438         torture_rpc_tcase_add_test(tcase, "NetrGetJoinableOus2",
1439                                    test_NetrGetJoinableOus2);
1440
1441         torture_rpc_tcase_add_test(tcase, "NetrWorkstationStatisticsGet",
1442                                    test_NetrWorkstationStatisticsGet);
1443         torture_rpc_tcase_add_test(tcase, "NetrMessageBufferSend",
1444                                    test_NetrMessageBufferSend);
1445
1446         return suite;
1447 }