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