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