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