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