r18757: Disable this for now
[metze/samba/wip.git] / source4 / torture / rpc / srvsvc.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for srvsvc rpc operations
4
5    Copyright (C) Stefan (metze) Metzmacher 2003
6    
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 2 of the License, or
10    (at your option) any later version.
11    
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.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "librpc/gen_ndr/ndr_srvsvc.h"
25 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
26 #include "torture/rpc/rpc.h"
27
28 /**************************/
29 /* srvsvc_NetCharDev      */
30 /**************************/
31 static BOOL test_NetCharDevGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
32                                 const char *devname)
33 {
34         NTSTATUS status;
35         struct srvsvc_NetCharDevGetInfo r;
36         uint32_t levels[] = {0, 1};
37         int i;
38         BOOL ret = True;
39
40         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
41         r.in.device_name = devname;
42
43         for (i=0;i<ARRAY_SIZE(levels);i++) {
44                 ZERO_STRUCT(r.out);
45                 r.in.level = levels[i];
46                 d_printf("testing NetCharDevGetInfo level %u on device '%s'\n",
47                         r.in.level, r.in.device_name);
48                 status = dcerpc_srvsvc_NetCharDevGetInfo(p, mem_ctx, &r);
49                 if (!NT_STATUS_IS_OK(status)) {
50                         d_printf("NetCharDevGetInfo level %u on device '%s' failed - %s\n",
51                                 r.in.level, r.in.device_name, nt_errstr(status));
52                         ret = False;
53                         continue;
54                 }
55                 if (!W_ERROR_IS_OK(r.out.result)) {
56                         d_printf("NetCharDevGetInfo level %u on device '%s' failed - %s\n",
57                                 r.in.level, r.in.device_name, win_errstr(r.out.result));
58                         continue;
59                 }
60         }
61
62         return ret;
63 }
64
65 static BOOL test_NetCharDevControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
66                                 const char *devname)
67 {
68         NTSTATUS status;
69         struct srvsvc_NetCharDevControl r;
70         uint32_t opcodes[] = {0, 1};
71         int i;
72         BOOL ret = True;
73
74         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
75         r.in.device_name = devname;
76
77         for (i=0;i<ARRAY_SIZE(opcodes);i++) {
78                 ZERO_STRUCT(r.out);
79                 r.in.opcode = opcodes[i];
80                 d_printf("testing NetCharDevControl opcode %u on device '%s'\n", 
81                         r.in.opcode, r.in.device_name);
82                 status = dcerpc_srvsvc_NetCharDevControl(p, mem_ctx, &r);
83                 if (!NT_STATUS_IS_OK(status)) {
84                         d_printf("NetCharDevControl opcode %u failed - %s\n", r.in.opcode, nt_errstr(status));
85                         ret = False;
86                         continue;
87                 }
88                 if (!W_ERROR_IS_OK(r.out.result)) {
89                         d_printf("NetCharDevControl opcode %u failed - %s\n", r.in.opcode, win_errstr(r.out.result));
90                         continue;
91                 }
92         }
93
94         return ret;
95 }
96
97 static BOOL test_NetCharDevEnum(struct dcerpc_pipe *p, 
98                            TALLOC_CTX *mem_ctx)
99 {
100         NTSTATUS status;
101         struct srvsvc_NetCharDevEnum r;
102         struct srvsvc_NetCharDevCtr0 c0;
103         uint32_t levels[] = {0, 1};
104         int i;
105         BOOL ret = True;
106
107         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
108         r.in.ctr.ctr0 = &c0;
109         r.in.ctr.ctr0->count = 0;
110         r.in.ctr.ctr0->array = NULL;
111         r.in.max_buffer = (uint32_t)-1;
112         r.in.resume_handle = NULL;
113
114         for (i=0;i<ARRAY_SIZE(levels);i++) {
115                 int j;
116
117
118                 ZERO_STRUCT(r.out);
119                 r.in.level = levels[i];
120                 printf("testing NetCharDevEnum level %u\n", r.in.level);
121                 status = dcerpc_srvsvc_NetCharDevEnum(p, mem_ctx, &r);
122                 if (!NT_STATUS_IS_OK(status)) {
123                         d_printf("NetCharDevEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
124                         ret = False;
125                         continue;
126                 }
127                 if (!W_ERROR_IS_OK(r.out.result)) {
128                         d_printf("NetCharDevEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
129                         continue;
130                 }
131
132                 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
133                 if (r.in.level == 1) {
134                         for (j=0;j<r.out.ctr.ctr1->count;j++) {
135                                 const char *device;
136                                 device = r.out.ctr.ctr1->array[j].device;
137                                 if (!test_NetCharDevGetInfo(p, mem_ctx, device)) {
138                                         ret = False;
139                                 }
140                                 if (!test_NetCharDevControl(p, mem_ctx, device)) {
141                                         ret = False;
142                                 }
143                         }
144                 }
145         }
146
147         return ret;
148 }
149
150 /**************************/
151 /* srvsvc_NetCharDevQ     */
152 /**************************/
153 static BOOL test_NetCharDevQGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
154                                 const char *devicequeue)
155 {
156         NTSTATUS status;
157         struct srvsvc_NetCharDevQGetInfo r;
158         uint32_t levels[] = {0, 1};
159         int i;
160         BOOL ret = True;
161
162         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
163         r.in.queue_name = devicequeue;
164         r.in.user = talloc_asprintf(mem_ctx,"Administrator");
165
166         for (i=0;i<ARRAY_SIZE(levels);i++) {
167                 ZERO_STRUCT(r.out);
168                 r.in.level = levels[i];
169                 d_printf("testing NetCharDevQGetInfo level %u on devicequeue '%s'\n",
170                         r.in.level, r.in.queue_name);
171                 status = dcerpc_srvsvc_NetCharDevQGetInfo(p, mem_ctx, &r);
172                 if (!NT_STATUS_IS_OK(status)) {
173                         d_printf("NetCharDevQGetInfo level %u on devicequeue '%s' failed - %s\n",
174                                 r.in.level, r.in.queue_name, nt_errstr(status));
175                         ret = False;
176                         continue;
177                 }
178                 if (!W_ERROR_IS_OK(r.out.result)) {
179                         printf("NetCharDevQGetInfo level %u on devicequeue '%s' failed - %s\n",
180                                 r.in.level, r.in.queue_name, win_errstr(r.out.result));
181                         continue;
182                 }
183         }
184
185         return ret;
186 }
187
188 #if 0
189 static BOOL test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
190                                 const char *devicequeue)
191 {
192         NTSTATUS status;
193         struct srvsvc_NetCharDevQSetInfo r;
194         uint32_t parm_error;
195         uint32_t levels[] = {0, 1};
196         int i;
197         BOOL ret = True;
198
199         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
200         r.in.queue_name = devicequeue;
201
202         for (i=0;i<ARRAY_SIZE(levels);i++) {
203                 ZERO_STRUCT(r.out);
204                 parm_error = 0;
205                 r.in.level = levels[i];
206                 d_printf("testing NetCharDevQSetInfo level %u on devicequeue '%s'\n", 
207                         r.in.level, devicequeue);
208                 switch (r.in.level) {
209                 case 0:
210                         r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0);
211                         r.in.info.info0->device = r.in.queue_name;
212                         break;
213                 case 1:
214                         r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo1);
215                         r.in.info.info1->device = r.in.queue_name;
216                         r.in.info.info1->priority = 0x000;
217                         r.in.info.info1->devices = r.in.queue_name;
218                         r.in.info.info1->users = 0x000;
219                         r.in.info.info1->num_ahead = 0x000;
220                         break;
221                 default:
222                         break;
223                 }
224                 r.in.parm_error = &parm_error;
225                 status = dcerpc_srvsvc_NetCharDevQSetInfo(p, mem_ctx, &r);
226                 if (!NT_STATUS_IS_OK(status)) {
227                         d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
228                                 r.in.level, r.in.queue_name, nt_errstr(status));
229                         ret = False;
230                         continue;
231                 }
232                 if (!W_ERROR_IS_OK(r.out.result)) {
233                         d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
234                                 r.in.level, r.in.queue_name, win_errstr(r.out.result));
235                         continue;
236                 }
237         }
238
239         return ret;
240 }
241 #endif
242
243 static BOOL test_NetCharDevQEnum(struct dcerpc_pipe *p, 
244                            TALLOC_CTX *mem_ctx)
245 {
246         NTSTATUS status;
247         struct srvsvc_NetCharDevQEnum r;
248         struct srvsvc_NetCharDevQCtr0 c0;
249         uint32_t levels[] = {0, 1};
250         int i;
251         BOOL ret = True;
252
253         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
254         r.in.user = talloc_asprintf(mem_ctx,"%s","Administrator");
255         r.in.ctr.ctr0 = &c0;
256         r.in.ctr.ctr0->count = 0;
257         r.in.ctr.ctr0->array = NULL;
258         r.in.max_buffer = (uint32_t)-1;
259         r.in.resume_handle = NULL;
260
261         for (i=0;i<ARRAY_SIZE(levels);i++) {
262                 int j;
263
264                 ZERO_STRUCT(r.out);
265                 r.in.level = levels[i];
266                 printf("testing NetCharDevQEnum level %u\n", r.in.level);
267                 status = dcerpc_srvsvc_NetCharDevQEnum(p, mem_ctx, &r);
268                 if (!NT_STATUS_IS_OK(status)) {
269                         d_printf("NetCharDevQEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
270                         ret = False;
271                         continue;
272                 }
273                 if (!W_ERROR_IS_OK(r.out.result)) {
274                         d_printf("NetCharDevQEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
275                         continue;
276                 }
277
278                 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
279                 if (r.in.level == 1) {
280                         for (j=0;j<r.out.ctr.ctr1->count;j++) {
281                                 const char *device;
282                                 device = r.out.ctr.ctr1->array[j].device;
283                                 if (!test_NetCharDevQGetInfo(p, mem_ctx, device)) {
284                                         ret = False;
285                                 }
286                         }
287                 }
288         }
289
290         return ret;
291 }
292
293 /**************************/
294 /* srvsvc_NetConn         */
295 /**************************/
296 static BOOL test_NetConnEnum(struct dcerpc_pipe *p, 
297                            TALLOC_CTX *mem_ctx)
298 {
299         NTSTATUS status;
300         struct srvsvc_NetConnEnum r;
301         struct srvsvc_NetConnCtr0 c0;
302         uint32_t levels[] = {0, 1};
303         int i;
304         BOOL ret = True;
305
306         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
307         r.in.path = talloc_asprintf(mem_ctx,"%s","ADMIN$");
308         r.in.ctr.ctr0 = &c0;
309         r.in.ctr.ctr0->count = 0;
310         r.in.ctr.ctr0->array = NULL;
311         r.in.max_buffer = (uint32_t)-1;
312         r.in.resume_handle = NULL;
313
314         for (i=0;i<ARRAY_SIZE(levels);i++) {
315                 ZERO_STRUCT(r.out);
316                 r.in.level = levels[i];
317                 d_printf("testing NetConnEnum level %u\n", r.in.level);
318                 status = dcerpc_srvsvc_NetConnEnum(p, mem_ctx, &r);
319                 if (!NT_STATUS_IS_OK(status)) {
320                         d_printf("NetConnEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
321                         ret = False;
322                         continue;
323                 }
324                 if (!W_ERROR_IS_OK(r.out.result)) {
325                         d_printf("NetConnEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
326                         continue;
327                 }
328         }
329
330         return ret;
331 }
332
333 /**************************/
334 /* srvsvc_NetFile         */
335 /**************************/
336 static BOOL test_NetFileEnum(struct dcerpc_pipe *p, 
337                            TALLOC_CTX *mem_ctx)
338 {
339         NTSTATUS status;
340         struct srvsvc_NetFileEnum r;
341         struct srvsvc_NetFileCtr3 c3;
342         uint32_t levels[] = {2, 3};
343         int i;
344         BOOL ret = True;
345
346         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
347         r.in.path = NULL;
348         r.in.user = NULL;
349         r.in.ctr.ctr3 = &c3;
350         r.in.ctr.ctr3->count = 0;
351         r.in.ctr.ctr3->array = NULL;
352         r.in.max_buffer = (uint32_t)4096;
353         r.in.resume_handle = NULL;
354
355         for (i=0;i<ARRAY_SIZE(levels);i++) {
356                 ZERO_STRUCT(r.out);
357                 r.in.level = levels[i];
358                 d_printf("testing NetFileEnum level %u\n", r.in.level);
359                 status = dcerpc_srvsvc_NetFileEnum(p, mem_ctx, &r);
360                 if (!NT_STATUS_IS_OK(status)) {
361                         d_printf("NetFileEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
362                         ret = False;
363                         continue;
364                 }
365                 if (!W_ERROR_IS_OK(r.out.result)) {
366                         d_printf("NetFileEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
367                         continue;
368                 }
369         }
370
371         return ret;
372 }
373
374 /**************************/
375 /* srvsvc_NetSess         */
376 /**************************/
377 static BOOL test_NetSessEnum(struct dcerpc_pipe *p, 
378                            TALLOC_CTX *mem_ctx)
379 {
380         NTSTATUS status;
381         struct srvsvc_NetSessEnum r;
382         struct srvsvc_NetSessCtr0 c0;
383         uint32_t levels[] = {0, 1, 2, 10, 502};
384         int i;
385         BOOL ret = True;
386
387         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
388         r.in.client = NULL;
389         r.in.user = NULL;
390         r.in.ctr.ctr0 = &c0;
391         r.in.ctr.ctr0->count = 0;
392         r.in.ctr.ctr0->array = NULL;
393         r.in.max_buffer = (uint32_t)-1;
394         r.in.resume_handle = NULL;
395
396         for (i=0;i<ARRAY_SIZE(levels);i++) {
397                 ZERO_STRUCT(r.out);
398                 r.in.level = levels[i];
399                 d_printf("testing NetSessEnum level %u\n", r.in.level);
400                 status = dcerpc_srvsvc_NetSessEnum(p, mem_ctx, &r);
401                 if (!NT_STATUS_IS_OK(status)) {
402                         d_printf("NetSessEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
403                         ret = False;
404                         continue;
405                 }
406                 if (!W_ERROR_IS_OK(r.out.result)) {
407                         d_printf("NetSessEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
408                         continue;
409                 }
410         }
411
412         return ret;
413 }
414
415 /**************************/
416 /* srvsvc_NetShare        */
417 /**************************/
418 static BOOL test_NetShareCheck(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
419                                const char *device_name)
420 {
421         NTSTATUS status;
422         struct srvsvc_NetShareCheck r;
423         BOOL ret = True;
424
425         r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
426         r.in.device_name = device_name;
427
428         d_printf("testing NetShareCheck on device '%s'\n", r.in.device_name);
429
430         status = dcerpc_srvsvc_NetShareCheck(p, mem_ctx, &r);
431         if (!NT_STATUS_IS_OK(status)) {
432                 d_printf("dcerpc_srvsvc_NetShareCheck on device '%s' failed - %s\n",
433                         r.in.device_name, nt_errstr(status));
434                 ret = False;
435         } else if (!W_ERROR_IS_OK(r.out.result)) {
436                 d_printf("NetShareCheck on device '%s' failed - %s\n",
437                         r.in.device_name, win_errstr(r.out.result));
438                 ret = False;
439         }
440
441         return ret;
442 }
443
444 static BOOL test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
445                                  const char *sharename, BOOL admin)
446 {
447         NTSTATUS status;
448         struct srvsvc_NetShareGetInfo r;
449         struct {
450                 uint32_t level;
451                 WERROR anon_status;
452                 WERROR admin_status;
453         } levels[] = {
454                  { 0,           WERR_OK,                WERR_OK },
455                  { 1,           WERR_OK,                WERR_OK },
456                  { 2,           WERR_ACCESS_DENIED,     WERR_OK },
457                  { 501,         WERR_OK,                WERR_OK },
458                  { 502,         WERR_ACCESS_DENIED,     WERR_OK },
459                  { 1005,        WERR_OK,                WERR_OK },
460         };
461         int i;
462         BOOL ret = True;
463
464         r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
465         r.in.share_name = sharename;
466
467         for (i=0;i<ARRAY_SIZE(levels);i++) {
468                 WERROR expected;
469
470                 r.in.level = levels[i].level;
471                 expected = levels[i].anon_status;
472                 if (admin) expected = levels[i].admin_status;
473                 ZERO_STRUCT(r.out);
474
475                 d_printf("testing NetShareGetInfo level %u on share '%s'\n", 
476                        r.in.level, r.in.share_name);
477
478                 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
479                 if (!NT_STATUS_IS_OK(status)) {
480                         d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
481                                 r.in.level, r.in.share_name, nt_errstr(status));
482                         ret = False;
483                         continue;
484                 }
485                 if (!W_ERROR_EQUAL(r.out.result, expected)) {
486                         d_printf("NetShareGetInfo level %u on share '%s' failed - %s (expected %s)\n",
487                                 r.in.level, r.in.share_name, win_errstr(r.out.result),
488                                 win_errstr(expected));
489                         ret = False;
490                         continue;
491                 }
492
493                 if (r.in.level != 2) continue;
494                 if (!r.out.info.info2 || !r.out.info.info2->path) continue;
495                 if (!test_NetShareCheck(p, mem_ctx, r.out.info.info2->path)) {
496                         ret = False;
497                 }
498         }
499
500         return ret;
501 }
502
503 static BOOL test_NetShareAddSetDel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
504 {
505         NTSTATUS status;
506         struct srvsvc_NetShareAdd a;
507         struct srvsvc_NetShareSetInfo r;
508         struct srvsvc_NetShareGetInfo q;
509         struct srvsvc_NetShareDel d;
510         struct {
511                 uint32_t level;
512                 WERROR expected;
513         } levels[] = {
514                  { 0,           WERR_UNKNOWN_LEVEL },
515                  { 1,           WERR_OK },
516                  { 2,           WERR_OK },
517                  { 501,         WERR_UNKNOWN_LEVEL },
518                  { 502,         WERR_OK },
519                  { 1004,        WERR_OK },
520                  { 1005,        WERR_OK },
521                  { 1006,        WERR_OK },
522 /*               { 1007,        WERR_OK }, */
523                  { 1501,        WERR_OK },
524         };
525         int i;
526         BOOL ret = True;
527
528         a.in.server_unc = r.in.server_unc = q.in.server_unc = d.in.server_unc =
529                 talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
530         r.in.share_name = talloc_strdup(mem_ctx, "testshare");
531
532         a.in.level = 2;
533         a.in.info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
534         a.in.info.info2->name = r.in.share_name;
535         a.in.info.info2->type = STYPE_DISKTREE;
536         a.in.info.info2->comment = talloc_strdup(mem_ctx, "test comment");
537         a.in.info.info2->permissions = 123434566;
538         a.in.info.info2->max_users = -1;
539         a.in.info.info2->current_users = 0;
540         a.in.info.info2->path = talloc_strdup(mem_ctx, "C:\\");
541         a.in.info.info2->password = NULL;
542
543         a.in.parm_error = NULL;
544
545         status = dcerpc_srvsvc_NetShareAdd(p, mem_ctx, &a);
546         if (!NT_STATUS_IS_OK(status)) {
547                 d_printf("NetShareAdd level 2 on share 'testshare' failed - %s\n",
548                          nt_errstr(status));
549                 return False;
550         } else if (!W_ERROR_EQUAL(a.out.result, WERR_OK)) {
551                 d_printf("NetShareAdd level 2 on share 'testshare' failed - %s\n",
552                          win_errstr(a.out.result));
553                 return False;
554         }
555
556         r.in.parm_error = NULL;
557
558         q.in.level = 502;
559
560         for (i = 0; i < ARRAY_SIZE(levels); i++) {
561
562                 r.in.level = levels[i].level;
563                 ZERO_STRUCT(r.out);
564
565                 d_printf("testing NetShareSetInfo level %u on share '%s'\n", 
566                        r.in.level, r.in.share_name);
567
568                 switch (levels[i].level) {
569                 case 0:
570                         r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetShareInfo0);
571                         r.in.info.info0->name = r.in.share_name;
572                         break;
573                 case 1:
574                         r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetShareInfo1);
575                         r.in.info.info1->name = r.in.share_name;
576                         r.in.info.info1->type = STYPE_DISKTREE;
577                         r.in.info.info1->comment = talloc_strdup(mem_ctx, "test comment 1");
578                         break;
579                 case 2: 
580                         r.in.info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
581                         r.in.info.info2->name = r.in.share_name;
582                         r.in.info.info2->type = STYPE_DISKTREE;
583                         r.in.info.info2->comment = talloc_strdup(mem_ctx, "test comment 2");
584                         r.in.info.info2->permissions = 0;
585                         r.in.info.info2->max_users = 2;
586                         r.in.info.info2->current_users = 1;
587                         r.in.info.info2->path = talloc_strdup(mem_ctx, "::BLaH::"); /* "C:\\"); */
588                         r.in.info.info2->password = NULL;
589                         break;
590                 case 501:
591                         r.in.info.info501 = talloc(mem_ctx, struct srvsvc_NetShareInfo501);
592                         r.in.info.info501->name = r.in.share_name;
593                         r.in.info.info501->type = STYPE_DISKTREE;
594                         r.in.info.info501->comment = talloc_strdup(mem_ctx, "test comment 501");
595                         r.in.info.info501->csc_policy = 0;
596                         break;
597                 case 502:
598                         r.in.info.info502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502);
599                         r.in.info.info502->name = r.in.share_name;
600                         r.in.info.info502->type = STYPE_DISKTREE;
601                         r.in.info.info502->comment = talloc_strdup(mem_ctx, "test comment 502");
602                         r.in.info.info502->permissions = 0;
603                         r.in.info.info502->max_users = 502;
604                         r.in.info.info502->current_users = 1;
605                         r.in.info.info502->path = talloc_strdup(mem_ctx, "C:\\");
606                         r.in.info.info502->password = NULL;
607                         r.in.info.info502->unknown = 0;
608                         r.in.info.info502->sd = NULL;
609                         break;
610                 case 1004:
611                         r.in.info.info1004 = talloc(mem_ctx, struct srvsvc_NetShareInfo1004);
612                         r.in.info.info1004->comment = talloc_strdup(mem_ctx, "test comment 1004");
613                         break;
614                 case 1005:
615                         r.in.info.info1005 = talloc(mem_ctx, struct srvsvc_NetShareInfo1005);
616                         r.in.info.info1005->dfs_flags = 0;
617                         break;
618                 case 1006:
619                         r.in.info.info1006 = talloc(mem_ctx, struct srvsvc_NetShareInfo1006);
620                         r.in.info.info1006->max_users = 1006;
621                         break;
622 /*              case 1007:
623                         r.in.info.info1007 = talloc(mem_ctx, struct srvsvc_NetShareInfo1007);
624                         r.in.info.info1007->flags = 0;
625                         r.in.info.info1007->alternate_directory_name = talloc_strdup(mem_ctx, "test");
626                         break;
627 */
628                 case 1501:
629                         r.in.info.info1501 = talloc_zero(mem_ctx, struct sec_desc_buf);
630                         break;
631                 }
632                 
633                 status = dcerpc_srvsvc_NetShareSetInfo(p, mem_ctx, &r);
634                 if (!NT_STATUS_IS_OK(status)) {
635                         d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
636                                 r.in.level, r.in.share_name, nt_errstr(status));
637                         ret = False;
638                         continue;
639                 } else if (!W_ERROR_EQUAL(r.out.result, levels[i].expected)) {
640                         d_printf("NetShareSetInfo level %u on share '%s' failed - %s (expected %s)\n",
641                                 r.in.level, r.in.share_name, win_errstr(r.out.result),
642                                 win_errstr(levels[i].expected));
643                         ret = False;
644                         continue;
645                 }
646                 
647                 q.in.share_name = r.in.share_name;
648
649                 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &q);
650                 if (!NT_STATUS_IS_OK(status)) {
651                         d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
652                                 q.in.level, q.in.share_name, nt_errstr(status));
653                         ret = False;
654                         continue;
655                 } else if (!W_ERROR_EQUAL(q.out.result, WERR_OK)) {
656                         d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
657                                 q.in.level, q.in.share_name, win_errstr(q.out.result));
658                         ret = False;
659                         continue;
660                 }
661
662                 if (strcmp(q.out.info.info502->name, r.in.share_name) != 0) {
663                         ret = False;
664                 }
665                 switch (levels[i].level) {
666                 case 0:
667                         break;
668                 case 1:
669                         if (strcmp(q.out.info.info502->comment, "test comment 1") != 0)
670                                 ret = False;
671                         break;
672                 case 2:
673                         if (strcmp(q.out.info.info502->comment, "test comment 2") != 0)
674                                 ret = False;
675                         if (q.out.info.info2->max_users != 2)
676                                 ret = False;
677                         if (strcmp(q.out.info.info2->path, "C:\\") != 0)
678                                 ret = False;
679                         break;
680                 case 501:
681                         if (strcmp(q.out.info.info501->comment, "test comment 501") != 0)
682                                 ret = False;
683                         break;
684                 case 502:
685                         if (strcmp(q.out.info.info502->comment, "test comment 502") != 0)
686                                 ret = False;
687                         if (q.out.info.info2->max_users != 502)
688                                 ret = False;
689                         if (strcmp(q.out.info.info2->path, "C:\\") != 0)
690                                 ret = False;
691                         break;
692                 case 1004:
693                         if (strcmp(q.out.info.info502->comment, "test comment 1004") != 0)
694                                 ret = False;
695                         break;
696                 case 1005:
697                         break;
698                 case 1006:
699                         if (q.out.info.info2->max_users != 1006)
700                                 ret = False;
701                         break;
702 /*              case 1007:
703                         break;
704 */
705                 case 1501:
706                         break;
707                 }
708         }
709
710         d.in.share_name = r.in.share_name;
711         d.in.reserved = 0;
712
713         status = dcerpc_srvsvc_NetShareDel(p, mem_ctx, &d);
714         if (!NT_STATUS_IS_OK(status)) {
715                 d_printf("NetShareDel on share 'testshare502' failed - %s\n",
716                          nt_errstr(status));
717                 ret = False;
718         } else if (!W_ERROR_EQUAL(a.out.result, WERR_OK)) {
719                 d_printf("NetShareDel on share 'testshare502' failed - %s\n",
720                          win_errstr(d.out.result));
721                 ret = False;
722         }
723
724         return ret;
725 }
726
727 /**************************/
728 /* srvsvc_NetShare        */
729 /**************************/
730 static BOOL test_NetShareEnumAll(struct dcerpc_pipe *p, 
731                                  TALLOC_CTX *mem_ctx, BOOL admin)
732 {
733         NTSTATUS status;
734         struct srvsvc_NetShareEnumAll r;
735         struct srvsvc_NetShareCtr0 c0;
736         struct {
737                 uint32_t level;
738                 WERROR anon_status;
739                 WERROR admin_status;
740         } levels[] = {
741                  { 0,   WERR_OK,                WERR_OK },
742                  { 1,   WERR_OK,                WERR_OK },
743                  { 2,   WERR_ACCESS_DENIED,     WERR_OK },
744                  { 501, WERR_ACCESS_DENIED,     WERR_OK },
745                  { 502, WERR_ACCESS_DENIED,     WERR_OK },
746         };
747         int i;
748         BOOL ret = True;
749         uint32_t resume_handle;
750
751         ZERO_STRUCT(c0);
752
753         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
754         r.in.ctr.ctr0 = &c0;
755         r.in.max_buffer = (uint32_t)-1;
756         r.in.resume_handle = &resume_handle;
757         r.out.resume_handle = &resume_handle;
758
759         for (i=0;i<ARRAY_SIZE(levels);i++) {
760                 int j;
761                 WERROR expected;
762
763                 r.in.level = levels[i].level;
764                 expected = levels[i].anon_status;
765                 if (admin) expected = levels[i].admin_status;
766
767                 ZERO_STRUCT(r.out);
768                 resume_handle = 0;
769
770                 d_printf("testing NetShareEnumAll level %u\n", r.in.level);
771                 status = dcerpc_srvsvc_NetShareEnumAll(p, mem_ctx, &r);
772                 if (!NT_STATUS_IS_OK(status)) {
773                         d_printf("NetShareEnumAll level %u failed - %s\n", r.in.level, nt_errstr(status));
774                         ret = False;
775                         continue;
776                 }
777                 if (!W_ERROR_EQUAL(r.out.result, expected)) {
778                         d_printf("NetShareEnumAll level %u failed - %s (expected %s)\n",
779                                 r.in.level, win_errstr(r.out.result),
780                                 win_errstr(expected));
781                         continue;
782                 }
783
784                 /* call srvsvc_NetShareGetInfo for each returned share */
785                 if (r.in.level == 2 && r.out.ctr.ctr2) {
786                         for (j=0;j<r.out.ctr.ctr2->count;j++) {
787                                 const char *name;
788                                 name = r.out.ctr.ctr2->array[j].name;
789                                 if (!test_NetShareGetInfo(p, mem_ctx, name, admin)) {
790                                         ret = False;
791                                 }
792                         }
793                 }
794         }
795
796         return ret;
797 }
798
799 static BOOL test_NetShareEnum(struct dcerpc_pipe *p, 
800                               TALLOC_CTX *mem_ctx, BOOL admin)
801 {
802         NTSTATUS status;
803         struct srvsvc_NetShareEnum r;
804         struct srvsvc_NetShareCtr0 c0;
805         struct {
806                 uint32_t level;
807                 WERROR anon_status;
808                 WERROR admin_status;
809         } levels[] = {
810                  { 0,   WERR_OK,                WERR_OK },
811                  { 1,   WERR_OK,                WERR_OK },
812                  { 2,   WERR_ACCESS_DENIED,     WERR_OK },
813                  { 501, WERR_UNKNOWN_LEVEL,     WERR_UNKNOWN_LEVEL },
814                  { 502, WERR_ACCESS_DENIED,     WERR_OK },
815         };
816         int i;
817         BOOL ret = True;
818
819         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
820         r.in.ctr.ctr0 = &c0;
821         r.in.ctr.ctr0->count = 0;
822         r.in.ctr.ctr0->array = NULL;
823         r.in.max_buffer = (uint32_t)-1;
824         r.in.resume_handle = NULL;
825
826         for (i=0;i<ARRAY_SIZE(levels);i++) {
827                 WERROR expected;
828
829                 r.in.level = levels[i].level;
830                 expected = levels[i].anon_status;
831                 if (admin) expected = levels[i].admin_status;
832
833                 ZERO_STRUCT(r.out);
834
835                 d_printf("testing NetShareEnum level %u\n", r.in.level);
836                 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
837                 if (!NT_STATUS_IS_OK(status)) {
838                         d_printf("NetShareEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
839                         ret = False;
840                         continue;
841                 }
842                 if (!W_ERROR_EQUAL(r.out.result, expected)) {
843                         d_printf("NetShareEnum level %u failed - %s (expected %s)\n",
844                                 r.in.level, win_errstr(r.out.result),
845                                 win_errstr(expected));
846                         continue;
847                 }
848         }
849
850         return ret;
851 }
852
853 /**************************/
854 /* srvsvc_NetSrv          */
855 /**************************/
856 static BOOL test_NetSrvGetInfo(struct dcerpc_pipe *p, 
857                                  TALLOC_CTX *mem_ctx)
858 {
859         NTSTATUS status;
860         struct srvsvc_NetSrvGetInfo r;
861         struct srvsvc_NetSrvInfo503 i503;
862         uint32_t levels[] = {100, 101, 102, 502, 503};
863         int i;
864         BOOL ret = True;
865         uint32_t resume_handle;
866
867         ZERO_STRUCT(i503);
868
869         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
870
871         for (i=0;i<ARRAY_SIZE(levels);i++) {
872                 ZERO_STRUCT(r.out);
873                 resume_handle = 0;
874                 r.in.level = levels[i];
875                 d_printf("testing NetSrvGetInfo level %u\n", r.in.level);
876                 status = dcerpc_srvsvc_NetSrvGetInfo(p, mem_ctx, &r);
877                 if (!NT_STATUS_IS_OK(status)) {
878                         d_printf("NetSrvGetInfo level %u failed - %s\n", r.in.level, nt_errstr(status));
879                         ret = False;
880                         continue;
881                 }
882                 if (!W_ERROR_IS_OK(r.out.result)) {
883                         d_printf("NetSrvGetInfo level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
884                         continue;
885                 }
886         }
887
888         return ret;
889 }
890
891 /**************************/
892 /* srvsvc_NetDisk         */
893 /**************************/
894 static BOOL test_NetDiskEnum(struct dcerpc_pipe *p, 
895                            TALLOC_CTX *mem_ctx)
896 {
897         NTSTATUS status;
898         struct srvsvc_NetDiskEnum r;
899         uint32_t levels[] = {0};
900         int i;
901         BOOL ret = True;
902         uint32_t resume_handle=0;
903
904         ZERO_STRUCT(r.in);
905         r.in.server_unc = NULL;
906         r.in.resume_handle = &resume_handle;
907
908         for (i=0;i<ARRAY_SIZE(levels);i++) {
909                 ZERO_STRUCT(r.out);
910                 r.in.level = levels[i];
911                 d_printf("testing NetDiskEnum level %u\n", r.in.level);
912                 status = dcerpc_srvsvc_NetDiskEnum(p, mem_ctx, &r);
913                 if (!NT_STATUS_IS_OK(status)) {
914                         NDR_PRINT_OUT_DEBUG(srvsvc_NetDiskEnum, &r);
915                         d_printf("NetDiskEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
916                         ret = False;
917                         continue;
918                 }
919                 if (!W_ERROR_IS_OK(r.out.result)) {
920                         d_printf("NetDiskEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
921                         continue;
922                 }
923         }
924
925         return ret;
926 }
927
928 /**************************/
929 /* srvsvc_NetTransport    */
930 /**************************/
931 static BOOL test_NetTransportEnum(struct dcerpc_pipe *p, 
932                            TALLOC_CTX *mem_ctx)
933 {
934         NTSTATUS status;
935         struct srvsvc_NetTransportEnum r;
936         struct srvsvc_NetTransportCtr0 c0;
937         uint32_t levels[] = {0, 1};
938         int i;
939         BOOL ret = True;
940
941         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
942         r.in.transports.ctr0 = &c0;
943         r.in.transports.ctr0->count = 0;
944         r.in.transports.ctr0->array = NULL;
945         r.in.max_buffer = (uint32_t)-1;
946         r.in.resume_handle = NULL;
947
948         for (i=0;i<ARRAY_SIZE(levels);i++) {
949                 ZERO_STRUCT(r.out);
950                 r.in.level = levels[i];
951                 d_printf("testing NetTransportEnum level %u\n", r.in.level);
952                 status = dcerpc_srvsvc_NetTransportEnum(p, mem_ctx, &r);
953                 if (!NT_STATUS_IS_OK(status)) {
954                         d_printf("NetTransportEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
955                         ret = False;
956                         continue;
957                 }
958                 if (!W_ERROR_IS_OK(r.out.result)) {
959                         d_printf("NetTransportEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
960                         continue;
961                 }
962         }
963
964         return ret;
965 }
966
967 /**************************/
968 /* srvsvc_NetRemoteTOD    */
969 /**************************/
970 static BOOL test_NetRemoteTOD(struct dcerpc_pipe *p, 
971                            TALLOC_CTX *mem_ctx)
972 {
973         NTSTATUS status;
974         struct srvsvc_NetRemoteTOD r;
975         BOOL ret = True;
976
977         r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
978
979         ZERO_STRUCT(r.out);
980         d_printf("testing NetRemoteTOD\n");
981         status = dcerpc_srvsvc_NetRemoteTOD(p, mem_ctx, &r);
982         if (!NT_STATUS_IS_OK(status)) {
983                 d_printf("NetRemoteTOD failed - %s\n", nt_errstr(status));
984                 ret = False;
985         }
986         if (!W_ERROR_IS_OK(r.out.result)) {
987                 d_printf("NetRemoteTOD failed - %s\n", win_errstr(r.out.result));
988         }
989
990         return ret;
991 }
992
993 /**************************/
994 /* srvsvc_NetName         */
995 /**************************/
996
997 static BOOL test_NetNameValidate(struct dcerpc_pipe *p,
998                                  TALLOC_CTX *mem_ctx)
999 {
1000         NTSTATUS status;
1001         struct srvsvc_NetNameValidate r;
1002         char *invalidc;
1003         char *name;
1004         int i, n, min, max;
1005
1006         r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1007         r.in.flags = 0x0;
1008
1009         d_printf("testing NetNameValidate\n");
1010
1011         /* valid path types only between 1 and 13 */
1012         for (i = 1; i < 14; i++) {
1013
1014 again:
1015                 /* let's limit ourselves to a maximum of 4096 bytes */
1016                 r.in.name = name = talloc_array(mem_ctx, char, 4097);
1017                 max = 4096;
1018                 min = 0;
1019                 n = max;
1020
1021                 while (1) {
1022
1023                         /* Find maximum length accepted by this type */
1024                         ZERO_STRUCT(r.out);
1025                         r.in.name_type = i;
1026                         memset(name, 'A', n);
1027                         name[n] = '\0';
1028
1029                         status = dcerpc_srvsvc_NetNameValidate(p, mem_ctx, &r);
1030                         if (!NT_STATUS_IS_OK(status)) {
1031                                 d_printf("NetNameValidate failed while checking maximum size (%s)\n",
1032                                                 nt_errstr(status));
1033                                 break;
1034                         }
1035
1036                         if (W_ERROR_IS_OK(r.out.result)) {
1037                                 min = n;
1038                                 n += (max - min + 1)/2;
1039                                 continue;
1040                                 
1041                         } else {
1042                                 if ((min + 1) >= max) break; /* found it */
1043                                 
1044                                 max = n;
1045                                 n -= (max - min)/2;
1046                                 continue;
1047                         }
1048                 }
1049
1050                 talloc_free(r.in.name);
1051
1052                 d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
1053
1054                 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
1055
1056                 invalidc = talloc_strdup(mem_ctx, "");
1057
1058                 for (n = 0x20; n < 0x7e; n++) {
1059                         r.in.name = talloc_asprintf(mem_ctx, "%c", (char)n);
1060
1061                         status = dcerpc_srvsvc_NetNameValidate(p, mem_ctx, &r);
1062                         if (!NT_STATUS_IS_OK(status)) {
1063                                 d_printf("NetNameValidate failed while checking valid chars (%s)\n",
1064                                                 nt_errstr(status));
1065                                 break;
1066                         }
1067
1068                         if (!W_ERROR_IS_OK(r.out.result)) {
1069                                 invalidc = talloc_asprintf_append(invalidc, "%c", (char)n);
1070                         }
1071
1072                         talloc_free(r.in.name);
1073                 }
1074
1075                 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc);
1076
1077                 /* only two values are accepted for flags: 0x0 and 0x80000000 */
1078                 if (r.in.flags == 0x0) {
1079                         r.in.flags = 0x80000000;
1080                         goto again;
1081                 }
1082
1083                 r.in.flags = 0x0;
1084         }
1085
1086         return True;
1087 }
1088
1089 BOOL torture_rpc_srvsvc(struct torture_context *torture)
1090 {
1091         NTSTATUS status;
1092         struct dcerpc_pipe *p;
1093         TALLOC_CTX *mem_ctx;
1094         BOOL ret = True;
1095         const char *binding = lp_parm_string(-1, "torture", "binding");
1096         struct cli_credentials *anon_credentials;
1097
1098         mem_ctx = talloc_init("torture_rpc_srvsvc");
1099
1100         status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_srvsvc);
1101         if (!NT_STATUS_IS_OK(status)) {
1102                 talloc_free(mem_ctx);
1103                 return False;
1104         }
1105
1106         ret &= test_NetCharDevEnum(p, mem_ctx);
1107         ret &= test_NetCharDevQEnum(p, mem_ctx);
1108         ret &= test_NetConnEnum(p, mem_ctx);
1109         ret &= test_NetFileEnum(p, mem_ctx);
1110         ret &= test_NetSessEnum(p, mem_ctx);
1111         ret &= test_NetShareEnumAll(p, mem_ctx, True);
1112         ret &= test_NetSrvGetInfo(p, mem_ctx);
1113         ret &= test_NetDiskEnum(p, mem_ctx);
1114         ret &= test_NetTransportEnum(p, mem_ctx);
1115         ret &= test_NetRemoteTOD(p, mem_ctx);
1116         ret &= test_NetShareEnum(p, mem_ctx, True);
1117         ret &= test_NetShareGetInfo(p, mem_ctx, "ADMIN$", True);
1118 /*      ret &= test_NetShareAddSetDel(p, mem_ctx); */
1119         ret &= test_NetNameValidate(p, mem_ctx);
1120         
1121         status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_srvsvc);
1122
1123         if (!binding) {
1124                 d_printf("You must specify a ncacn binding string\n");
1125                 return False;
1126         }
1127
1128         anon_credentials = cli_credentials_init(mem_ctx);
1129         cli_credentials_set_conf(anon_credentials);
1130         cli_credentials_set_anonymous(anon_credentials);
1131
1132         status = dcerpc_pipe_connect(mem_ctx, 
1133                                      &p, binding, &dcerpc_table_srvsvc,
1134                                      anon_credentials, NULL);
1135         if (!NT_STATUS_IS_OK(status)) {
1136                 talloc_free(mem_ctx);
1137                 return False;
1138         }
1139
1140         ret &= test_NetShareEnumAll(p, mem_ctx, False);
1141         ret &= test_NetShareEnum(p, mem_ctx, False);
1142         ret &= test_NetShareGetInfo(p, mem_ctx, "ADMIN$", False);
1143
1144         talloc_free(mem_ctx);
1145
1146         return ret;
1147 }