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