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