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