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