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