2d34b9b4d1ce901fcd3980852b7662280df876dc
[kai/samba.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  Copyright (C) Guenther Deschner            2008.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 3 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 /* This is the implementation of the srvsvc pipe. */
25
26 #include "includes.h"
27 #include "system/passwd.h"
28 #include "ntdomain.h"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
34 #include "session.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
38 #include "auth.h"
39 #include "messages.h"
40 #include "lib/conn_tdb.h"
41
42 extern const struct generic_mapping file_generic_mapping;
43
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_RPC_SRV
46
47 #define MAX_SERVER_DISK_ENTRIES 15
48
49 /* Use for enumerating connections, pipes, & files */
50
51 struct file_enum_count {
52         TALLOC_CTX *ctx;
53         const char *username;
54         struct srvsvc_NetFileCtr3 *ctr3;
55 };
56
57 struct sess_file_count {
58         struct server_id pid;
59         uid_t uid;
60         int count;
61 };
62
63 /* Used to store pipe open records for NetFileEnum() */
64
65 struct pipe_open_rec {
66         struct server_id pid;
67         uid_t uid;
68         int pnum;
69         fstring name;
70 };
71
72 /****************************************************************************
73  Count the entries belonging to a service in the connection db.
74 ****************************************************************************/
75
76 static int pipe_enum_fn( struct db_record *rec, void *p)
77 {
78         struct pipe_open_rec prec;
79         struct file_enum_count *fenum = (struct file_enum_count *)p;
80         struct srvsvc_NetFileInfo3 *f;
81         int i = fenum->ctr3->count;
82         char *fullpath = NULL;
83         const char *username;
84         TDB_DATA value;
85
86         value = dbwrap_record_get_value(rec);
87
88         if (value.dsize != sizeof(struct pipe_open_rec))
89                 return 0;
90
91         memcpy(&prec, value.dptr, sizeof(struct pipe_open_rec));
92
93         if ( !process_exists(prec.pid) ) {
94                 return 0;
95         }
96
97         username = uidtoname(prec.uid);
98
99         if ((fenum->username != NULL)
100             && !strequal(username, fenum->username)) {
101                 return 0;
102         }
103
104         fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
105         if (!fullpath) {
106                 return 1;
107         }
108
109         f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
110                                  struct srvsvc_NetFileInfo3, i+1);
111         if ( !f ) {
112                 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
113                 return 1;
114         }
115         fenum->ctr3->array = f;
116
117         fenum->ctr3->array[i].fid               =
118                 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
119         fenum->ctr3->array[i].permissions       =
120                 (FILE_READ_DATA|FILE_WRITE_DATA);
121         fenum->ctr3->array[i].num_locks         = 0;
122         fenum->ctr3->array[i].path              = fullpath;
123         fenum->ctr3->array[i].user              = username;
124
125         fenum->ctr3->count++;
126
127         return 0;
128 }
129
130 /*******************************************************************
131 ********************************************************************/
132
133 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
134                              const char *username,
135                              struct srvsvc_NetFileCtr3 **ctr3,
136                              uint32_t resume )
137 {
138         struct file_enum_count fenum;
139
140         fenum.ctx = ctx;
141         fenum.username = username;
142         fenum.ctr3 = *ctr3;
143
144         if (connections_traverse(pipe_enum_fn, &fenum) < 0) {
145                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
146                          "failed\n"));
147                 return WERR_NOMEM;
148         }
149
150         *ctr3 = fenum.ctr3;
151
152         return WERR_OK;
153 }
154
155 /*******************************************************************
156 ********************************************************************/
157
158 static void enum_file_fn( const struct share_mode_entry *e,
159                           const char *sharepath, const char *fname,
160                           void *private_data )
161 {
162         struct file_enum_count *fenum =
163                 (struct file_enum_count *)private_data;
164
165         struct srvsvc_NetFileInfo3 *f;
166         int i = fenum->ctr3->count;
167         files_struct fsp;
168         struct byte_range_lock *brl;
169         int num_locks = 0;
170         char *fullpath = NULL;
171         uint32 permissions;
172         const char *username;
173
174         /* If the pid was not found delete the entry from connections.tdb */
175
176         if ( !process_exists(e->pid) ) {
177                 return;
178         }
179
180         username = uidtoname(e->uid);
181
182         if ((fenum->username != NULL)
183             && !strequal(username, fenum->username)) {
184                 return;
185         }
186
187         f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
188                                  struct srvsvc_NetFileInfo3, i+1);
189         if ( !f ) {
190                 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
191                 return;
192         }
193         fenum->ctr3->array = f;
194
195         /* need to count the number of locks on a file */
196
197         ZERO_STRUCT( fsp );
198         fsp.file_id = e->id;
199
200         if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
201                 num_locks = brl->num_locks;
202                 TALLOC_FREE(brl);
203         }
204
205         if ( strcmp( fname, "." ) == 0 ) {
206                 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
207         } else {
208                 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
209                                 sharepath, fname );
210         }
211         if (!fullpath) {
212                 return;
213         }
214         string_replace( fullpath, '/', '\\' );
215
216         /* mask out create (what ever that is) */
217         permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
218
219         /* now fill in the srvsvc_NetFileInfo3 struct */
220
221         fenum->ctr3->array[i].fid               =
222                 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
223         fenum->ctr3->array[i].permissions       = permissions;
224         fenum->ctr3->array[i].num_locks         = num_locks;
225         fenum->ctr3->array[i].path              = fullpath;
226         fenum->ctr3->array[i].user              = username;
227
228         fenum->ctr3->count++;
229 }
230
231 /*******************************************************************
232 ********************************************************************/
233
234 static WERROR net_enum_files(TALLOC_CTX *ctx,
235                              const char *username,
236                              struct srvsvc_NetFileCtr3 **ctr3,
237                              uint32_t resume)
238 {
239         struct file_enum_count f_enum_cnt;
240
241         f_enum_cnt.ctx = ctx;
242         f_enum_cnt.username = username;
243         f_enum_cnt.ctr3 = *ctr3;
244
245         share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
246
247         *ctr3 = f_enum_cnt.ctr3;
248
249         return WERR_OK;
250 }
251
252 /*******************************************************************
253  Utility function to get the 'type' of a share from an snum.
254  ********************************************************************/
255 static enum srvsvc_ShareType get_share_type(int snum)
256 {
257         /* work out the share type */
258         enum srvsvc_ShareType type = STYPE_DISKTREE;
259
260         if (lp_print_ok(snum)) {
261                 type = lp_administrative_share(snum)
262                         ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
263         }
264         if (strequal(lp_fstype(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         nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2189                                        (SECINFO_OWNER
2190                                         |SECINFO_GROUP
2191                                         |SECINFO_DACL), &psd);
2192
2193         if (!NT_STATUS_IS_OK(nt_status)) {
2194                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2195                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
2196                 werr = ntstatus_to_werror(nt_status);
2197                 goto error_exit;
2198         }
2199
2200         sd_size = ndr_size_security_descriptor(psd, 0);
2201
2202         sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2203         if (!sd_buf) {
2204                 werr = WERR_NOMEM;
2205                 goto error_exit;
2206         }
2207
2208         sd_buf->sd_size = sd_size;
2209         sd_buf->sd = psd;
2210
2211         *r->out.sd_buf = sd_buf;
2212
2213         psd->dacl->revision = NT4_ACL_REVISION;
2214
2215         close_file(NULL, fsp, NORMAL_CLOSE);
2216         vfs_ChDir(conn, oldcwd);
2217         SMB_VFS_DISCONNECT(conn);
2218         conn_free(conn);
2219         werr = WERR_OK;
2220         goto done;
2221
2222 error_exit:
2223
2224         if (fsp) {
2225                 close_file(NULL, fsp, NORMAL_CLOSE);
2226         }
2227
2228         if (oldcwd) {
2229                 vfs_ChDir(conn, oldcwd);
2230         }
2231
2232         if (conn) {
2233                 SMB_VFS_DISCONNECT(conn);
2234                 conn_free(conn);
2235         }
2236
2237  done:
2238         TALLOC_FREE(smb_fname);
2239
2240         return werr;
2241 }
2242
2243 /***********************************************************************************
2244  _srvsvc_NetSetFileSecurity
2245  Win9x NT tools set security descriptor.
2246 ***********************************************************************************/
2247
2248 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2249                                   struct srvsvc_NetSetFileSecurity *r)
2250 {
2251         struct smb_filename *smb_fname = NULL;
2252         char *servicename = NULL;
2253         files_struct *fsp = NULL;
2254         SMB_STRUCT_STAT st;
2255         NTSTATUS nt_status;
2256         WERROR werr;
2257         connection_struct *conn = NULL;
2258         int snum;
2259         char *oldcwd = NULL;
2260         struct security_descriptor *psd = NULL;
2261         uint32_t security_info_sent = 0;
2262
2263         ZERO_STRUCT(st);
2264
2265         if (!r->in.share) {
2266                 werr = WERR_NET_NAME_NOT_FOUND;
2267                 goto error_exit;
2268         }
2269
2270         snum = find_service(talloc_tos(), r->in.share, &servicename);
2271         if (!servicename) {
2272                 werr = WERR_NOMEM;
2273                 goto error_exit;
2274         }
2275
2276         if (snum == -1) {
2277                 DEBUG(10, ("Could not find service %s\n", servicename));
2278                 werr = WERR_NET_NAME_NOT_FOUND;
2279                 goto error_exit;
2280         }
2281
2282         nt_status = create_conn_struct(talloc_tos(),
2283                                        server_event_context(),
2284                                        server_messaging_context(),
2285                                        &conn,
2286                                        snum, lp_pathname(talloc_tos(), snum),
2287                                        p->session_info, &oldcwd);
2288         if (!NT_STATUS_IS_OK(nt_status)) {
2289                 DEBUG(10, ("create_conn_struct failed: %s\n",
2290                            nt_errstr(nt_status)));
2291                 werr = ntstatus_to_werror(nt_status);
2292                 goto error_exit;
2293         }
2294
2295         nt_status = filename_convert(talloc_tos(),
2296                                         conn,
2297                                         false,
2298                                         r->in.file,
2299                                         0,
2300                                         NULL,
2301                                         &smb_fname);
2302         if (!NT_STATUS_IS_OK(nt_status)) {
2303                 werr = ntstatus_to_werror(nt_status);
2304                 goto error_exit;
2305         }
2306
2307         nt_status = SMB_VFS_CREATE_FILE(
2308                 conn,                                   /* conn */
2309                 NULL,                                   /* req */
2310                 0,                                      /* root_dir_fid */
2311                 smb_fname,                              /* fname */
2312                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
2313                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2314                 FILE_OPEN,                              /* create_disposition*/
2315                 0,                                      /* create_options */
2316                 0,                                      /* file_attributes */
2317                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2318                 0,                                      /* allocation_size */
2319                 0,                                      /* private_flags */
2320                 NULL,                                   /* sd */
2321                 NULL,                                   /* ea_list */
2322                 &fsp,                                   /* result */
2323                 NULL);                                  /* pinfo */
2324
2325         if (!NT_STATUS_IS_OK(nt_status)) {
2326                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2327                          smb_fname_str_dbg(smb_fname)));
2328                 werr = ntstatus_to_werror(nt_status);
2329                 goto error_exit;
2330         }
2331
2332         psd = r->in.sd_buf->sd;
2333         security_info_sent = r->in.securityinformation;
2334
2335         nt_status = set_sd(fsp, psd, security_info_sent);
2336
2337         if (!NT_STATUS_IS_OK(nt_status) ) {
2338                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2339                          "on file %s\n", r->in.share));
2340                 werr = WERR_ACCESS_DENIED;
2341                 goto error_exit;
2342         }
2343
2344         close_file(NULL, fsp, NORMAL_CLOSE);
2345         vfs_ChDir(conn, oldcwd);
2346         SMB_VFS_DISCONNECT(conn);
2347         conn_free(conn);
2348         werr = WERR_OK;
2349         goto done;
2350
2351 error_exit:
2352
2353         if (fsp) {
2354                 close_file(NULL, fsp, NORMAL_CLOSE);
2355         }
2356
2357         if (oldcwd) {
2358                 vfs_ChDir(conn, oldcwd);
2359         }
2360
2361         if (conn) {
2362                 SMB_VFS_DISCONNECT(conn);
2363                 conn_free(conn);
2364         }
2365
2366  done:
2367         TALLOC_FREE(smb_fname);
2368
2369         return werr;
2370 }
2371
2372 /***********************************************************************************
2373  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2374  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2375  These disks would the disks listed by this function.
2376  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2377  "Nigel Williams" <nigel@veritas.com>.
2378 ***********************************************************************************/
2379
2380 static const char *server_disks[] = {"C:"};
2381
2382 static uint32 get_server_disk_count(void)
2383 {
2384         return sizeof(server_disks)/sizeof(server_disks[0]);
2385 }
2386
2387 static uint32 init_server_disk_enum(uint32 *resume)
2388 {
2389         uint32 server_disk_count = get_server_disk_count();
2390
2391         /*resume can be an offset into the list for now*/
2392
2393         if(*resume & 0x80000000)
2394                 *resume = 0;
2395
2396         if(*resume > server_disk_count)
2397                 *resume = server_disk_count;
2398
2399         return server_disk_count - *resume;
2400 }
2401
2402 static const char *next_server_disk_enum(uint32 *resume)
2403 {
2404         const char *disk;
2405
2406         if(init_server_disk_enum(resume) == 0)
2407                 return NULL;
2408
2409         disk = server_disks[*resume];
2410
2411         (*resume)++;
2412
2413         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2414
2415         return disk;
2416 }
2417
2418 /********************************************************************
2419  _srvsvc_NetDiskEnum
2420 ********************************************************************/
2421
2422 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2423                            struct srvsvc_NetDiskEnum *r)
2424 {
2425         uint32 i;
2426         const char *disk_name;
2427         TALLOC_CTX *ctx = p->mem_ctx;
2428         WERROR werr;
2429         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2430
2431         werr = WERR_OK;
2432
2433         *r->out.totalentries = init_server_disk_enum(&resume);
2434
2435         r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2436                                                MAX_SERVER_DISK_ENTRIES);
2437         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2438
2439         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2440
2441         r->out.info->count = 0;
2442
2443         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2444
2445                 r->out.info->count++;
2446
2447                 /*copy disk name into a unicode string*/
2448
2449                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2450                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2451         }
2452
2453         /* add a terminating null string.  Is this there if there is more data to come? */
2454
2455         r->out.info->count++;
2456
2457         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2458         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2459
2460         if (r->out.resume_handle) {
2461                 *r->out.resume_handle = resume;
2462         }
2463
2464         return werr;
2465 }
2466
2467 /********************************************************************
2468  _srvsvc_NetNameValidate
2469 ********************************************************************/
2470
2471 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2472                                struct srvsvc_NetNameValidate *r)
2473 {
2474         switch (r->in.name_type) {
2475         case 0x9:
2476                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2477                                        strlen_m(r->in.name)))
2478                 {
2479                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2480                                 r->in.name));
2481                         return WERR_INVALID_NAME;
2482                 }
2483                 break;
2484
2485         default:
2486                 return WERR_UNKNOWN_LEVEL;
2487         }
2488
2489         return WERR_OK;
2490 }
2491
2492 /*******************************************************************
2493 ********************************************************************/
2494
2495 struct enum_file_close_state {
2496         struct srvsvc_NetFileClose *r;
2497         struct messaging_context *msg_ctx;
2498 };
2499
2500 static void enum_file_close_fn( const struct share_mode_entry *e,
2501                           const char *sharepath, const char *fname,
2502                           void *private_data )
2503 {
2504         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2505         struct enum_file_close_state *state =
2506                 (struct enum_file_close_state *)private_data;
2507         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2508
2509         if (fid != state->r->in.fid) {
2510                 return; /* Not this file. */
2511         }
2512
2513         if (!process_exists(e->pid) ) {
2514                 return;
2515         }
2516
2517         /* Ok - send the close message. */
2518         DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2519                 sharepath,
2520                 share_mode_str(talloc_tos(), 0, e) ));
2521
2522         share_mode_entry_to_message(msg, e);
2523
2524         state->r->out.result = ntstatus_to_werror(
2525                 messaging_send_buf(state->msg_ctx,
2526                                 e->pid, MSG_SMB_CLOSE_FILE,
2527                                 (uint8 *)msg,
2528                                 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2529 }
2530
2531 /********************************************************************
2532  Close a file given a 32-bit file id.
2533 ********************************************************************/
2534
2535 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2536                             struct srvsvc_NetFileClose *r)
2537 {
2538         struct enum_file_close_state state;
2539         bool is_disk_op;
2540
2541         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2542
2543         is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2544
2545         if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2546                 return WERR_ACCESS_DENIED;
2547         }
2548
2549         /* enum_file_close_fn sends the close message to
2550          * the relevent smbd process. */
2551
2552         r->out.result = WERR_BADFILE;
2553         state.r = r;
2554         state.msg_ctx = p->msg_ctx;
2555         share_mode_forall(enum_file_close_fn, &state);
2556         return r->out.result;
2557 }
2558
2559 /********************************************************************
2560 ********************************************************************/
2561
2562 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2563                               struct srvsvc_NetCharDevEnum *r)
2564 {
2565         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2566         return WERR_NOT_SUPPORTED;
2567 }
2568
2569 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2570                                  struct srvsvc_NetCharDevGetInfo *r)
2571 {
2572         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2573         return WERR_NOT_SUPPORTED;
2574 }
2575
2576 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2577                                  struct srvsvc_NetCharDevControl *r)
2578 {
2579         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2580         return WERR_NOT_SUPPORTED;
2581 }
2582
2583 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2584                                struct srvsvc_NetCharDevQEnum *r)
2585 {
2586         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2587         return WERR_NOT_SUPPORTED;
2588 }
2589
2590 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2591                                   struct srvsvc_NetCharDevQGetInfo *r)
2592 {
2593         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2594         return WERR_NOT_SUPPORTED;
2595 }
2596
2597 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2598                                   struct srvsvc_NetCharDevQSetInfo *r)
2599 {
2600         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2601         return WERR_NOT_SUPPORTED;
2602 }
2603
2604 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2605                                 struct srvsvc_NetCharDevQPurge *r)
2606 {
2607         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2608         return WERR_NOT_SUPPORTED;
2609 }
2610
2611 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2612                                     struct srvsvc_NetCharDevQPurgeSelf *r)
2613 {
2614         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2615         return WERR_NOT_SUPPORTED;
2616 }
2617
2618 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2619                               struct srvsvc_NetFileGetInfo *r)
2620 {
2621         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2622         return WERR_NOT_SUPPORTED;
2623 }
2624
2625 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2626                              struct srvsvc_NetShareCheck *r)
2627 {
2628         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2629         return WERR_NOT_SUPPORTED;
2630 }
2631
2632 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2633                                       struct srvsvc_NetServerStatisticsGet *r)
2634 {
2635         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2636         return WERR_NOT_SUPPORTED;
2637 }
2638
2639 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2640                                struct srvsvc_NetTransportAdd *r)
2641 {
2642         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2643         return WERR_NOT_SUPPORTED;
2644 }
2645
2646 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2647                                 struct srvsvc_NetTransportEnum *r)
2648 {
2649         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2650         return WERR_NOT_SUPPORTED;
2651 }
2652
2653 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2654                                struct srvsvc_NetTransportDel *r)
2655 {
2656         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2657         return WERR_NOT_SUPPORTED;
2658 }
2659
2660 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2661                                  struct srvsvc_NetSetServiceBits *r)
2662 {
2663         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2664         return WERR_NOT_SUPPORTED;
2665 }
2666
2667 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2668                            struct srvsvc_NetPathType *r)
2669 {
2670         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2671         return WERR_NOT_SUPPORTED;
2672 }
2673
2674 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2675                                    struct srvsvc_NetPathCanonicalize *r)
2676 {
2677         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2678         return WERR_NOT_SUPPORTED;
2679 }
2680
2681 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2682                               struct srvsvc_NetPathCompare *r)
2683 {
2684         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2685         return WERR_NOT_SUPPORTED;
2686 }
2687
2688 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2689                                       struct srvsvc_NETRPRNAMECANONICALIZE *r)
2690 {
2691         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2692         return WERR_NOT_SUPPORTED;
2693 }
2694
2695 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2696                                 struct srvsvc_NetPRNameCompare *r)
2697 {
2698         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2699         return WERR_NOT_SUPPORTED;
2700 }
2701
2702 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2703                                 struct srvsvc_NetShareDelStart *r)
2704 {
2705         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2706         return WERR_NOT_SUPPORTED;
2707 }
2708
2709 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2710                                  struct srvsvc_NetShareDelCommit *r)
2711 {
2712         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2713         return WERR_NOT_SUPPORTED;
2714 }
2715
2716 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2717                                        struct srvsvc_NetServerTransportAddEx *r)
2718 {
2719         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2720         return WERR_NOT_SUPPORTED;
2721 }
2722
2723 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2724                                          struct srvsvc_NetServerSetServiceBitsEx *r)
2725 {
2726         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2727         return WERR_NOT_SUPPORTED;
2728 }
2729
2730 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2731                                  struct srvsvc_NETRDFSGETVERSION *r)
2732 {
2733         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2734         return WERR_NOT_SUPPORTED;
2735 }
2736
2737 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2738                                            struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2739 {
2740         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2741         return WERR_NOT_SUPPORTED;
2742 }
2743
2744 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2745                                            struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2746 {
2747         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2748         return WERR_NOT_SUPPORTED;
2749 }
2750
2751 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2752                                           struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2753 {
2754         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2755         return WERR_NOT_SUPPORTED;
2756 }
2757
2758 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2759                                     struct srvsvc_NETRDFSSETSERVERINFO *r)
2760 {
2761         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2762         return WERR_NOT_SUPPORTED;
2763 }
2764
2765 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2766                                       struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2767 {
2768         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2769         return WERR_NOT_SUPPORTED;
2770 }
2771
2772 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2773                                       struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2774 {
2775         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2776         return WERR_NOT_SUPPORTED;
2777 }
2778
2779 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2780                                    struct srvsvc_NETRDFSMODIFYPREFIX *r)
2781 {
2782         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2783         return WERR_NOT_SUPPORTED;
2784 }
2785
2786 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2787                                      struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2788 {
2789         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2790         return WERR_NOT_SUPPORTED;
2791 }
2792
2793 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2794                                             struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2795 {
2796         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2797         return WERR_NOT_SUPPORTED;
2798 }
2799
2800 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2801                                         struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2802 {
2803         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2804         return WERR_NOT_SUPPORTED;
2805 }