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