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