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