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