s3-secdesc: remove "typedef struct security_descriptor SEC_DESC".
[samba.git] / source3 / rpc_server / srv_srvsvc_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  Copyright (C) Guenther Deschner            2008.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 3 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 /* This is the implementation of the srvsvc pipe. */
25
26 #include "includes.h"
27 #include "../librpc/gen_ndr/srv_srvsvc.h"
28 #include "librpc/gen_ndr/messaging.h"
29
30 extern const struct generic_mapping file_generic_mapping;
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_RPC_SRV
34
35 #define MAX_SERVER_DISK_ENTRIES 15
36
37 /* Use for enumerating connections, pipes, & files */
38
39 struct file_enum_count {
40         TALLOC_CTX *ctx;
41         const char *username;
42         struct srvsvc_NetFileCtr3 *ctr3;
43 };
44
45 struct sess_file_count {
46         struct server_id pid;
47         uid_t uid;
48         int count;
49 };
50
51 /****************************************************************************
52  Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
54
55 static int pipe_enum_fn( struct db_record *rec, void *p)
56 {
57         struct pipe_open_rec prec;
58         struct file_enum_count *fenum = (struct file_enum_count *)p;
59         struct srvsvc_NetFileInfo3 *f;
60         int i = fenum->ctr3->count;
61         char *fullpath = NULL;
62         const char *username;
63
64         if (rec->value.dsize != sizeof(struct pipe_open_rec))
65                 return 0;
66
67         memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
68
69         if ( !process_exists(prec.pid) ) {
70                 return 0;
71         }
72
73         username = uidtoname(prec.uid);
74
75         if ((fenum->username != NULL)
76             && !strequal(username, fenum->username)) {
77                 return 0;
78         }
79
80         fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
81         if (!fullpath) {
82                 return 1;
83         }
84
85         f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
86                                  struct srvsvc_NetFileInfo3, i+1);
87         if ( !f ) {
88                 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
89                 return 1;
90         }
91         fenum->ctr3->array = f;
92
93         fenum->ctr3->array[i].fid               =
94                 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
95         fenum->ctr3->array[i].permissions       =
96                 (FILE_READ_DATA|FILE_WRITE_DATA);
97         fenum->ctr3->array[i].num_locks         = 0;
98         fenum->ctr3->array[i].path              = fullpath;
99         fenum->ctr3->array[i].user              = username;
100
101         fenum->ctr3->count++;
102
103         return 0;
104 }
105
106 /*******************************************************************
107 ********************************************************************/
108
109 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
110                              const char *username,
111                              struct srvsvc_NetFileCtr3 **ctr3,
112                              uint32_t resume )
113 {
114         struct file_enum_count fenum;
115
116         fenum.ctx = ctx;
117         fenum.username = username;
118         fenum.ctr3 = *ctr3;
119
120         if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
121                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
122                          "failed\n"));
123                 return WERR_NOMEM;
124         }
125
126         *ctr3 = fenum.ctr3;
127
128         return WERR_OK;
129 }
130
131 /*******************************************************************
132 ********************************************************************/
133
134 static void enum_file_fn( const struct share_mode_entry *e,
135                           const char *sharepath, const char *fname,
136                           void *private_data )
137 {
138         struct file_enum_count *fenum =
139                 (struct file_enum_count *)private_data;
140
141         struct srvsvc_NetFileInfo3 *f;
142         int i = fenum->ctr3->count;
143         files_struct fsp;
144         struct byte_range_lock *brl;
145         int num_locks = 0;
146         char *fullpath = NULL;
147         uint32 permissions;
148         const char *username;
149
150         /* If the pid was not found delete the entry from connections.tdb */
151
152         if ( !process_exists(e->pid) ) {
153                 return;
154         }
155
156         username = uidtoname(e->uid);
157
158         if ((fenum->username != NULL)
159             && !strequal(username, fenum->username)) {
160                 return;
161         }
162
163         f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
164                                  struct srvsvc_NetFileInfo3, i+1);
165         if ( !f ) {
166                 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
167                 return;
168         }
169         fenum->ctr3->array = f;
170
171         /* need to count the number of locks on a file */
172
173         ZERO_STRUCT( fsp );
174         fsp.file_id = e->id;
175
176         if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
177                 num_locks = brl->num_locks;
178                 TALLOC_FREE(brl);
179         }
180
181         if ( strcmp( fname, "." ) == 0 ) {
182                 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
183         } else {
184                 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
185                                 sharepath, fname );
186         }
187         if (!fullpath) {
188                 return;
189         }
190         string_replace( fullpath, '/', '\\' );
191
192         /* mask out create (what ever that is) */
193         permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
194
195         /* now fill in the srvsvc_NetFileInfo3 struct */
196
197         fenum->ctr3->array[i].fid               =
198                 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
199         fenum->ctr3->array[i].permissions       = permissions;
200         fenum->ctr3->array[i].num_locks         = num_locks;
201         fenum->ctr3->array[i].path              = fullpath;
202         fenum->ctr3->array[i].user              = username;
203
204         fenum->ctr3->count++;
205 }
206
207 /*******************************************************************
208 ********************************************************************/
209
210 static WERROR net_enum_files(TALLOC_CTX *ctx,
211                              const char *username,
212                              struct srvsvc_NetFileCtr3 **ctr3,
213                              uint32_t resume)
214 {
215         struct file_enum_count f_enum_cnt;
216
217         f_enum_cnt.ctx = ctx;
218         f_enum_cnt.username = username;
219         f_enum_cnt.ctr3 = *ctr3;
220
221         share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
222
223         *ctr3 = f_enum_cnt.ctr3;
224
225         return WERR_OK;
226 }
227
228 /*******************************************************************
229  Utility function to get the 'type' of a share from an snum.
230  ********************************************************************/
231 static uint32 get_share_type(int snum)
232 {
233         /* work out the share type */
234         uint32 type = STYPE_DISKTREE;
235
236         if (lp_print_ok(snum))
237                 type = STYPE_PRINTQ;
238         if (strequal(lp_fstype(snum), "IPC"))
239                 type = STYPE_IPC;
240         if (lp_administrative_share(snum))
241                 type |= STYPE_HIDDEN;
242
243         return type;
244 }
245
246 /*******************************************************************
247  Fill in a share info level 0 structure.
248  ********************************************************************/
249
250 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
251 {
252         r->name         = lp_servicename(snum);
253 }
254
255 /*******************************************************************
256  Fill in a share info level 1 structure.
257  ********************************************************************/
258
259 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
260 {
261         char *net_name = lp_servicename(snum);
262         char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
263
264         if (remark) {
265                 remark = talloc_sub_advanced(
266                         p->mem_ctx, lp_servicename(snum),
267                         get_current_username(), lp_pathname(snum),
268                         p->server_info->utok.uid, get_current_username(),
269                         "", remark);
270         }
271
272         r->name         = net_name;
273         r->type         = get_share_type(snum);
274         r->comment      = remark ? remark : "";
275 }
276
277 /*******************************************************************
278  Fill in a share info level 2 structure.
279  ********************************************************************/
280
281 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
282 {
283         char *remark = NULL;
284         char *path = NULL;
285         int max_connections = lp_max_connections(snum);
286         uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
287         char *net_name = lp_servicename(snum);
288
289         remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
290         if (remark) {
291                 remark = talloc_sub_advanced(
292                         p->mem_ctx, lp_servicename(snum),
293                         get_current_username(), lp_pathname(snum),
294                         p->server_info->utok.uid, get_current_username(),
295                         "", remark);
296         }
297         path = talloc_asprintf(p->mem_ctx,
298                         "C:%s", lp_pathname(snum));
299
300         if (path) {
301                 /*
302                  * Change / to \\ so that win2k will see it as a valid path.
303                  * This was added to enable use of browsing in win2k add
304                  * share dialog.
305                  */
306
307                 string_replace(path, '/', '\\');
308         }
309
310         r->name                 = net_name;
311         r->type                 = get_share_type(snum);
312         r->comment              = remark ? remark : "";
313         r->permissions          = 0;
314         r->max_users            = max_uses;
315         r->current_users        = count_current_connections(net_name, false);
316         r->path                 = path ? path : "";
317         r->password             = "";
318 }
319
320 /*******************************************************************
321  Map any generic bits to file specific bits.
322 ********************************************************************/
323
324 static void map_generic_share_sd_bits(struct security_descriptor *psd)
325 {
326         int i;
327         struct security_acl *ps_dacl = NULL;
328
329         if (!psd)
330                 return;
331
332         ps_dacl = psd->dacl;
333         if (!ps_dacl)
334                 return;
335
336         for (i = 0; i < ps_dacl->num_aces; i++) {
337                 struct security_ace *psa = &ps_dacl->aces[i];
338                 uint32 orig_mask = psa->access_mask;
339
340                 se_map_generic(&psa->access_mask, &file_generic_mapping);
341                 psa->access_mask |= orig_mask;
342         }
343 }
344
345 /*******************************************************************
346  Fill in a share info level 501 structure.
347 ********************************************************************/
348
349 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
350 {
351         const char *net_name = lp_servicename(snum);
352         char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
353
354         if (remark) {
355                 remark = talloc_sub_advanced(
356                         p->mem_ctx, lp_servicename(snum),
357                         get_current_username(), lp_pathname(snum),
358                         p->server_info->utok.uid, get_current_username(),
359                         "", remark);
360         }
361
362         r->name         = net_name;
363         r->type         = get_share_type(snum);
364         r->comment      = remark ? remark : "";
365         r->csc_policy   = (lp_csc_policy(snum) << 4);
366 }
367
368 /*******************************************************************
369  Fill in a share info level 502 structure.
370  ********************************************************************/
371
372 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
373 {
374         const char *net_name = lp_servicename(snum);
375         char *path = NULL;
376         struct security_descriptor *sd = NULL;
377         struct sec_desc_buf *sd_buf = NULL;
378         size_t sd_size = 0;
379         TALLOC_CTX *ctx = p->mem_ctx;
380         char *remark = talloc_strdup(ctx, lp_comment(snum));;
381
382         if (remark) {
383                 remark = talloc_sub_advanced(
384                         p->mem_ctx, lp_servicename(snum),
385                         get_current_username(), lp_pathname(snum),
386                         p->server_info->utok.uid, get_current_username(),
387                         "", remark);
388         }
389         path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
390         if (path) {
391                 /*
392                  * Change / to \\ so that win2k will see it as a valid path.  This was added to
393                  * enable use of browsing in win2k add share dialog.
394                  */
395                 string_replace(path, '/', '\\');
396         }
397
398         sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
399
400         sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
401
402         r->name                 = net_name;
403         r->type                 = get_share_type(snum);
404         r->comment              = remark ? remark : "";
405         r->permissions          = 0;
406         r->max_users            = (uint32_t)-1;
407         r->current_users        = 1; /* ??? */
408         r->path                 = path ? path : "";
409         r->password             = "";
410         r->sd_buf               = *sd_buf;
411 }
412
413 /***************************************************************************
414  Fill in a share info level 1004 structure.
415  ***************************************************************************/
416
417 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
418 {
419         char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
420
421         if (remark) {
422                 remark = talloc_sub_advanced(
423                         p->mem_ctx, lp_servicename(snum),
424                         get_current_username(), lp_pathname(snum),
425                         p->server_info->utok.uid, get_current_username(),
426                         "", remark);
427         }
428
429         r->comment      = remark ? remark : "";
430 }
431
432 /***************************************************************************
433  Fill in a share info level 1005 structure.
434  ***************************************************************************/
435
436 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
437 {
438         uint32_t dfs_flags = 0;
439
440         if (lp_host_msdfs() && lp_msdfs_root(snum)) {
441                 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
442         }
443
444         dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
445
446         r->dfs_flags    = dfs_flags;
447 }
448
449 /***************************************************************************
450  Fill in a share info level 1006 structure.
451  ***************************************************************************/
452
453 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
454 {
455         r->max_users    = (uint32_t)-1;
456 }
457
458 /***************************************************************************
459  Fill in a share info level 1007 structure.
460  ***************************************************************************/
461
462 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
463 {
464         r->flags                        = 0;
465         r->alternate_directory_name     = "";
466 }
467
468 /*******************************************************************
469  Fill in a share info level 1501 structure.
470  ********************************************************************/
471
472 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
473 {
474         struct security_descriptor *sd;
475         size_t sd_size;
476         TALLOC_CTX *ctx = p->mem_ctx;
477
478         sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
479
480         r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
481 }
482
483 /*******************************************************************
484  True if it ends in '$'.
485  ********************************************************************/
486
487 static bool is_hidden_share(int snum)
488 {
489         const char *net_name = lp_servicename(snum);
490
491         return (net_name[strlen(net_name) - 1] == '$') ? True : False;
492 }
493
494 /*******************************************************************
495  Verify user is allowed to view share, access based enumeration
496 ********************************************************************/
497 static bool is_enumeration_allowed(pipes_struct *p,
498                                    int snum)
499 {
500     if (!lp_access_based_share_enum(snum))
501         return true;
502
503     return share_access_check(p->server_info->ptok, lp_servicename(snum),
504                               FILE_READ_DATA);
505 }
506
507 /*******************************************************************
508  Fill in a share info structure.
509  ********************************************************************/
510
511 static WERROR init_srv_share_info_ctr(pipes_struct *p,
512                                       struct srvsvc_NetShareInfoCtr *info_ctr,
513                                       uint32_t *resume_handle_p,
514                                       uint32_t *total_entries,
515                                       bool all_shares)
516 {
517         int num_entries = 0;
518         int alloc_entries = 0;
519         int num_services = 0;
520         int snum;
521         TALLOC_CTX *ctx = p->mem_ctx;
522         int i = 0;
523         int valid_share_count = 0;
524         bool *allowed = 0;
525         union srvsvc_NetShareCtr ctr;
526         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
527
528         DEBUG(5,("init_srv_share_info_ctr\n"));
529
530         /* Ensure all the usershares are loaded. */
531         become_root();
532         load_usershare_shares();
533         load_registry_shares();
534         num_services = lp_numservices();
535         unbecome_root();
536
537         allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
538         W_ERROR_HAVE_NO_MEMORY(allowed);
539
540         /* Count the number of entries. */
541         for (snum = 0; snum < num_services; snum++) {
542                 if (lp_browseable(snum) && lp_snum_ok(snum) &&
543                     is_enumeration_allowed(p, snum) &&
544                     (all_shares || !is_hidden_share(snum)) ) {
545                         DEBUG(10, ("counting service %s\n",
546                                 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
547                         allowed[snum] = true;
548                         num_entries++;
549                 } else {
550                         DEBUG(10, ("NOT counting service %s\n",
551                                 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
552                 }
553         }
554
555         if (!num_entries || (resume_handle >= num_entries)) {
556                 return WERR_OK;
557         }
558
559         /* Calculate alloc entries. */
560         alloc_entries = num_entries - resume_handle;
561         switch (info_ctr->level) {
562         case 0:
563                 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
564                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
565
566                 ctr.ctr0->count = alloc_entries;
567                 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
568                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
569
570                 for (snum = 0; snum < num_services; snum++) {
571                         if (allowed[snum] &&
572                             (resume_handle <= (i + valid_share_count++)) ) {
573                                 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
574                         }
575                 }
576
577                 break;
578
579         case 1:
580                 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
581                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
582
583                 ctr.ctr1->count = alloc_entries;
584                 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
585                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
586
587                 for (snum = 0; snum < num_services; snum++) {
588                         if (allowed[snum] &&
589                             (resume_handle <= (i + valid_share_count++)) ) {
590                                 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
591                         }
592                 }
593
594                 break;
595
596         case 2:
597                 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
598                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
599
600                 ctr.ctr2->count = alloc_entries;
601                 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
602                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
603
604                 for (snum = 0; snum < num_services; snum++) {
605                         if (allowed[snum] &&
606                             (resume_handle <= (i + valid_share_count++)) ) {
607                                 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
608                         }
609                 }
610
611                 break;
612
613         case 501:
614                 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
615                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
616
617                 ctr.ctr501->count = alloc_entries;
618                 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
619                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
620
621                 for (snum = 0; snum < num_services; snum++) {
622                         if (allowed[snum] &&
623                             (resume_handle <= (i + valid_share_count++)) ) {
624                                 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
625                         }
626                 }
627
628                 break;
629
630         case 502:
631                 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
632                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
633
634                 ctr.ctr502->count = alloc_entries;
635                 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
636                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
637
638                 for (snum = 0; snum < num_services; snum++) {
639                         if (allowed[snum] &&
640                             (resume_handle <= (i + valid_share_count++)) ) {
641                                 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
642                         }
643                 }
644
645                 break;
646
647         case 1004:
648                 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
649                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
650
651                 ctr.ctr1004->count = alloc_entries;
652                 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
653                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
654
655                 for (snum = 0; snum < num_services; snum++) {
656                         if (allowed[snum] &&
657                             (resume_handle <= (i + valid_share_count++)) ) {
658                                 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
659                         }
660                 }
661
662                 break;
663
664         case 1005:
665                 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
666                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
667
668                 ctr.ctr1005->count = alloc_entries;
669                 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
670                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
671
672                 for (snum = 0; snum < num_services; snum++) {
673                         if (allowed[snum] &&
674                             (resume_handle <= (i + valid_share_count++)) ) {
675                                 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
676                         }
677                 }
678
679                 break;
680
681         case 1006:
682                 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
683                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
684
685                 ctr.ctr1006->count = alloc_entries;
686                 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
687                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
688
689                 for (snum = 0; snum < num_services; snum++) {
690                         if (allowed[snum] &&
691                             (resume_handle <= (i + valid_share_count++)) ) {
692                                 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
693                         }
694                 }
695
696                 break;
697
698         case 1007:
699                 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
700                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
701
702                 ctr.ctr1007->count = alloc_entries;
703                 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
704                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
705
706                 for (snum = 0; snum < num_services; snum++) {
707                         if (allowed[snum] &&
708                             (resume_handle <= (i + valid_share_count++)) ) {
709                                 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
710                         }
711                 }
712
713                 break;
714
715         case 1501:
716                 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
717                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
718
719                 ctr.ctr1501->count = alloc_entries;
720                 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
721                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
722
723                 for (snum = 0; snum < num_services; snum++) {
724                         if (allowed[snum] &&
725                             (resume_handle <= (i + valid_share_count++)) ) {
726                                 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
727                         }
728                 }
729
730                 break;
731
732         default:
733                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
734                         info_ctr->level));
735                 return WERR_UNKNOWN_LEVEL;
736         }
737
738         *total_entries = alloc_entries;
739         if (resume_handle_p) {
740                 if (all_shares) {
741                         *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
742                 } else {
743                         *resume_handle_p = num_entries;
744                 }
745         }
746
747         info_ctr->ctr = ctr;
748
749         return WERR_OK;
750 }
751
752 /*******************************************************************
753  fill in a sess info level 0 structure.
754  ********************************************************************/
755
756 static WERROR init_srv_sess_info_0(pipes_struct *p,
757                                    struct srvsvc_NetSessCtr0 *ctr0,
758                                    uint32_t *resume_handle_p,
759                                    uint32_t *total_entries)
760 {
761         struct sessionid *session_list;
762         uint32_t num_entries = 0;
763         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
764         *total_entries = list_sessions(p->mem_ctx, &session_list);
765
766         DEBUG(5,("init_srv_sess_info_0\n"));
767
768         if (ctr0 == NULL) {
769                 if (resume_handle_p) {
770                         *resume_handle_p = 0;
771                 }
772                 return WERR_OK;
773         }
774
775         for (; resume_handle < *total_entries; resume_handle++) {
776
777                 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
778                                                    ctr0->array,
779                                                    struct srvsvc_NetSessInfo0,
780                                                    num_entries+1);
781                 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
782
783                 ctr0->array[num_entries].client =
784                         session_list[resume_handle].remote_machine;
785
786                 num_entries++;
787         }
788
789         ctr0->count = num_entries;
790
791         if (resume_handle_p) {
792                 if (*resume_handle_p >= *total_entries) {
793                         *resume_handle_p = 0;
794                 } else {
795                         *resume_handle_p = resume_handle;
796                 }
797         }
798
799         return WERR_OK;
800 }
801
802 /*******************************************************************
803 ********************************************************************/
804
805 static void sess_file_fn( const struct share_mode_entry *e,
806                           const char *sharepath, const char *fname,
807                           void *data )
808 {
809         struct sess_file_count *sess = (struct sess_file_count *)data;
810
811         if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
812                 sess->count++;
813         }
814
815         return;
816 }
817
818 /*******************************************************************
819 ********************************************************************/
820
821 static int net_count_files( uid_t uid, struct server_id pid )
822 {
823         struct sess_file_count s_file_cnt;
824
825         s_file_cnt.count = 0;
826         s_file_cnt.uid = uid;
827         s_file_cnt.pid = pid;
828
829         share_mode_forall( sess_file_fn, &s_file_cnt );
830
831         return s_file_cnt.count;
832 }
833
834 /*******************************************************************
835  fill in a sess info level 1 structure.
836  ********************************************************************/
837
838 static WERROR init_srv_sess_info_1(pipes_struct *p,
839                                    struct srvsvc_NetSessCtr1 *ctr1,
840                                    uint32_t *resume_handle_p,
841                                    uint32_t *total_entries)
842 {
843         struct sessionid *session_list;
844         uint32_t num_entries = 0;
845         time_t now = time(NULL);
846         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
847
848         ZERO_STRUCTP(ctr1);
849
850         if (ctr1 == NULL) {
851                 if (resume_handle_p) {
852                         *resume_handle_p = 0;
853                 }
854                 return WERR_OK;
855         }
856
857         *total_entries = list_sessions(p->mem_ctx, &session_list);
858
859         for (; resume_handle < *total_entries; resume_handle++) {
860                 uint32 num_files;
861                 uint32 connect_time;
862                 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
863                 bool guest;
864
865                 if ( !pw ) {
866                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
867                                 session_list[resume_handle].username));
868                         continue;
869                 }
870
871                 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
872                 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
873                 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
874
875                 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
876                                                    ctr1->array,
877                                                    struct srvsvc_NetSessInfo1,
878                                                    num_entries+1);
879                 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
880
881                 ctr1->array[num_entries].client         = session_list[resume_handle].remote_machine;
882                 ctr1->array[num_entries].user           = session_list[resume_handle].username;
883                 ctr1->array[num_entries].num_open       = num_files;
884                 ctr1->array[num_entries].time           = connect_time;
885                 ctr1->array[num_entries].idle_time      = 0;
886                 ctr1->array[num_entries].user_flags     = guest;
887
888                 num_entries++;
889         }
890
891         ctr1->count = num_entries;
892
893         if (resume_handle_p) {
894                 if (*resume_handle_p >= *total_entries) {
895                         *resume_handle_p = 0;
896                 } else {
897                         *resume_handle_p = resume_handle;
898                 }
899         }
900
901         return WERR_OK;
902 }
903
904 /*******************************************************************
905  fill in a conn info level 0 structure.
906  ********************************************************************/
907
908 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
909                                    uint32_t *resume_handle_p,
910                                    uint32_t *total_entries)
911 {
912         uint32_t num_entries = 0;
913         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
914
915         DEBUG(5,("init_srv_conn_info_0\n"));
916
917         if (ctr0 == NULL) {
918                 if (resume_handle_p) {
919                         *resume_handle_p = 0;
920                 }
921                 return WERR_OK;
922         }
923
924         *total_entries = 1;
925
926         ZERO_STRUCTP(ctr0);
927
928         for (; resume_handle < *total_entries; resume_handle++) {
929
930                 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
931                                                    ctr0->array,
932                                                    struct srvsvc_NetConnInfo0,
933                                                    num_entries+1);
934                 if (!ctr0->array) {
935                         return WERR_NOMEM;
936                 }
937
938                 ctr0->array[num_entries].conn_id = *total_entries;
939
940                 /* move on to creating next connection */
941                 num_entries++;
942         }
943
944         ctr0->count = num_entries;
945         *total_entries = num_entries;
946
947         if (resume_handle_p) {
948                 if (*resume_handle_p >= *total_entries) {
949                         *resume_handle_p = 0;
950                 } else {
951                         *resume_handle_p = resume_handle;
952                 }
953         }
954
955         return WERR_OK;
956 }
957
958 /*******************************************************************
959  fill in a conn info level 1 structure.
960  ********************************************************************/
961
962 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
963                                    uint32_t *resume_handle_p,
964                                    uint32_t *total_entries)
965 {
966         uint32_t num_entries = 0;
967         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
968
969         DEBUG(5,("init_srv_conn_info_1\n"));
970
971         if (ctr1 == NULL) {
972                 if (resume_handle_p) {
973                         *resume_handle_p = 0;
974                 }
975                 return WERR_OK;
976         }
977
978         *total_entries = 1;
979
980         ZERO_STRUCTP(ctr1);
981
982         for (; resume_handle < *total_entries; resume_handle++) {
983
984                 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
985                                                    ctr1->array,
986                                                    struct srvsvc_NetConnInfo1,
987                                                    num_entries+1);
988                 if (!ctr1->array) {
989                         return WERR_NOMEM;
990                 }
991
992                 ctr1->array[num_entries].conn_id        = *total_entries;
993                 ctr1->array[num_entries].conn_type      = 0x3;
994                 ctr1->array[num_entries].num_open       = 1;
995                 ctr1->array[num_entries].num_users      = 1;
996                 ctr1->array[num_entries].conn_time      = 3;
997                 ctr1->array[num_entries].user           = "dummy_user";
998                 ctr1->array[num_entries].share          = "IPC$";
999
1000                 /* move on to creating next connection */
1001                 num_entries++;
1002         }
1003
1004         ctr1->count = num_entries;
1005         *total_entries = num_entries;
1006
1007         if (resume_handle_p) {
1008                 if (*resume_handle_p >= *total_entries) {
1009                         *resume_handle_p = 0;
1010                 } else {
1011                         *resume_handle_p = resume_handle;
1012                 }
1013         }
1014
1015         return WERR_OK;
1016 }
1017
1018 /*******************************************************************
1019  _srvsvc_NetFileEnum
1020 *******************************************************************/
1021
1022 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
1023                            struct srvsvc_NetFileEnum *r)
1024 {
1025         TALLOC_CTX *ctx = NULL;
1026         struct srvsvc_NetFileCtr3 *ctr3;
1027         uint32_t resume_hnd = 0;
1028         WERROR werr;
1029
1030         switch (r->in.info_ctr->level) {
1031         case 3:
1032                 break;
1033         default:
1034                 return WERR_UNKNOWN_LEVEL;
1035         }
1036
1037         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1038                                 p->server_info->ptok)) {
1039                 DEBUG(1, ("Enumerating files only allowed for "
1040                           "administrators\n"));
1041                 return WERR_ACCESS_DENIED;
1042         }
1043
1044         ctx = talloc_tos();
1045         ctr3 = r->in.info_ctr->ctr.ctr3;
1046         if (!ctr3) {
1047                 werr = WERR_INVALID_PARAM;
1048                 goto done;
1049         }
1050
1051         /* TODO -- Windows enumerates
1052            (b) active pipes
1053            (c) open directories and files */
1054
1055         werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1056         if (!W_ERROR_IS_OK(werr)) {
1057                 goto done;
1058         }
1059
1060         werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1061         if (!W_ERROR_IS_OK(werr)) {
1062                 goto done;
1063         }
1064
1065         *r->out.totalentries = ctr3->count;
1066         r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1067         r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1068
1069         werr = WERR_OK;
1070
1071  done:
1072         return werr;
1073 }
1074
1075 /*******************************************************************
1076  _srvsvc_NetSrvGetInfo
1077 ********************************************************************/
1078
1079 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1080                              struct srvsvc_NetSrvGetInfo *r)
1081 {
1082         WERROR status = WERR_OK;
1083
1084         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1085
1086         if (!pipe_access_check(p)) {
1087                 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1088                 return WERR_ACCESS_DENIED;
1089         }
1090
1091         switch (r->in.level) {
1092
1093                 /* Technically level 102 should only be available to
1094                    Administrators but there isn't anything super-secret
1095                    here, as most of it is made up. */
1096
1097         case 102: {
1098                 struct srvsvc_NetSrvInfo102 *info102;
1099
1100                 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1101                 if (!info102) {
1102                         return WERR_NOMEM;
1103                 }
1104
1105                 info102->platform_id    = PLATFORM_ID_NT;
1106                 info102->server_name    = global_myname();
1107                 info102->version_major  = lp_major_announce_version();
1108                 info102->version_minor  = lp_minor_announce_version();
1109                 info102->server_type    = lp_default_server_announce();
1110                 info102->comment        = string_truncate(lp_serverstring(),
1111                                                 MAX_SERVER_STRING_LENGTH);
1112                 info102->users          = 0xffffffff;
1113                 info102->disc           = 0xf;
1114                 info102->hidden         = 0;
1115                 info102->announce       = 240;
1116                 info102->anndelta       = 3000;
1117                 info102->licenses       = 100000;
1118                 info102->userpath       = "C:\\";
1119
1120                 r->out.info->info102 = info102;
1121                 break;
1122         }
1123         case 101: {
1124                 struct srvsvc_NetSrvInfo101 *info101;
1125
1126                 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1127                 if (!info101) {
1128                         return WERR_NOMEM;
1129                 }
1130
1131                 info101->platform_id    = PLATFORM_ID_NT;
1132                 info101->server_name    = global_myname();
1133                 info101->version_major  = lp_major_announce_version();
1134                 info101->version_minor  = lp_minor_announce_version();
1135                 info101->server_type    = lp_default_server_announce();
1136                 info101->comment        = string_truncate(lp_serverstring(),
1137                                                 MAX_SERVER_STRING_LENGTH);
1138
1139                 r->out.info->info101 = info101;
1140                 break;
1141         }
1142         case 100: {
1143                 struct srvsvc_NetSrvInfo100 *info100;
1144
1145                 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1146                 if (!info100) {
1147                         return WERR_NOMEM;
1148                 }
1149
1150                 info100->platform_id    = PLATFORM_ID_NT;
1151                 info100->server_name    = global_myname();
1152
1153                 r->out.info->info100 = info100;
1154
1155                 break;
1156         }
1157         default:
1158                 status = WERR_UNKNOWN_LEVEL;
1159                 break;
1160         }
1161
1162         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1163
1164         return status;
1165 }
1166
1167 /*******************************************************************
1168  _srvsvc_NetSrvSetInfo
1169 ********************************************************************/
1170
1171 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1172                              struct srvsvc_NetSrvSetInfo *r)
1173 {
1174         WERROR status = WERR_OK;
1175
1176         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1177
1178         /* Set up the net server set info structure. */
1179
1180         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1181
1182         return status;
1183 }
1184
1185 /*******************************************************************
1186  _srvsvc_NetConnEnum
1187 ********************************************************************/
1188
1189 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1190                            struct srvsvc_NetConnEnum *r)
1191 {
1192         WERROR werr;
1193
1194         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1195
1196         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1197                                 p->server_info->ptok)) {
1198                 DEBUG(1, ("Enumerating connections only allowed for "
1199                           "administrators\n"));
1200                 return WERR_ACCESS_DENIED;
1201         }
1202
1203         switch (r->in.info_ctr->level) {
1204                 case 0:
1205                         werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1206                                                     r->in.resume_handle,
1207                                                     r->out.totalentries);
1208                         break;
1209                 case 1:
1210                         werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1211                                                     r->in.resume_handle,
1212                                                     r->out.totalentries);
1213                         break;
1214                 default:
1215                         return WERR_UNKNOWN_LEVEL;
1216         }
1217
1218         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1219
1220         return werr;
1221 }
1222
1223 /*******************************************************************
1224  _srvsvc_NetSessEnum
1225 ********************************************************************/
1226
1227 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1228                            struct srvsvc_NetSessEnum *r)
1229 {
1230         WERROR werr;
1231
1232         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1233
1234         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1235                                 p->server_info->ptok)) {
1236                 DEBUG(1, ("Enumerating sessions only allowed for "
1237                           "administrators\n"));
1238                 return WERR_ACCESS_DENIED;
1239         }
1240
1241         switch (r->in.info_ctr->level) {
1242                 case 0:
1243                         werr = init_srv_sess_info_0(p,
1244                                                     r->in.info_ctr->ctr.ctr0,
1245                                                     r->in.resume_handle,
1246                                                     r->out.totalentries);
1247                         break;
1248                 case 1:
1249                         werr = init_srv_sess_info_1(p,
1250                                                     r->in.info_ctr->ctr.ctr1,
1251                                                     r->in.resume_handle,
1252                                                     r->out.totalentries);
1253                         break;
1254                 default:
1255                         return WERR_UNKNOWN_LEVEL;
1256         }
1257
1258         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1259
1260         return werr;
1261 }
1262
1263 /*******************************************************************
1264  _srvsvc_NetSessDel
1265 ********************************************************************/
1266
1267 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1268                           struct srvsvc_NetSessDel *r)
1269 {
1270         struct sessionid *session_list;
1271         int num_sessions, snum;
1272         const char *username;
1273         const char *machine;
1274         bool not_root = False;
1275         WERROR werr;
1276
1277         username = r->in.user;
1278         machine = r->in.client;
1279
1280         /* strip leading backslashes if any */
1281         if (machine && machine[0] == '\\' && machine[1] == '\\') {
1282                 machine += 2;
1283         }
1284
1285         num_sessions = list_sessions(p->mem_ctx, &session_list);
1286
1287         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1288
1289         werr = WERR_ACCESS_DENIED;
1290
1291         /* fail out now if you are not root or not a domain admin */
1292
1293         if ((p->server_info->utok.uid != sec_initial_uid()) &&
1294                 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1295                                               DOMAIN_RID_ADMINS))) {
1296
1297                 goto done;
1298         }
1299
1300         for (snum = 0; snum < num_sessions; snum++) {
1301
1302                 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1303                     strequal(session_list[snum].remote_machine, machine)) {
1304
1305                         NTSTATUS ntstat;
1306
1307                         if (p->server_info->utok.uid != sec_initial_uid()) {
1308                                 not_root = True;
1309                                 become_root();
1310                         }
1311
1312                         ntstat = messaging_send(smbd_messaging_context(),
1313                                                 session_list[snum].pid,
1314                                                 MSG_SHUTDOWN, &data_blob_null);
1315
1316                         if (NT_STATUS_IS_OK(ntstat))
1317                                 werr = WERR_OK;
1318
1319                         if (not_root)
1320                                 unbecome_root();
1321                 }
1322         }
1323
1324         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1325
1326 done:
1327
1328         return werr;
1329 }
1330
1331 /*******************************************************************
1332  _srvsvc_NetShareEnumAll
1333 ********************************************************************/
1334
1335 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1336                                struct srvsvc_NetShareEnumAll *r)
1337 {
1338         WERROR werr;
1339
1340         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1341
1342         if (!pipe_access_check(p)) {
1343                 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1344                 return WERR_ACCESS_DENIED;
1345         }
1346
1347         /* Create the list of shares for the response. */
1348         werr = init_srv_share_info_ctr(p,
1349                                        r->in.info_ctr,
1350                                        r->in.resume_handle,
1351                                        r->out.totalentries,
1352                                        true);
1353
1354         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1355
1356         return werr;
1357 }
1358
1359 /*******************************************************************
1360  _srvsvc_NetShareEnum
1361 ********************************************************************/
1362
1363 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1364                             struct srvsvc_NetShareEnum *r)
1365 {
1366         WERROR werr;
1367
1368         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1369
1370         if (!pipe_access_check(p)) {
1371                 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1372                 return WERR_ACCESS_DENIED;
1373         }
1374
1375         /* Create the list of shares for the response. */
1376         werr = init_srv_share_info_ctr(p,
1377                                        r->in.info_ctr,
1378                                        r->in.resume_handle,
1379                                        r->out.totalentries,
1380                                        false);
1381
1382         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1383
1384         return werr;
1385 }
1386
1387 /*******************************************************************
1388  _srvsvc_NetShareGetInfo
1389 ********************************************************************/
1390
1391 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1392                                struct srvsvc_NetShareGetInfo *r)
1393 {
1394         WERROR status = WERR_OK;
1395         fstring share_name;
1396         int snum;
1397         union srvsvc_NetShareInfo *info = r->out.info;
1398
1399         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1400
1401         fstrcpy(share_name, r->in.share_name);
1402
1403         snum = find_service(share_name);
1404         if (snum < 0) {
1405                 return WERR_INVALID_NAME;
1406         }
1407
1408         switch (r->in.level) {
1409                 case 0:
1410                         info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1411                         W_ERROR_HAVE_NO_MEMORY(info->info0);
1412                         init_srv_share_info_0(p, info->info0, snum);
1413                         break;
1414                 case 1:
1415                         info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1416                         W_ERROR_HAVE_NO_MEMORY(info->info1);
1417                         init_srv_share_info_1(p, info->info1, snum);
1418                         break;
1419                 case 2:
1420                         info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1421                         W_ERROR_HAVE_NO_MEMORY(info->info2);
1422                         init_srv_share_info_2(p, info->info2, snum);
1423                         break;
1424                 case 501:
1425                         info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1426                         W_ERROR_HAVE_NO_MEMORY(info->info501);
1427                         init_srv_share_info_501(p, info->info501, snum);
1428                         break;
1429                 case 502:
1430                         info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1431                         W_ERROR_HAVE_NO_MEMORY(info->info502);
1432                         init_srv_share_info_502(p, info->info502, snum);
1433                         break;
1434                 case 1004:
1435                         info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1436                         W_ERROR_HAVE_NO_MEMORY(info->info1004);
1437                         init_srv_share_info_1004(p, info->info1004, snum);
1438                         break;
1439                 case 1005:
1440                         info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1441                         W_ERROR_HAVE_NO_MEMORY(info->info1005);
1442                         init_srv_share_info_1005(p, info->info1005, snum);
1443                         break;
1444                 case 1006:
1445                         info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1446                         W_ERROR_HAVE_NO_MEMORY(info->info1006);
1447                         init_srv_share_info_1006(p, info->info1006, snum);
1448                         break;
1449                 case 1007:
1450                         info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1451                         W_ERROR_HAVE_NO_MEMORY(info->info1007);
1452                         init_srv_share_info_1007(p, info->info1007, snum);
1453                         break;
1454                 case 1501:
1455                         init_srv_share_info_1501(p, info->info1501, snum);
1456                         break;
1457                 default:
1458                         DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1459                                 r->in.level));
1460                         status = WERR_UNKNOWN_LEVEL;
1461                         break;
1462         }
1463
1464         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1465
1466         return status;
1467 }
1468
1469 /*******************************************************************
1470  Check a given DOS pathname is valid for a share.
1471 ********************************************************************/
1472
1473 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1474 {
1475         char *ptr = NULL;
1476
1477         if (!dos_pathname) {
1478                 return NULL;
1479         }
1480
1481         ptr = talloc_strdup(ctx, dos_pathname);
1482         if (!ptr) {
1483                 return NULL;
1484         }
1485         /* Convert any '\' paths to '/' */
1486         unix_format(ptr);
1487         ptr = unix_clean_name(ctx, ptr);
1488         if (!ptr) {
1489                 return NULL;
1490         }
1491
1492         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1493         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1494                 ptr += 2;
1495
1496         /* Only absolute paths allowed. */
1497         if (*ptr != '/')
1498                 return NULL;
1499
1500         return ptr;
1501 }
1502
1503 /*******************************************************************
1504  _srvsvc_NetShareSetInfo. Modify share details.
1505 ********************************************************************/
1506
1507 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1508                                struct srvsvc_NetShareSetInfo *r)
1509 {
1510         char *command = NULL;
1511         char *share_name = NULL;
1512         char *comment = NULL;
1513         const char *pathname = NULL;
1514         int type;
1515         int snum;
1516         int ret;
1517         char *path = NULL;
1518         struct security_descriptor *psd = NULL;
1519         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1520         bool is_disk_op = False;
1521         int max_connections = 0;
1522         TALLOC_CTX *ctx = p->mem_ctx;
1523         union srvsvc_NetShareInfo *info = r->in.info;
1524
1525         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1526
1527         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1528         if (!share_name) {
1529                 return WERR_NOMEM;
1530         }
1531
1532         if (r->out.parm_error) {
1533                 *r->out.parm_error = 0;
1534         }
1535
1536         if ( strequal(share_name,"IPC$")
1537                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1538                 || strequal(share_name,"global") )
1539         {
1540                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1541                         "modified by a remote user.\n",
1542                         share_name ));
1543                 return WERR_ACCESS_DENIED;
1544         }
1545
1546         snum = find_service(share_name);
1547
1548         /* Does this share exist ? */
1549         if (snum < 0)
1550                 return WERR_NET_NAME_NOT_FOUND;
1551
1552         /* No change to printer shares. */
1553         if (lp_print_ok(snum))
1554                 return WERR_ACCESS_DENIED;
1555
1556         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1557
1558         /* fail out now if you are not root and not a disk op */
1559
1560         if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1561                 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1562                         "SeDiskOperatorPrivilege privilege needed to modify "
1563                         "share %s\n",
1564                         (unsigned int)p->server_info->utok.uid,
1565                         share_name ));
1566                 return WERR_ACCESS_DENIED;
1567         }
1568
1569         switch (r->in.level) {
1570         case 1:
1571                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1572                 comment = talloc_strdup(ctx, info->info1->comment);
1573                 type = info->info1->type;
1574                 psd = NULL;
1575                 break;
1576         case 2:
1577                 comment = talloc_strdup(ctx, info->info2->comment);
1578                 pathname = info->info2->path;
1579                 type = info->info2->type;
1580                 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1581                         0 : info->info2->max_users;
1582                 psd = NULL;
1583                 break;
1584 #if 0
1585                 /* not supported on set but here for completeness */
1586         case 501:
1587                 comment = talloc_strdup(ctx, info->info501->comment);
1588                 type = info->info501->type;
1589                 psd = NULL;
1590                 break;
1591 #endif
1592         case 502:
1593                 comment = talloc_strdup(ctx, info->info502->comment);
1594                 pathname = info->info502->path;
1595                 type = info->info502->type;
1596                 psd = info->info502->sd_buf.sd;
1597                 map_generic_share_sd_bits(psd);
1598                 break;
1599         case 1004:
1600                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1601                 comment = talloc_strdup(ctx, info->info1004->comment);
1602                 type = STYPE_DISKTREE;
1603                 break;
1604         case 1005:
1605                 /* XP re-sets the csc policy even if it wasn't changed by the
1606                    user, so we must compare it to see if it's what is set in
1607                    smb.conf, so that we can contine other ops like setting
1608                    ACLs on a share */
1609                 if (((info->info1005->dfs_flags &
1610                       SHARE_1005_CSC_POLICY_MASK) >>
1611                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1612                         return WERR_OK;
1613                 else {
1614                         DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1615                         return WERR_ACCESS_DENIED;
1616                 }
1617         case 1006:
1618         case 1007:
1619                 return WERR_ACCESS_DENIED;
1620         case 1501:
1621                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1622                 comment = talloc_strdup(ctx, lp_comment(snum));
1623                 psd = info->info1501->sd;
1624                 map_generic_share_sd_bits(psd);
1625                 type = STYPE_DISKTREE;
1626                 break;
1627         default:
1628                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1629                         r->in.level));
1630                 return WERR_UNKNOWN_LEVEL;
1631         }
1632
1633         /* We can only modify disk shares. */
1634         if (type != STYPE_DISKTREE) {
1635                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1636                         "disk share\n",
1637                         share_name ));
1638                 return WERR_ACCESS_DENIED;
1639         }
1640
1641         if (comment == NULL) {
1642                 return WERR_NOMEM;
1643         }
1644
1645         /* Check if the pathname is valid. */
1646         if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1647                 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1648                         pathname ));
1649                 return WERR_OBJECT_PATH_INVALID;
1650         }
1651
1652         /* Ensure share name, pathname and comment don't contain '"' characters. */
1653         string_replace(share_name, '"', ' ');
1654         string_replace(path, '"', ' ');
1655         string_replace(comment, '"', ' ');
1656
1657         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1658                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1659
1660         /* Only call modify function if something changed. */
1661
1662         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1663                         || (lp_max_connections(snum) != max_connections)) {
1664                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1665                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1666                         return WERR_ACCESS_DENIED;
1667                 }
1668
1669                 command = talloc_asprintf(p->mem_ctx,
1670                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1671                                 lp_change_share_cmd(),
1672                                 get_dyn_CONFIGFILE(),
1673                                 share_name,
1674                                 path,
1675                                 comment ? comment : "",
1676                                 max_connections);
1677                 if (!command) {
1678                         return WERR_NOMEM;
1679                 }
1680
1681                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1682
1683                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1684
1685                 if (is_disk_op)
1686                         become_root();
1687
1688                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1689                         /* Tell everyone we updated smb.conf. */
1690                         message_send_all(smbd_messaging_context(),
1691                                          MSG_SMB_CONF_UPDATED, NULL, 0,
1692                                          NULL);
1693                 }
1694
1695                 if ( is_disk_op )
1696                         unbecome_root();
1697
1698                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1699
1700                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1701                         command, ret ));
1702
1703                 TALLOC_FREE(command);
1704
1705                 if ( ret != 0 )
1706                         return WERR_ACCESS_DENIED;
1707         } else {
1708                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1709                         share_name ));
1710         }
1711
1712         /* Replace SD if changed. */
1713         if (psd) {
1714                 struct security_descriptor *old_sd;
1715                 size_t sd_size;
1716
1717                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1718
1719                 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1720                         if (!set_share_security(share_name, psd))
1721                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1722                                         share_name ));
1723                 }
1724         }
1725
1726         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1727
1728         return WERR_OK;
1729 }
1730
1731 /*******************************************************************
1732  _srvsvc_NetShareAdd.
1733  Call 'add_share_command "sharename" "pathname"
1734  "comment" "max connections = "
1735 ********************************************************************/
1736
1737 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1738                            struct srvsvc_NetShareAdd *r)
1739 {
1740         char *command = NULL;
1741         char *share_name = NULL;
1742         char *comment = NULL;
1743         char *pathname = NULL;
1744         int type;
1745         int snum;
1746         int ret;
1747         char *path;
1748         struct security_descriptor *psd = NULL;
1749         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1750         bool is_disk_op;
1751         int max_connections = 0;
1752         TALLOC_CTX *ctx = p->mem_ctx;
1753
1754         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1755
1756         if (r->out.parm_error) {
1757                 *r->out.parm_error = 0;
1758         }
1759
1760         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1761
1762         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1763                 return WERR_ACCESS_DENIED;
1764
1765         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1766                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1767                 return WERR_ACCESS_DENIED;
1768         }
1769
1770         switch (r->in.level) {
1771         case 0:
1772                 /* No path. Not enough info in a level 0 to do anything. */
1773                 return WERR_ACCESS_DENIED;
1774         case 1:
1775                 /* Not enough info in a level 1 to do anything. */
1776                 return WERR_ACCESS_DENIED;
1777         case 2:
1778                 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1779                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1780                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1781                 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1782                         0 : r->in.info->info2->max_users;
1783                 type = r->in.info->info2->type;
1784                 break;
1785         case 501:
1786                 /* No path. Not enough info in a level 501 to do anything. */
1787                 return WERR_ACCESS_DENIED;
1788         case 502:
1789                 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1790                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1791                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1792                 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1793                         0 : r->in.info->info502->max_users;
1794                 type = r->in.info->info502->type;
1795                 psd = r->in.info->info502->sd_buf.sd;
1796                 map_generic_share_sd_bits(psd);
1797                 break;
1798
1799                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1800
1801         case 1004:
1802         case 1005:
1803         case 1006:
1804         case 1007:
1805                 return WERR_ACCESS_DENIED;
1806         case 1501:
1807                 /* DFS only level. */
1808                 return WERR_ACCESS_DENIED;
1809         default:
1810                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1811                         r->in.level));
1812                 return WERR_UNKNOWN_LEVEL;
1813         }
1814
1815         /* check for invalid share names */
1816
1817         if (!share_name || !validate_net_name(share_name,
1818                                 INVALID_SHARENAME_CHARS,
1819                                 strlen(share_name))) {
1820                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1821                                         share_name ? share_name : ""));
1822                 return WERR_INVALID_NAME;
1823         }
1824
1825         if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1826                         || (lp_enable_asu_support() &&
1827                                         strequal(share_name,"ADMIN$"))) {
1828                 return WERR_ACCESS_DENIED;
1829         }
1830
1831         snum = find_service(share_name);
1832
1833         /* Share already exists. */
1834         if (snum >= 0) {
1835                 return WERR_FILE_EXISTS;
1836         }
1837
1838         /* We can only add disk shares. */
1839         if (type != STYPE_DISKTREE) {
1840                 return WERR_ACCESS_DENIED;
1841         }
1842
1843         /* Check if the pathname is valid. */
1844         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1845                 return WERR_OBJECT_PATH_INVALID;
1846         }
1847
1848         /* Ensure share name, pathname and comment don't contain '"' characters. */
1849         string_replace(share_name, '"', ' ');
1850         string_replace(path, '"', ' ');
1851         if (comment) {
1852                 string_replace(comment, '"', ' ');
1853         }
1854
1855         command = talloc_asprintf(ctx,
1856                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1857                         lp_add_share_cmd(),
1858                         get_dyn_CONFIGFILE(),
1859                         share_name,
1860                         path,
1861                         comment ? comment : "",
1862                         max_connections);
1863         if (!command) {
1864                 return WERR_NOMEM;
1865         }
1866
1867         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1868
1869         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1870
1871         if ( is_disk_op )
1872                 become_root();
1873
1874         /* FIXME: use libnetconf here - gd */
1875
1876         if ( (ret = smbrun(command, NULL)) == 0 ) {
1877                 /* Tell everyone we updated smb.conf. */
1878                 message_send_all(smbd_messaging_context(),
1879                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1880         }
1881
1882         if ( is_disk_op )
1883                 unbecome_root();
1884
1885         /********* END SeDiskOperatorPrivilege BLOCK *********/
1886
1887         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1888                 command, ret ));
1889
1890         TALLOC_FREE(command);
1891
1892         if ( ret != 0 )
1893                 return WERR_ACCESS_DENIED;
1894
1895         if (psd) {
1896                 if (!set_share_security(share_name, psd)) {
1897                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1898                                 share_name ));
1899                 }
1900         }
1901
1902         /*
1903          * We don't call reload_services() here, the message will
1904          * cause this to be done before the next packet is read
1905          * from the client. JRA.
1906          */
1907
1908         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1909
1910         return WERR_OK;
1911 }
1912
1913 /*******************************************************************
1914  _srvsvc_NetShareDel
1915  Call "delete share command" with the share name as
1916  a parameter.
1917 ********************************************************************/
1918
1919 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1920                            struct srvsvc_NetShareDel *r)
1921 {
1922         char *command = NULL;
1923         char *share_name = NULL;
1924         int ret;
1925         int snum;
1926         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1927         bool is_disk_op;
1928         struct share_params *params;
1929         TALLOC_CTX *ctx = p->mem_ctx;
1930
1931         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1932
1933         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1934         if (!share_name) {
1935                 return WERR_NET_NAME_NOT_FOUND;
1936         }
1937         if ( strequal(share_name,"IPC$")
1938                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1939                 || strequal(share_name,"global") )
1940         {
1941                 return WERR_ACCESS_DENIED;
1942         }
1943
1944         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1945                 return WERR_NO_SUCH_SHARE;
1946         }
1947
1948         snum = find_service(share_name);
1949
1950         /* No change to printer shares. */
1951         if (lp_print_ok(snum))
1952                 return WERR_ACCESS_DENIED;
1953
1954         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1955
1956         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1957                 return WERR_ACCESS_DENIED;
1958
1959         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1960                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1961                 return WERR_ACCESS_DENIED;
1962         }
1963
1964         command = talloc_asprintf(ctx,
1965                         "%s \"%s\" \"%s\"",
1966                         lp_delete_share_cmd(),
1967                         get_dyn_CONFIGFILE(),
1968                         lp_servicename(snum));
1969         if (!command) {
1970                 return WERR_NOMEM;
1971         }
1972
1973         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1974
1975         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1976
1977         if ( is_disk_op )
1978                 become_root();
1979
1980         if ( (ret = smbrun(command, NULL)) == 0 ) {
1981                 /* Tell everyone we updated smb.conf. */
1982                 message_send_all(smbd_messaging_context(),
1983                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1984         }
1985
1986         if ( is_disk_op )
1987                 unbecome_root();
1988
1989         /********* END SeDiskOperatorPrivilege BLOCK *********/
1990
1991         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1992
1993         if ( ret != 0 )
1994                 return WERR_ACCESS_DENIED;
1995
1996         /* Delete the SD in the database. */
1997         delete_share_security(lp_servicename(params->service));
1998
1999         lp_killservice(params->service);
2000
2001         return WERR_OK;
2002 }
2003
2004 /*******************************************************************
2005  _srvsvc_NetShareDelSticky
2006 ********************************************************************/
2007
2008 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
2009                                  struct srvsvc_NetShareDelSticky *r)
2010 {
2011         struct srvsvc_NetShareDel q;
2012
2013         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2014
2015         q.in.server_unc         = r->in.server_unc;
2016         q.in.share_name         = r->in.share_name;
2017         q.in.reserved           = r->in.reserved;
2018
2019         return _srvsvc_NetShareDel(p, &q);
2020 }
2021
2022 /*******************************************************************
2023  _srvsvc_NetRemoteTOD
2024 ********************************************************************/
2025
2026 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2027                             struct srvsvc_NetRemoteTOD *r)
2028 {
2029         struct srvsvc_NetRemoteTODInfo *tod;
2030         struct tm *t;
2031         time_t unixdate = time(NULL);
2032
2033         /* We do this call first as if we do it *after* the gmtime call
2034            it overwrites the pointed-to values. JRA */
2035
2036         uint32 zone = get_time_zone(unixdate)/60;
2037
2038         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2039
2040         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2041                 return WERR_NOMEM;
2042
2043         *r->out.info = tod;
2044
2045         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2046
2047         t = gmtime(&unixdate);
2048
2049         /* set up the */
2050         tod->elapsed    = unixdate;
2051         tod->msecs      = 0;
2052         tod->hours      = t->tm_hour;
2053         tod->mins       = t->tm_min;
2054         tod->secs       = t->tm_sec;
2055         tod->hunds      = 0;
2056         tod->timezone   = zone;
2057         tod->tinterval  = 10000;
2058         tod->day        = t->tm_mday;
2059         tod->month      = t->tm_mon + 1;
2060         tod->year       = 1900+t->tm_year;
2061         tod->weekday    = t->tm_wday;
2062
2063         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2064
2065         return WERR_OK;
2066 }
2067
2068 /***********************************************************************************
2069  _srvsvc_NetGetFileSecurity
2070  Win9x NT tools get security descriptor.
2071 ***********************************************************************************/
2072
2073 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2074                                   struct srvsvc_NetGetFileSecurity *r)
2075 {
2076         struct smb_filename *smb_fname = NULL;
2077         struct security_descriptor *psd = NULL;
2078         size_t sd_size;
2079         fstring servicename;
2080         SMB_STRUCT_STAT st;
2081         NTSTATUS nt_status;
2082         WERROR werr;
2083         connection_struct *conn = NULL;
2084         struct sec_desc_buf *sd_buf = NULL;
2085         files_struct *fsp = NULL;
2086         int snum;
2087         char *oldcwd = NULL;
2088
2089         ZERO_STRUCT(st);
2090
2091         fstrcpy(servicename, r->in.share);
2092
2093         snum = find_service(servicename);
2094         if (snum == -1) {
2095                 DEBUG(10, ("Could not find service %s\n", servicename));
2096                 werr = WERR_NET_NAME_NOT_FOUND;
2097                 goto error_exit;
2098         }
2099
2100         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2101                                        lp_pathname(snum), p->server_info,
2102                                        &oldcwd);
2103         if (!NT_STATUS_IS_OK(nt_status)) {
2104                 DEBUG(10, ("create_conn_struct failed: %s\n",
2105                            nt_errstr(nt_status)));
2106                 werr = ntstatus_to_werror(nt_status);
2107                 goto error_exit;
2108         }
2109
2110         nt_status = filename_convert(talloc_tos(),
2111                                         conn,
2112                                         false,
2113                                         r->in.file,
2114                                         0,
2115                                         NULL,
2116                                         &smb_fname);
2117         if (!NT_STATUS_IS_OK(nt_status)) {
2118                 werr = ntstatus_to_werror(nt_status);
2119                 goto error_exit;
2120         }
2121
2122         nt_status = SMB_VFS_CREATE_FILE(
2123                 conn,                                   /* conn */
2124                 NULL,                                   /* req */
2125                 0,                                      /* root_dir_fid */
2126                 smb_fname,                              /* fname */
2127                 FILE_READ_ATTRIBUTES,                   /* access_mask */
2128                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2129                 FILE_OPEN,                              /* create_disposition*/
2130                 0,                                      /* create_options */
2131                 0,                                      /* file_attributes */
2132                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2133                 0,                                      /* allocation_size */
2134                 0,                                      /* private_flags */
2135                 NULL,                                   /* sd */
2136                 NULL,                                   /* ea_list */
2137                 &fsp,                                   /* result */
2138                 NULL);                                  /* pinfo */
2139
2140         if (!NT_STATUS_IS_OK(nt_status)) {
2141                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2142                          smb_fname_str_dbg(smb_fname)));
2143                 werr = ntstatus_to_werror(nt_status);
2144                 goto error_exit;
2145         }
2146
2147         nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2148                                        (OWNER_SECURITY_INFORMATION
2149                                         |GROUP_SECURITY_INFORMATION
2150                                         |DACL_SECURITY_INFORMATION), &psd);
2151
2152         if (!NT_STATUS_IS_OK(nt_status)) {
2153                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2154                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
2155                 werr = ntstatus_to_werror(nt_status);
2156                 goto error_exit;
2157         }
2158
2159         sd_size = ndr_size_security_descriptor(psd, 0);
2160
2161         sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2162         if (!sd_buf) {
2163                 werr = WERR_NOMEM;
2164                 goto error_exit;
2165         }
2166
2167         sd_buf->sd_size = sd_size;
2168         sd_buf->sd = psd;
2169
2170         *r->out.sd_buf = sd_buf;
2171
2172         psd->dacl->revision = NT4_ACL_REVISION;
2173
2174         close_file(NULL, fsp, NORMAL_CLOSE);
2175         vfs_ChDir(conn, oldcwd);
2176         conn_free(conn);
2177         werr = WERR_OK;
2178         goto done;
2179
2180 error_exit:
2181
2182         if (fsp) {
2183                 close_file(NULL, fsp, NORMAL_CLOSE);
2184         }
2185
2186         if (oldcwd) {
2187                 vfs_ChDir(conn, oldcwd);
2188         }
2189
2190         if (conn) {
2191                 conn_free(conn);
2192         }
2193
2194  done:
2195         TALLOC_FREE(smb_fname);
2196
2197         return werr;
2198 }
2199
2200 /***********************************************************************************
2201  _srvsvc_NetSetFileSecurity
2202  Win9x NT tools set security descriptor.
2203 ***********************************************************************************/
2204
2205 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2206                                   struct srvsvc_NetSetFileSecurity *r)
2207 {
2208         struct smb_filename *smb_fname = NULL;
2209         fstring servicename;
2210         files_struct *fsp = NULL;
2211         SMB_STRUCT_STAT st;
2212         NTSTATUS nt_status;
2213         WERROR werr;
2214         connection_struct *conn = NULL;
2215         int snum;
2216         char *oldcwd = NULL;
2217         struct security_descriptor *psd = NULL;
2218         uint32_t security_info_sent = 0;
2219
2220         ZERO_STRUCT(st);
2221
2222         fstrcpy(servicename, r->in.share);
2223
2224         snum = find_service(servicename);
2225         if (snum == -1) {
2226                 DEBUG(10, ("Could not find service %s\n", servicename));
2227                 werr = WERR_NET_NAME_NOT_FOUND;
2228                 goto error_exit;
2229         }
2230
2231         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2232                                        lp_pathname(snum), p->server_info,
2233                                        &oldcwd);
2234         if (!NT_STATUS_IS_OK(nt_status)) {
2235                 DEBUG(10, ("create_conn_struct failed: %s\n",
2236                            nt_errstr(nt_status)));
2237                 werr = ntstatus_to_werror(nt_status);
2238                 goto error_exit;
2239         }
2240
2241         nt_status = filename_convert(talloc_tos(),
2242                                         conn,
2243                                         false,
2244                                         r->in.file,
2245                                         0,
2246                                         NULL,
2247                                         &smb_fname);
2248         if (!NT_STATUS_IS_OK(nt_status)) {
2249                 werr = ntstatus_to_werror(nt_status);
2250                 goto error_exit;
2251         }
2252
2253         nt_status = SMB_VFS_CREATE_FILE(
2254                 conn,                                   /* conn */
2255                 NULL,                                   /* req */
2256                 0,                                      /* root_dir_fid */
2257                 smb_fname,                              /* fname */
2258                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
2259                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2260                 FILE_OPEN,                              /* create_disposition*/
2261                 0,                                      /* create_options */
2262                 0,                                      /* file_attributes */
2263                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2264                 0,                                      /* allocation_size */
2265                 0,                                      /* private_flags */
2266                 NULL,                                   /* sd */
2267                 NULL,                                   /* ea_list */
2268                 &fsp,                                   /* result */
2269                 NULL);                                  /* pinfo */
2270
2271         if (!NT_STATUS_IS_OK(nt_status)) {
2272                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2273                          smb_fname_str_dbg(smb_fname)));
2274                 werr = ntstatus_to_werror(nt_status);
2275                 goto error_exit;
2276         }
2277
2278         psd = r->in.sd_buf->sd;
2279         security_info_sent = r->in.securityinformation;
2280
2281         if (psd->owner_sid==0) {
2282                 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2283         }
2284         if (psd->group_sid==0) {
2285                 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2286         }
2287         if (psd->sacl==0) {
2288                 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2289         }
2290         if (psd->dacl==0) {
2291                 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2292         }
2293
2294         /* Convert all the generic bits. */
2295         security_acl_map_generic(psd->dacl, &file_generic_mapping);
2296         security_acl_map_generic(psd->sacl, &file_generic_mapping);
2297
2298         nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2299                                         security_info_sent,
2300                                         psd);
2301
2302         if (!NT_STATUS_IS_OK(nt_status) ) {
2303                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2304                          "on file %s\n", r->in.share));
2305                 werr = WERR_ACCESS_DENIED;
2306                 goto error_exit;
2307         }
2308
2309         close_file(NULL, fsp, NORMAL_CLOSE);
2310         vfs_ChDir(conn, oldcwd);
2311         conn_free(conn);
2312         werr = WERR_OK;
2313         goto done;
2314
2315 error_exit:
2316
2317         if (fsp) {
2318                 close_file(NULL, fsp, NORMAL_CLOSE);
2319         }
2320
2321         if (oldcwd) {
2322                 vfs_ChDir(conn, oldcwd);
2323         }
2324
2325         if (conn) {
2326                 conn_free(conn);
2327         }
2328
2329  done:
2330         TALLOC_FREE(smb_fname);
2331
2332         return werr;
2333 }
2334
2335 /***********************************************************************************
2336  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2337  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2338  These disks would the disks listed by this function.
2339  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2340  "Nigel Williams" <nigel@veritas.com>.
2341 ***********************************************************************************/
2342
2343 static const char *server_disks[] = {"C:"};
2344
2345 static uint32 get_server_disk_count(void)
2346 {
2347         return sizeof(server_disks)/sizeof(server_disks[0]);
2348 }
2349
2350 static uint32 init_server_disk_enum(uint32 *resume)
2351 {
2352         uint32 server_disk_count = get_server_disk_count();
2353
2354         /*resume can be an offset into the list for now*/
2355
2356         if(*resume & 0x80000000)
2357                 *resume = 0;
2358
2359         if(*resume > server_disk_count)
2360                 *resume = server_disk_count;
2361
2362         return server_disk_count - *resume;
2363 }
2364
2365 static const char *next_server_disk_enum(uint32 *resume)
2366 {
2367         const char *disk;
2368
2369         if(init_server_disk_enum(resume) == 0)
2370                 return NULL;
2371
2372         disk = server_disks[*resume];
2373
2374         (*resume)++;
2375
2376         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2377
2378         return disk;
2379 }
2380
2381 /********************************************************************
2382  _srvsvc_NetDiskEnum
2383 ********************************************************************/
2384
2385 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2386                            struct srvsvc_NetDiskEnum *r)
2387 {
2388         uint32 i;
2389         const char *disk_name;
2390         TALLOC_CTX *ctx = p->mem_ctx;
2391         WERROR werr;
2392         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2393
2394         werr = WERR_OK;
2395
2396         *r->out.totalentries = init_server_disk_enum(&resume);
2397
2398         r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2399                                                MAX_SERVER_DISK_ENTRIES);
2400         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2401
2402         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2403
2404         r->out.info->count = 0;
2405
2406         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2407
2408                 r->out.info->count++;
2409
2410                 /*copy disk name into a unicode string*/
2411
2412                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2413                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2414         }
2415
2416         /* add a terminating null string.  Is this there if there is more data to come? */
2417
2418         r->out.info->count++;
2419
2420         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2421         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2422
2423         if (r->out.resume_handle) {
2424                 *r->out.resume_handle = resume;
2425         }
2426
2427         return werr;
2428 }
2429
2430 /********************************************************************
2431  _srvsvc_NetNameValidate
2432 ********************************************************************/
2433
2434 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2435                                struct srvsvc_NetNameValidate *r)
2436 {
2437         switch (r->in.name_type) {
2438         case 0x9:
2439                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2440                                        strlen_m(r->in.name)))
2441                 {
2442                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2443                                 r->in.name));
2444                         return WERR_INVALID_NAME;
2445                 }
2446                 break;
2447
2448         default:
2449                 return WERR_UNKNOWN_LEVEL;
2450         }
2451
2452         return WERR_OK;
2453 }
2454
2455 /*******************************************************************
2456 ********************************************************************/
2457
2458 static void enum_file_close_fn( const struct share_mode_entry *e,
2459                           const char *sharepath, const char *fname,
2460                           void *private_data )
2461 {
2462         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2463         struct srvsvc_NetFileClose *r =
2464                 (struct srvsvc_NetFileClose *)private_data;
2465         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2466
2467         if (fid != r->in.fid) {
2468                 return; /* Not this file. */
2469         }
2470
2471         if (!process_exists(e->pid) ) {
2472                 return;
2473         }
2474
2475         /* Ok - send the close message. */
2476         DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2477                 sharepath,
2478                 share_mode_str(talloc_tos(), 0, e) ));
2479
2480         share_mode_entry_to_message(msg, e);
2481
2482         r->out.result = ntstatus_to_werror(
2483                         messaging_send_buf(smbd_messaging_context(),
2484                                 e->pid, MSG_SMB_CLOSE_FILE,
2485                                 (uint8 *)msg,
2486                                 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2487 }
2488
2489 /********************************************************************
2490  Close a file given a 32-bit file id.
2491 ********************************************************************/
2492
2493 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2494 {
2495         SE_PRIV se_diskop = SE_DISK_OPERATOR;
2496         bool is_disk_op;
2497
2498         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2499
2500         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2501
2502         if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2503                 return WERR_ACCESS_DENIED;
2504         }
2505
2506         /* enum_file_close_fn sends the close message to
2507          * the relevent smbd process. */
2508
2509         r->out.result = WERR_BADFILE;
2510         share_mode_forall( enum_file_close_fn, (void *)r);
2511         return r->out.result;
2512 }
2513
2514 /********************************************************************
2515 ********************************************************************/
2516
2517 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2518 {
2519         p->rng_fault_state = True;
2520         return WERR_NOT_SUPPORTED;
2521 }
2522
2523 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2524 {
2525         p->rng_fault_state = True;
2526         return WERR_NOT_SUPPORTED;
2527 }
2528
2529 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2530 {
2531         p->rng_fault_state = True;
2532         return WERR_NOT_SUPPORTED;
2533 }
2534
2535 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2536 {
2537         p->rng_fault_state = True;
2538         return WERR_NOT_SUPPORTED;
2539 }
2540
2541 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2542 {
2543         p->rng_fault_state = True;
2544         return WERR_NOT_SUPPORTED;
2545 }
2546
2547 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2548 {
2549         p->rng_fault_state = True;
2550         return WERR_NOT_SUPPORTED;
2551 }
2552
2553 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2554 {
2555         p->rng_fault_state = True;
2556         return WERR_NOT_SUPPORTED;
2557 }
2558
2559 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2560 {
2561         p->rng_fault_state = True;
2562         return WERR_NOT_SUPPORTED;
2563 }
2564
2565 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2566 {
2567         p->rng_fault_state = True;
2568         return WERR_NOT_SUPPORTED;
2569 }
2570
2571 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2572 {
2573         p->rng_fault_state = True;
2574         return WERR_NOT_SUPPORTED;
2575 }
2576
2577 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2578 {
2579         p->rng_fault_state = True;
2580         return WERR_NOT_SUPPORTED;
2581 }
2582
2583 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2584 {
2585         p->rng_fault_state = True;
2586         return WERR_NOT_SUPPORTED;
2587 }
2588
2589 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2590 {
2591         p->rng_fault_state = True;
2592         return WERR_NOT_SUPPORTED;
2593 }
2594
2595 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2596 {
2597         p->rng_fault_state = True;
2598         return WERR_NOT_SUPPORTED;
2599 }
2600
2601 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2602 {
2603         p->rng_fault_state = True;
2604         return WERR_NOT_SUPPORTED;
2605 }
2606
2607 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2608 {
2609         p->rng_fault_state = True;
2610         return WERR_NOT_SUPPORTED;
2611 }
2612
2613 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2614 {
2615         p->rng_fault_state = True;
2616         return WERR_NOT_SUPPORTED;
2617 }
2618
2619 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2620 {
2621         p->rng_fault_state = True;
2622         return WERR_NOT_SUPPORTED;
2623 }
2624
2625 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2626 {
2627         p->rng_fault_state = True;
2628         return WERR_NOT_SUPPORTED;
2629 }
2630
2631 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2632 {
2633         p->rng_fault_state = True;
2634         return WERR_NOT_SUPPORTED;
2635 }
2636
2637 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2638 {
2639         p->rng_fault_state = True;
2640         return WERR_NOT_SUPPORTED;
2641 }
2642
2643 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2644 {
2645         p->rng_fault_state = True;
2646         return WERR_NOT_SUPPORTED;
2647 }
2648
2649 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2650 {
2651         p->rng_fault_state = True;
2652         return WERR_NOT_SUPPORTED;
2653 }
2654
2655 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2656 {
2657         p->rng_fault_state = True;
2658         return WERR_NOT_SUPPORTED;
2659 }
2660
2661 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2662 {
2663         p->rng_fault_state = True;
2664         return WERR_NOT_SUPPORTED;
2665 }
2666
2667 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2668 {
2669         p->rng_fault_state = True;
2670         return WERR_NOT_SUPPORTED;
2671 }
2672
2673 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2674 {
2675         p->rng_fault_state = True;
2676         return WERR_NOT_SUPPORTED;
2677 }
2678
2679 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2680 {
2681         p->rng_fault_state = True;
2682         return WERR_NOT_SUPPORTED;
2683 }
2684
2685 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2686 {
2687         p->rng_fault_state = True;
2688         return WERR_NOT_SUPPORTED;
2689 }
2690
2691 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2692 {
2693         p->rng_fault_state = True;
2694         return WERR_NOT_SUPPORTED;
2695 }
2696
2697 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2698 {
2699         p->rng_fault_state = True;
2700         return WERR_NOT_SUPPORTED;
2701 }
2702
2703 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2704 {
2705         p->rng_fault_state = True;
2706         return WERR_NOT_SUPPORTED;
2707 }
2708
2709 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2710 {
2711         p->rng_fault_state = True;
2712         return WERR_NOT_SUPPORTED;
2713 }
2714
2715 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2716 {
2717         p->rng_fault_state = True;
2718         return WERR_NOT_SUPPORTED;
2719 }
2720
2721 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2722 {
2723         p->rng_fault_state = True;
2724         return WERR_NOT_SUPPORTED;
2725 }
2726