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