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