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