fdf42ea030b47153729b7193917d4e3a1a12c0ec
[sfrench/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, NULL);
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                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\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                                  NULL);
2116         }
2117
2118         if ( is_disk_op )
2119                 unbecome_root();
2120
2121         /********* END SeDiskOperatorPrivilege BLOCK *********/
2122
2123         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2124                 command, ret ));
2125
2126         TALLOC_FREE(command);
2127
2128         if ( ret != 0 )
2129                 return WERR_ACCESS_DENIED;
2130
2131         if (psd) {
2132                 /* Note we use share_name here, not share_name_in as
2133                    we need a canonicalized name for setting security. */
2134                 if (!set_share_security(share_name, psd)) {
2135                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2136                                 share_name ));
2137                 }
2138         }
2139
2140         /*
2141          * We don't call reload_services() here, the message will
2142          * cause this to be done before the next packet is read
2143          * from the client. JRA.
2144          */
2145
2146         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2147
2148         return WERR_OK;
2149 }
2150
2151 /*******************************************************************
2152  _srvsvc_NetShareDel
2153  Call "delete share command" with the share name as
2154  a parameter.
2155 ********************************************************************/
2156
2157 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2158                            struct srvsvc_NetShareDel *r)
2159 {
2160         char *command = NULL;
2161         char *share_name = NULL;
2162         int ret;
2163         int snum;
2164         bool is_disk_op;
2165         TALLOC_CTX *ctx = p->mem_ctx;
2166
2167         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2168
2169         if (!r->in.share_name) {
2170                 return WERR_NERR_NETNAMENOTFOUND;
2171         }
2172
2173         if ( strequal(r->in.share_name,"IPC$")
2174                 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2175                 || strequal(r->in.share_name,"global") )
2176         {
2177                 return WERR_ACCESS_DENIED;
2178         }
2179
2180         snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2181         if (!share_name) {
2182                 return WERR_NOT_ENOUGH_MEMORY;
2183         }
2184
2185         if (snum < 0) {
2186                 return WERR_BAD_NET_NAME;
2187         }
2188
2189         /* No change to printer shares. */
2190         if (lp_printable(snum))
2191                 return WERR_ACCESS_DENIED;
2192
2193         is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2194
2195         if (p->session_info->unix_token->uid != sec_initial_uid()  && !is_disk_op )
2196                 return WERR_ACCESS_DENIED;
2197
2198         if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2199                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2200                 return WERR_ACCESS_DENIED;
2201         }
2202
2203         command = talloc_asprintf(ctx,
2204                         "%s \"%s\" \"%s\"",
2205                         lp_delete_share_command(talloc_tos()),
2206                         get_dyn_CONFIGFILE(),
2207                         share_name);
2208         if (!command) {
2209                 return WERR_NOT_ENOUGH_MEMORY;
2210         }
2211
2212         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2213
2214         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2215
2216         if ( is_disk_op )
2217                 become_root();
2218
2219         ret = smbrun(command, NULL, NULL);
2220         if (ret == 0) {
2221                 /* Tell everyone we updated smb.conf. */
2222                 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2223                                  NULL);
2224         }
2225
2226         if ( is_disk_op )
2227                 unbecome_root();
2228
2229         /********* END SeDiskOperatorPrivilege BLOCK *********/
2230
2231         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2232
2233         if ( ret != 0 )
2234                 return WERR_ACCESS_DENIED;
2235
2236         /* Delete the SD in the database. */
2237         delete_share_security(share_name);
2238
2239         lp_killservice(snum);
2240
2241         return WERR_OK;
2242 }
2243
2244 /*******************************************************************
2245  _srvsvc_NetShareDelSticky
2246 ********************************************************************/
2247
2248 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2249                                  struct srvsvc_NetShareDelSticky *r)
2250 {
2251         struct srvsvc_NetShareDel q;
2252
2253         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2254
2255         q.in.server_unc         = r->in.server_unc;
2256         q.in.share_name         = r->in.share_name;
2257         q.in.reserved           = r->in.reserved;
2258
2259         return _srvsvc_NetShareDel(p, &q);
2260 }
2261
2262 /*******************************************************************
2263  _srvsvc_NetRemoteTOD
2264 ********************************************************************/
2265
2266 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2267                             struct srvsvc_NetRemoteTOD *r)
2268 {
2269         struct srvsvc_NetRemoteTODInfo *tod;
2270         struct tm *t;
2271         time_t unixdate = time(NULL);
2272
2273         /* We do this call first as if we do it *after* the gmtime call
2274            it overwrites the pointed-to values. JRA */
2275
2276         uint32_t zone = get_time_zone(unixdate)/60;
2277
2278         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2279
2280         if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2281                 return WERR_NOT_ENOUGH_MEMORY;
2282
2283         *r->out.info = tod;
2284
2285         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2286
2287         t = gmtime(&unixdate);
2288
2289         /* set up the */
2290         tod->elapsed    = unixdate;
2291         tod->msecs      = 0;
2292         tod->hours      = t->tm_hour;
2293         tod->mins       = t->tm_min;
2294         tod->secs       = t->tm_sec;
2295         tod->hunds      = 0;
2296         tod->timezone   = zone;
2297         tod->tinterval  = 10000;
2298         tod->day        = t->tm_mday;
2299         tod->month      = t->tm_mon + 1;
2300         tod->year       = 1900+t->tm_year;
2301         tod->weekday    = t->tm_wday;
2302
2303         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2304
2305         return WERR_OK;
2306 }
2307
2308 /***********************************************************************************
2309  _srvsvc_NetGetFileSecurity
2310  Win9x NT tools get security descriptor.
2311 ***********************************************************************************/
2312
2313 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2314                                   struct srvsvc_NetGetFileSecurity *r)
2315 {
2316         struct smb_filename *smb_fname = NULL;
2317         size_t sd_size;
2318         char *servicename = NULL;
2319         SMB_STRUCT_STAT st;
2320         NTSTATUS nt_status;
2321         WERROR werr;
2322         connection_struct *conn = NULL;
2323         struct sec_desc_buf *sd_buf = NULL;
2324         files_struct *fsp = NULL;
2325         int snum;
2326         char *oldcwd = NULL;
2327         uint32_t ucf_flags = 0;
2328
2329         ZERO_STRUCT(st);
2330
2331         if (!r->in.share) {
2332                 werr = WERR_NERR_NETNAMENOTFOUND;
2333                 goto error_exit;
2334         }
2335         snum = find_service(talloc_tos(), r->in.share, &servicename);
2336         if (!servicename) {
2337                 werr = WERR_NOT_ENOUGH_MEMORY;
2338                 goto error_exit;
2339         }
2340         if (snum == -1) {
2341                 DEBUG(10, ("Could not find service %s\n", servicename));
2342                 werr = WERR_NERR_NETNAMENOTFOUND;
2343                 goto error_exit;
2344         }
2345
2346         nt_status = create_conn_struct_cwd(talloc_tos(),
2347                                            server_event_context(),
2348                                            server_messaging_context(),
2349                                            &conn,
2350                                            snum, lp_path(talloc_tos(), snum),
2351                                            p->session_info, &oldcwd);
2352         if (!NT_STATUS_IS_OK(nt_status)) {
2353                 DEBUG(10, ("create_conn_struct failed: %s\n",
2354                            nt_errstr(nt_status)));
2355                 werr = ntstatus_to_werror(nt_status);
2356                 goto error_exit;
2357         }
2358
2359         nt_status = filename_convert(talloc_tos(),
2360                                         conn,
2361                                         r->in.file,
2362                                         ucf_flags,
2363                                         NULL,
2364                                         &smb_fname);
2365         if (!NT_STATUS_IS_OK(nt_status)) {
2366                 werr = ntstatus_to_werror(nt_status);
2367                 goto error_exit;
2368         }
2369
2370         nt_status = SMB_VFS_CREATE_FILE(
2371                 conn,                                   /* conn */
2372                 NULL,                                   /* req */
2373                 0,                                      /* root_dir_fid */
2374                 smb_fname,                              /* fname */
2375                 FILE_READ_ATTRIBUTES,                   /* access_mask */
2376                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2377                 FILE_OPEN,                              /* create_disposition*/
2378                 0,                                      /* create_options */
2379                 0,                                      /* file_attributes */
2380                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2381                 NULL,                                   /* lease */
2382                 0,                                      /* allocation_size */
2383                 0,                                      /* private_flags */
2384                 NULL,                                   /* sd */
2385                 NULL,                                   /* ea_list */
2386                 &fsp,                                   /* result */
2387                 NULL,                                   /* pinfo */
2388                 NULL, NULL);                            /* create context */
2389
2390         if (!NT_STATUS_IS_OK(nt_status)) {
2391                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2392                          smb_fname_str_dbg(smb_fname)));
2393                 werr = ntstatus_to_werror(nt_status);
2394                 goto error_exit;
2395         }
2396
2397         sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2398         if (!sd_buf) {
2399                 werr = WERR_NOT_ENOUGH_MEMORY;
2400                 goto error_exit;
2401         }
2402
2403         nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2404                                        (SECINFO_OWNER
2405                                         |SECINFO_GROUP
2406                                         |SECINFO_DACL), sd_buf, &sd_buf->sd);
2407
2408         if (!NT_STATUS_IS_OK(nt_status)) {
2409                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2410                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
2411                 werr = ntstatus_to_werror(nt_status);
2412                 TALLOC_FREE(sd_buf);
2413                 goto error_exit;
2414         }
2415
2416         if (sd_buf->sd->dacl) {
2417                 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2418         }
2419
2420         sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2421
2422         sd_buf->sd_size = sd_size;
2423
2424         *r->out.sd_buf = sd_buf;
2425
2426         close_file(NULL, fsp, NORMAL_CLOSE);
2427         vfs_ChDir(conn, oldcwd);
2428         SMB_VFS_DISCONNECT(conn);
2429         conn_free(conn);
2430         werr = WERR_OK;
2431         goto done;
2432
2433 error_exit:
2434
2435         if (fsp) {
2436                 close_file(NULL, fsp, NORMAL_CLOSE);
2437         }
2438
2439         if (oldcwd) {
2440                 vfs_ChDir(conn, oldcwd);
2441         }
2442
2443         if (conn) {
2444                 SMB_VFS_DISCONNECT(conn);
2445                 conn_free(conn);
2446         }
2447
2448  done:
2449
2450         TALLOC_FREE(smb_fname);
2451
2452         return werr;
2453 }
2454
2455 /***********************************************************************************
2456  _srvsvc_NetSetFileSecurity
2457  Win9x NT tools set security descriptor.
2458 ***********************************************************************************/
2459
2460 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2461                                   struct srvsvc_NetSetFileSecurity *r)
2462 {
2463         struct smb_filename *smb_fname = NULL;
2464         char *servicename = NULL;
2465         files_struct *fsp = NULL;
2466         SMB_STRUCT_STAT st;
2467         NTSTATUS nt_status;
2468         WERROR werr;
2469         connection_struct *conn = NULL;
2470         int snum;
2471         char *oldcwd = NULL;
2472         struct security_descriptor *psd = NULL;
2473         uint32_t security_info_sent = 0;
2474         uint32_t ucf_flags = 0;
2475
2476         ZERO_STRUCT(st);
2477
2478         if (!r->in.share) {
2479                 werr = WERR_NERR_NETNAMENOTFOUND;
2480                 goto error_exit;
2481         }
2482
2483         snum = find_service(talloc_tos(), r->in.share, &servicename);
2484         if (!servicename) {
2485                 werr = WERR_NOT_ENOUGH_MEMORY;
2486                 goto error_exit;
2487         }
2488
2489         if (snum == -1) {
2490                 DEBUG(10, ("Could not find service %s\n", servicename));
2491                 werr = WERR_NERR_NETNAMENOTFOUND;
2492                 goto error_exit;
2493         }
2494
2495         nt_status = create_conn_struct_cwd(talloc_tos(),
2496                                            server_event_context(),
2497                                            server_messaging_context(),
2498                                            &conn,
2499                                            snum, lp_path(talloc_tos(), snum),
2500                                            p->session_info, &oldcwd);
2501         if (!NT_STATUS_IS_OK(nt_status)) {
2502                 DEBUG(10, ("create_conn_struct failed: %s\n",
2503                            nt_errstr(nt_status)));
2504                 werr = ntstatus_to_werror(nt_status);
2505                 goto error_exit;
2506         }
2507
2508         nt_status = filename_convert(talloc_tos(),
2509                                         conn,
2510                                         r->in.file,
2511                                         ucf_flags,
2512                                         NULL,
2513                                         &smb_fname);
2514         if (!NT_STATUS_IS_OK(nt_status)) {
2515                 werr = ntstatus_to_werror(nt_status);
2516                 goto error_exit;
2517         }
2518
2519         nt_status = SMB_VFS_CREATE_FILE(
2520                 conn,                                   /* conn */
2521                 NULL,                                   /* req */
2522                 0,                                      /* root_dir_fid */
2523                 smb_fname,                              /* fname */
2524                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
2525                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2526                 FILE_OPEN,                              /* create_disposition*/
2527                 0,                                      /* create_options */
2528                 0,                                      /* file_attributes */
2529                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2530                 NULL,                                   /* lease */
2531                 0,                                      /* allocation_size */
2532                 0,                                      /* private_flags */
2533                 NULL,                                   /* sd */
2534                 NULL,                                   /* ea_list */
2535                 &fsp,                                   /* result */
2536                 NULL,                                   /* pinfo */
2537                 NULL, NULL);                            /* create context */
2538
2539         if (!NT_STATUS_IS_OK(nt_status)) {
2540                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2541                          smb_fname_str_dbg(smb_fname)));
2542                 werr = ntstatus_to_werror(nt_status);
2543                 goto error_exit;
2544         }
2545
2546         psd = r->in.sd_buf->sd;
2547         security_info_sent = r->in.securityinformation;
2548
2549         nt_status = set_sd(fsp, psd, security_info_sent);
2550
2551         if (!NT_STATUS_IS_OK(nt_status) ) {
2552                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2553                          "on file %s\n", r->in.share));
2554                 werr = WERR_ACCESS_DENIED;
2555                 goto error_exit;
2556         }
2557
2558         close_file(NULL, fsp, NORMAL_CLOSE);
2559         vfs_ChDir(conn, oldcwd);
2560         SMB_VFS_DISCONNECT(conn);
2561         conn_free(conn);
2562         werr = WERR_OK;
2563         goto done;
2564
2565 error_exit:
2566
2567         if (fsp) {
2568                 close_file(NULL, fsp, NORMAL_CLOSE);
2569         }
2570
2571         if (oldcwd) {
2572                 vfs_ChDir(conn, oldcwd);
2573         }
2574
2575         if (conn) {
2576                 SMB_VFS_DISCONNECT(conn);
2577                 conn_free(conn);
2578         }
2579
2580  done:
2581         TALLOC_FREE(smb_fname);
2582
2583         return werr;
2584 }
2585
2586 /***********************************************************************************
2587  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2588  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2589  These disks would the disks listed by this function.
2590  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2591  "Nigel Williams" <nigel@veritas.com>.
2592 ***********************************************************************************/
2593
2594 static const char *server_disks[] = {"C:"};
2595
2596 static uint32_t get_server_disk_count(void)
2597 {
2598         return sizeof(server_disks)/sizeof(server_disks[0]);
2599 }
2600
2601 static uint32_t init_server_disk_enum(uint32_t *resume)
2602 {
2603         uint32_t server_disk_count = get_server_disk_count();
2604
2605         /*resume can be an offset into the list for now*/
2606
2607         if(*resume & 0x80000000)
2608                 *resume = 0;
2609
2610         if(*resume > server_disk_count)
2611                 *resume = server_disk_count;
2612
2613         return server_disk_count - *resume;
2614 }
2615
2616 static const char *next_server_disk_enum(uint32_t *resume)
2617 {
2618         const char *disk;
2619
2620         if(init_server_disk_enum(resume) == 0)
2621                 return NULL;
2622
2623         disk = server_disks[*resume];
2624
2625         (*resume)++;
2626
2627         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2628
2629         return disk;
2630 }
2631
2632 /********************************************************************
2633  _srvsvc_NetDiskEnum
2634 ********************************************************************/
2635
2636 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2637                            struct srvsvc_NetDiskEnum *r)
2638 {
2639         uint32_t i;
2640         const char *disk_name;
2641         TALLOC_CTX *ctx = p->mem_ctx;
2642         WERROR werr;
2643         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2644
2645         werr = WERR_OK;
2646
2647         *r->out.totalentries = init_server_disk_enum(&resume);
2648
2649         r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2650                                                MAX_SERVER_DISK_ENTRIES);
2651         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2652
2653         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2654
2655         r->out.info->count = 0;
2656
2657         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2658
2659                 r->out.info->count++;
2660
2661                 /*copy disk name into a unicode string*/
2662
2663                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2664                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2665         }
2666
2667         /* add a terminating null string.  Is this there if there is more data to come? */
2668
2669         r->out.info->count++;
2670
2671         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2672         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2673
2674         if (r->out.resume_handle) {
2675                 *r->out.resume_handle = resume;
2676         }
2677
2678         return werr;
2679 }
2680
2681 /********************************************************************
2682  _srvsvc_NetNameValidate
2683 ********************************************************************/
2684
2685 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2686                                struct srvsvc_NetNameValidate *r)
2687 {
2688         switch (r->in.name_type) {
2689         case 0x9:
2690                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2691                                        strlen_m(r->in.name)))
2692                 {
2693                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2694                                 r->in.name));
2695                         return WERR_INVALID_NAME;
2696                 }
2697                 break;
2698
2699         default:
2700                 return WERR_INVALID_LEVEL;
2701         }
2702
2703         return WERR_OK;
2704 }
2705
2706 /*******************************************************************
2707 ********************************************************************/
2708
2709 struct enum_file_close_state {
2710         struct srvsvc_NetFileClose *r;
2711         struct messaging_context *msg_ctx;
2712 };
2713
2714 static int enum_file_close_fn(const struct share_mode_entry *e,
2715                               const char *sharepath,
2716                               const char *fname,
2717                               const char *sname,
2718                               void *private_data)
2719 {
2720         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2721         struct enum_file_close_state *state =
2722                 (struct enum_file_close_state *)private_data;
2723         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2724
2725         if (fid != state->r->in.fid) {
2726                 return 0; /* Not this file. */
2727         }
2728
2729         if (!process_exists(e->pid) ) {
2730                 return 0;
2731         }
2732
2733         /* Ok - send the close message. */
2734         DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2735                 sharepath,
2736                 share_mode_str(talloc_tos(), 0, e) ));
2737
2738         share_mode_entry_to_message(msg, e);
2739
2740         state->r->out.result = ntstatus_to_werror(
2741                 messaging_send_buf(state->msg_ctx,
2742                                 e->pid, MSG_SMB_CLOSE_FILE,
2743                                 (uint8_t *)msg, sizeof(msg)));
2744
2745         return 0;
2746 }
2747
2748 /********************************************************************
2749  Close a file given a 32-bit file id.
2750 ********************************************************************/
2751
2752 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2753                             struct srvsvc_NetFileClose *r)
2754 {
2755         struct enum_file_close_state state;
2756         bool is_disk_op;
2757
2758         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2759
2760         is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2761
2762         if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2763                 return WERR_ACCESS_DENIED;
2764         }
2765
2766         /* enum_file_close_fn sends the close message to
2767          * the relevant smbd process. */
2768
2769         r->out.result = WERR_FILE_NOT_FOUND;
2770         state.r = r;
2771         state.msg_ctx = p->msg_ctx;
2772         share_entry_forall(enum_file_close_fn, &state);
2773         return r->out.result;
2774 }
2775
2776 /********************************************************************
2777 ********************************************************************/
2778
2779 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2780                               struct srvsvc_NetCharDevEnum *r)
2781 {
2782         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2783         return WERR_NOT_SUPPORTED;
2784 }
2785
2786 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2787                                  struct srvsvc_NetCharDevGetInfo *r)
2788 {
2789         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2790         return WERR_NOT_SUPPORTED;
2791 }
2792
2793 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2794                                  struct srvsvc_NetCharDevControl *r)
2795 {
2796         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2797         return WERR_NOT_SUPPORTED;
2798 }
2799
2800 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2801                                struct srvsvc_NetCharDevQEnum *r)
2802 {
2803         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2804         return WERR_NOT_SUPPORTED;
2805 }
2806
2807 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2808                                   struct srvsvc_NetCharDevQGetInfo *r)
2809 {
2810         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2811         return WERR_NOT_SUPPORTED;
2812 }
2813
2814 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2815                                   struct srvsvc_NetCharDevQSetInfo *r)
2816 {
2817         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2818         return WERR_NOT_SUPPORTED;
2819 }
2820
2821 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2822                                 struct srvsvc_NetCharDevQPurge *r)
2823 {
2824         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2825         return WERR_NOT_SUPPORTED;
2826 }
2827
2828 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2829                                     struct srvsvc_NetCharDevQPurgeSelf *r)
2830 {
2831         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2832         return WERR_NOT_SUPPORTED;
2833 }
2834
2835 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2836                               struct srvsvc_NetFileGetInfo *r)
2837 {
2838         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2839         return WERR_NOT_SUPPORTED;
2840 }
2841
2842 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2843                              struct srvsvc_NetShareCheck *r)
2844 {
2845         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2846         return WERR_NOT_SUPPORTED;
2847 }
2848
2849 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2850                                       struct srvsvc_NetServerStatisticsGet *r)
2851 {
2852         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2853         return WERR_NOT_SUPPORTED;
2854 }
2855
2856 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2857                                struct srvsvc_NetTransportAdd *r)
2858 {
2859         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2860         return WERR_NOT_SUPPORTED;
2861 }
2862
2863 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2864                                 struct srvsvc_NetTransportEnum *r)
2865 {
2866         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2867         return WERR_NOT_SUPPORTED;
2868 }
2869
2870 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2871                                struct srvsvc_NetTransportDel *r)
2872 {
2873         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2874         return WERR_NOT_SUPPORTED;
2875 }
2876
2877 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2878                                  struct srvsvc_NetSetServiceBits *r)
2879 {
2880         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2881         return WERR_NOT_SUPPORTED;
2882 }
2883
2884 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2885                            struct srvsvc_NetPathType *r)
2886 {
2887         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2888         return WERR_NOT_SUPPORTED;
2889 }
2890
2891 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2892                                    struct srvsvc_NetPathCanonicalize *r)
2893 {
2894         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2895         return WERR_NOT_SUPPORTED;
2896 }
2897
2898 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2899                               struct srvsvc_NetPathCompare *r)
2900 {
2901         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2902         return WERR_NOT_SUPPORTED;
2903 }
2904
2905 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2906                                       struct srvsvc_NETRPRNAMECANONICALIZE *r)
2907 {
2908         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2909         return WERR_NOT_SUPPORTED;
2910 }
2911
2912 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2913                                 struct srvsvc_NetPRNameCompare *r)
2914 {
2915         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2916         return WERR_NOT_SUPPORTED;
2917 }
2918
2919 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2920                                 struct srvsvc_NetShareDelStart *r)
2921 {
2922         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2923         return WERR_NOT_SUPPORTED;
2924 }
2925
2926 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2927                                  struct srvsvc_NetShareDelCommit *r)
2928 {
2929         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2930         return WERR_NOT_SUPPORTED;
2931 }
2932
2933 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2934                                        struct srvsvc_NetServerTransportAddEx *r)
2935 {
2936         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2937         return WERR_NOT_SUPPORTED;
2938 }
2939
2940 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2941                                          struct srvsvc_NetServerSetServiceBitsEx *r)
2942 {
2943         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2944         return WERR_NOT_SUPPORTED;
2945 }
2946
2947 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2948                                  struct srvsvc_NETRDFSGETVERSION *r)
2949 {
2950         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2951         return WERR_NOT_SUPPORTED;
2952 }
2953
2954 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2955                                            struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2956 {
2957         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2958         return WERR_NOT_SUPPORTED;
2959 }
2960
2961 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2962                                            struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2963 {
2964         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2965         return WERR_NOT_SUPPORTED;
2966 }
2967
2968 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2969                                           struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2970 {
2971         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2972         return WERR_NOT_SUPPORTED;
2973 }
2974
2975 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2976                                     struct srvsvc_NETRDFSSETSERVERINFO *r)
2977 {
2978         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2979         return WERR_NOT_SUPPORTED;
2980 }
2981
2982 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2983                                       struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2984 {
2985         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2986         return WERR_NOT_SUPPORTED;
2987 }
2988
2989 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2990                                       struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2991 {
2992         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2993         return WERR_NOT_SUPPORTED;
2994 }
2995
2996 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2997                                    struct srvsvc_NETRDFSMODIFYPREFIX *r)
2998 {
2999         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3000         return WERR_NOT_SUPPORTED;
3001 }
3002
3003 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
3004                                      struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
3005 {
3006         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3007         return WERR_NOT_SUPPORTED;
3008 }
3009
3010 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3011                                             struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3012 {
3013         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3014         return WERR_NOT_SUPPORTED;
3015 }
3016
3017 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3018                                         struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3019 {
3020         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3021         return WERR_NOT_SUPPORTED;
3022 }