Add my copyright.
[tprouty/samba.git] / source3 / rpc_server / 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
28 extern const struct generic_mapping file_generic_mapping;
29
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
32
33 #define MAX_SERVER_DISK_ENTRIES 15
34
35 /***************************/
36
37 /* oops - this is going to take up a *massive* amount of stack. */
38 /* the UNISTR2s already have 1024 uint16 chars in them... */
39
40 #define MAX_SESS_ENTRIES 32
41
42 /***************************/
43
44 /* oops - this is going to take up a *massive* amount of stack. */
45 /* the UNISTR2s already have 1024 uint16 chars in them... */
46 #define MAX_CONN_ENTRIES 32
47
48 /* Use for enumerating connections, pipes, & files */
49
50 struct file_enum_count {
51         TALLOC_CTX *ctx;
52         const char *username;
53         struct srvsvc_NetFileCtr3 *ctr3;
54 };
55
56 struct sess_file_count {
57         struct server_id pid;
58         uid_t uid;
59         int count;
60 };
61
62 /****************************************************************************
63  Count the entries belonging to a service in the connection db.
64 ****************************************************************************/
65
66 static int pipe_enum_fn( struct db_record *rec, void *p)
67 {
68         struct pipe_open_rec prec;
69         struct file_enum_count *fenum = (struct file_enum_count *)p;
70         struct srvsvc_NetFileInfo3 *f;
71         int i = fenum->ctr3->count;
72         char *fullpath = NULL;
73         const char *username;
74
75         if (rec->value.dsize != sizeof(struct pipe_open_rec))
76                 return 0;
77
78         memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
79
80         if ( !process_exists(prec.pid) ) {
81                 return 0;
82         }
83
84         username = uidtoname(prec.uid);
85
86         if ((fenum->username != NULL)
87             && !strequal(username, fenum->username)) {
88                 return 0;
89         }
90
91         fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
92         if (!fullpath) {
93                 return 1;
94         }
95
96         f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
97                                  struct srvsvc_NetFileInfo3, i+1);
98         if ( !f ) {
99                 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
100                 return 1;
101         }
102         fenum->ctr3->array = f;
103
104         init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
105                                  (uint32_t)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
106                                  (FILE_READ_DATA|FILE_WRITE_DATA),
107                                  0,
108                                  fullpath,
109                                  username);
110
111         fenum->ctr3->count++;
112
113         return 0;
114 }
115
116 /*******************************************************************
117 ********************************************************************/
118
119 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
120                              const char *username,
121                              struct srvsvc_NetFileCtr3 **ctr3,
122                              uint32_t resume )
123 {
124         struct file_enum_count fenum;
125
126         fenum.ctx = ctx;
127         fenum.username = username;
128         fenum.ctr3 = *ctr3;
129
130         if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
131                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
132                          "failed\n"));
133                 return WERR_NOMEM;
134         }
135
136         *ctr3 = fenum.ctr3;
137
138         return WERR_OK;
139 }
140
141 /*******************************************************************
142 ********************************************************************/
143
144 static void enum_file_fn( const struct share_mode_entry *e,
145                           const char *sharepath, const char *fname,
146                           void *private_data )
147 {
148         struct file_enum_count *fenum =
149                 (struct file_enum_count *)private_data;
150
151         struct srvsvc_NetFileInfo3 *f;
152         int i = fenum->ctr3->count;
153         files_struct fsp;
154         struct byte_range_lock *brl;
155         int num_locks = 0;
156         char *fullpath = NULL;
157         uint32 permissions;
158         const char *username;
159
160         /* If the pid was not found delete the entry from connections.tdb */
161
162         if ( !process_exists(e->pid) ) {
163                 return;
164         }
165
166         username = uidtoname(e->uid);
167
168         if ((fenum->username != NULL)
169             && !strequal(username, fenum->username)) {
170                 return;
171         }
172
173         f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
174                                  struct srvsvc_NetFileInfo3, i+1);
175         if ( !f ) {
176                 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
177                 return;
178         }
179         fenum->ctr3->array = f;
180
181         /* need to count the number of locks on a file */
182
183         ZERO_STRUCT( fsp );
184         fsp.file_id = e->id;
185
186         if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
187                 num_locks = brl->num_locks;
188                 TALLOC_FREE(brl);
189         }
190
191         if ( strcmp( fname, "." ) == 0 ) {
192                 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
193         } else {
194                 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
195                                 sharepath, fname );
196         }
197         if (!fullpath) {
198                 return;
199         }
200         string_replace( fullpath, '/', '\\' );
201
202         /* mask out create (what ever that is) */
203         permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
204
205         /* now fill in the srvsvc_NetFileInfo3 struct */
206         init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
207                                  e->share_file_id,
208                                  permissions,
209                                  num_locks,
210                                  username,
211                                  fullpath);
212         fenum->ctr3->count++;
213 }
214
215 /*******************************************************************
216 ********************************************************************/
217
218 static WERROR net_enum_files(TALLOC_CTX *ctx,
219                              const char *username,
220                              struct srvsvc_NetFileCtr3 **ctr3,
221                              uint32_t resume)
222 {
223         struct file_enum_count f_enum_cnt;
224
225         f_enum_cnt.ctx = ctx;
226         f_enum_cnt.username = username;
227         f_enum_cnt.ctr3 = *ctr3;
228
229         share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
230
231         *ctr3 = f_enum_cnt.ctr3;
232
233         return WERR_OK;
234 }
235
236 /*******************************************************************
237  Utility function to get the 'type' of a share from an snum.
238  ********************************************************************/
239 static uint32 get_share_type(int snum)
240 {
241         /* work out the share type */
242         uint32 type = STYPE_DISKTREE;
243
244         if (lp_print_ok(snum))
245                 type = STYPE_PRINTQ;
246         if (strequal(lp_fstype(snum), "IPC"))
247                 type = STYPE_IPC;
248         if (lp_administrative_share(snum))
249                 type |= STYPE_HIDDEN;
250
251         return type;
252 }
253
254 /*******************************************************************
255  Fill in a share info level 0 structure.
256  ********************************************************************/
257
258 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
259 {
260         const char *net_name = lp_servicename(snum);
261
262         init_srvsvc_NetShareInfo0(r, net_name);
263 }
264
265 /*******************************************************************
266  Fill in a share info level 1 structure.
267  ********************************************************************/
268
269 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
270 {
271         char *net_name = lp_servicename(snum);
272         char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
273
274         if (remark) {
275                 remark = standard_sub_conn(p->mem_ctx,
276                                 p->conn,
277                                 remark);
278         }
279
280         init_srvsvc_NetShareInfo1(r, net_name,
281                                   get_share_type(snum),
282                                   remark ? remark : "");
283 }
284
285 /*******************************************************************
286  Fill in a share info level 2 structure.
287  ********************************************************************/
288
289 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
290 {
291         char *remark = NULL;
292         char *path = NULL;
293         int max_connections = lp_max_connections(snum);
294         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
295         int count = 0;
296         char *net_name = lp_servicename(snum);
297
298         remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
299         if (remark) {
300                 remark = standard_sub_conn(p->mem_ctx,
301                                 p->conn,
302                                 remark);
303         }
304         path = talloc_asprintf(p->mem_ctx,
305                         "C:%s", lp_pathname(snum));
306
307         if (path) {
308                 /*
309                  * Change / to \\ so that win2k will see it as a valid path.
310                  * This was added to enable use of browsing in win2k add
311                  * share dialog.
312                  */
313
314                 string_replace(path, '/', '\\');
315         }
316
317         count = count_current_connections(net_name, false);
318
319         init_srvsvc_NetShareInfo2(r, net_name,
320                                   get_share_type(snum),
321                                   remark ? remark : "",
322                                   0,
323                                   max_uses,
324                                   count,
325                                   path ? path : "",
326                                   "");
327 }
328
329 /*******************************************************************
330  Map any generic bits to file specific bits.
331 ********************************************************************/
332
333 static void map_generic_share_sd_bits(SEC_DESC *psd)
334 {
335         int i;
336         SEC_ACL *ps_dacl = NULL;
337
338         if (!psd)
339                 return;
340
341         ps_dacl = psd->dacl;
342         if (!ps_dacl)
343                 return;
344
345         for (i = 0; i < ps_dacl->num_aces; i++) {
346                 SEC_ACE *psa = &ps_dacl->aces[i];
347                 uint32 orig_mask = psa->access_mask;
348
349                 se_map_generic(&psa->access_mask, &file_generic_mapping);
350                 psa->access_mask |= orig_mask;
351         }
352 }
353
354 /*******************************************************************
355  Fill in a share info level 501 structure.
356 ********************************************************************/
357
358 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
359 {
360         const char *net_name = lp_servicename(snum);
361         char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
362
363         if (remark) {
364                 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
365         }
366
367         init_srvsvc_NetShareInfo501(r, net_name,
368                                     get_share_type(snum),
369                                     remark ? remark : "",
370                                     (lp_csc_policy(snum) << 4));
371 }
372
373 /*******************************************************************
374  Fill in a share info level 502 structure.
375  ********************************************************************/
376
377 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
378 {
379         const char *net_name = lp_servicename(snum);
380         char *path = NULL;
381         SEC_DESC *sd = NULL;
382         size_t sd_size = 0;
383         TALLOC_CTX *ctx = p->mem_ctx;
384         char *remark = talloc_strdup(ctx, lp_comment(snum));;
385
386         if (remark) {
387                 remark = standard_sub_conn(ctx, p->conn, remark);
388         }
389         path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
390         if (path) {
391                 /*
392                  * Change / to \\ so that win2k will see it as a valid path.  This was added to
393                  * enable use of browsing in win2k add share dialog.
394                  */
395                 string_replace(path, '/', '\\');
396         }
397
398         sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
399
400         init_srvsvc_NetShareInfo502(r, net_name,
401                                     get_share_type(snum),
402                                     remark ? remark : "",
403                                     0,
404                                     0xffffffff,
405                                     1,
406                                     path ? path : "",
407                                     "",
408                                     0,
409                                     sd);
410 }
411
412 /***************************************************************************
413  Fill in a share info level 1004 structure.
414  ***************************************************************************/
415
416 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
417 {
418         char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
419
420         if (remark) {
421                 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
422         }
423
424         init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
425 }
426
427 /***************************************************************************
428  Fill in a share info level 1005 structure.
429  ***************************************************************************/
430
431 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
432 {
433         uint32_t dfs_flags = 0;
434
435         if (lp_host_msdfs() && lp_msdfs_root(snum)) {
436                 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
437         }
438
439         dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
440
441         init_srvsvc_NetShareInfo1005(r, dfs_flags);
442 }
443
444 /***************************************************************************
445  Fill in a share info level 1006 structure.
446  ***************************************************************************/
447
448 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
449 {
450         init_srvsvc_NetShareInfo1006(r, 0xffffffff);
451 }
452
453 /***************************************************************************
454  Fill in a share info level 1007 structure.
455  ***************************************************************************/
456
457 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
458 {
459         uint32 flags = 0;
460
461         init_srvsvc_NetShareInfo1007(r, flags, "");
462 }
463
464 /*******************************************************************
465  Fill in a share info level 1501 structure.
466  ********************************************************************/
467
468 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
469 {
470         SEC_DESC *sd;
471         size_t sd_size;
472         TALLOC_CTX *ctx = p->mem_ctx;
473
474         sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
475
476         r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
477 }
478
479 /*******************************************************************
480  True if it ends in '$'.
481  ********************************************************************/
482
483 static bool is_hidden_share(int snum)
484 {
485         const char *net_name = lp_servicename(snum);
486
487         return (net_name[strlen(net_name) - 1] == '$') ? True : False;
488 }
489
490 /*******************************************************************
491  Fill in a share info structure.
492  ********************************************************************/
493
494 static WERROR init_srv_share_info_ctr(pipes_struct *p,
495                                       struct srvsvc_NetShareInfoCtr *info_ctr,
496                                       uint32_t *resume_handle_p,
497                                       uint32_t *total_entries,
498                                       bool all_shares)
499 {
500         int num_entries = 0;
501         int alloc_entries = 0;
502         int num_services = 0;
503         int snum;
504         TALLOC_CTX *ctx = p->mem_ctx;
505         int i = 0;
506         int valid_share_count = 0;
507         union srvsvc_NetShareCtr ctr;
508         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
509
510         DEBUG(5,("init_srv_share_info_ctr\n"));
511
512         /* Ensure all the usershares are loaded. */
513         become_root();
514         load_usershare_shares();
515         load_registry_shares();
516         num_services = lp_numservices();
517         unbecome_root();
518
519         /* Count the number of entries. */
520         for (snum = 0; snum < num_services; snum++) {
521                 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
522                         DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
523                         num_entries++;
524                 } else {
525                         DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
526                 }
527         }
528
529         if (!num_entries || (resume_handle >= num_entries)) {
530                 return WERR_OK;
531         }
532
533         /* Calculate alloc entries. */
534         alloc_entries = num_entries - resume_handle;
535         switch (info_ctr->level) {
536         case 0:
537                 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
538                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
539
540                 ctr.ctr0->count = alloc_entries;
541                 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
542                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
543
544                 for (snum = 0; snum < num_services; snum++) {
545                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
546                             (resume_handle <= (i + valid_share_count++)) ) {
547                                 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
548                         }
549                 }
550
551                 break;
552
553         case 1:
554                 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
555                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
556
557                 ctr.ctr1->count = alloc_entries;
558                 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
559                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
560
561                 for (snum = 0; snum < num_services; snum++) {
562                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
563                             (resume_handle <= (i + valid_share_count++)) ) {
564                                 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
565                         }
566                 }
567
568                 break;
569
570         case 2:
571                 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
572                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
573
574                 ctr.ctr2->count = alloc_entries;
575                 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
576                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
577
578                 for (snum = 0; snum < num_services; snum++) {
579                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
580                             (resume_handle <= (i + valid_share_count++)) ) {
581                                 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
582                         }
583                 }
584
585                 break;
586
587         case 501:
588                 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
589                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
590
591                 ctr.ctr501->count = alloc_entries;
592                 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
593                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
594
595                 for (snum = 0; snum < num_services; snum++) {
596                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
597                             (resume_handle <= (i + valid_share_count++)) ) {
598                                 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
599                         }
600                 }
601
602                 break;
603
604         case 502:
605                 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
606                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
607
608                 ctr.ctr502->count = alloc_entries;
609                 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
610                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
611
612                 for (snum = 0; snum < num_services; snum++) {
613                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
614                             (resume_handle <= (i + valid_share_count++)) ) {
615                                 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
616                         }
617                 }
618
619                 break;
620
621         case 1004:
622                 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
623                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
624
625                 ctr.ctr1004->count = alloc_entries;
626                 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
627                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
628
629                 for (snum = 0; snum < num_services; snum++) {
630                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
631                             (resume_handle <= (i + valid_share_count++)) ) {
632                                 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
633                         }
634                 }
635
636                 break;
637
638         case 1005:
639                 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
640                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
641
642                 ctr.ctr1005->count = alloc_entries;
643                 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
644                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
645
646                 for (snum = 0; snum < num_services; snum++) {
647                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
648                             (resume_handle <= (i + valid_share_count++)) ) {
649                                 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
650                         }
651                 }
652
653                 break;
654
655         case 1006:
656                 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
657                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
658
659                 ctr.ctr1006->count = alloc_entries;
660                 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
661                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
662
663                 for (snum = 0; snum < num_services; snum++) {
664                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
665                             (resume_handle <= (i + valid_share_count++)) ) {
666                                 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
667                         }
668                 }
669
670                 break;
671
672         case 1007:
673                 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
674                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
675
676                 ctr.ctr1007->count = alloc_entries;
677                 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
678                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
679
680                 for (snum = 0; snum < num_services; snum++) {
681                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
682                             (resume_handle <= (i + valid_share_count++)) ) {
683                                 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
684                         }
685                 }
686
687                 break;
688
689         case 1501:
690                 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
691                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
692
693                 ctr.ctr1501->count = alloc_entries;
694                 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
695                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
696
697                 for (snum = 0; snum < num_services; snum++) {
698                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
699                             (resume_handle <= (i + valid_share_count++)) ) {
700                                 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
701                         }
702                 }
703
704                 break;
705
706         default:
707                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
708                         info_ctr->level));
709                 return WERR_UNKNOWN_LEVEL;
710         }
711
712         *total_entries = alloc_entries;
713         if (resume_handle_p) {
714                 if (all_shares) {
715                         *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
716                 } else {
717                         *resume_handle_p = num_entries;
718                 }
719         }
720
721         info_ctr->ctr = ctr;
722
723         return WERR_OK;
724 }
725
726 /*******************************************************************
727  fill in a sess info level 0 structure.
728  ********************************************************************/
729
730 static WERROR init_srv_sess_info_0(pipes_struct *p,
731                                    struct srvsvc_NetSessCtr0 *ctr0,
732                                    uint32_t *resume_handle_p,
733                                    uint32_t *total_entries)
734 {
735         struct sessionid *session_list;
736         uint32_t num_entries = 0;
737         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
738         *total_entries = list_sessions(p->mem_ctx, &session_list);
739
740         DEBUG(5,("init_srv_sess_info_0\n"));
741
742         if (ctr0 == NULL) {
743                 if (resume_handle_p) {
744                         *resume_handle_p = 0;
745                 }
746                 return WERR_OK;
747         }
748
749         for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
750
751                 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
752                                                    ctr0->array,
753                                                    struct srvsvc_NetSessInfo0,
754                                                    num_entries+1);
755                 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
756
757                 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
758                                          session_list[resume_handle].remote_machine);
759                 num_entries++;
760         }
761
762         ctr0->count = num_entries;
763
764         if (resume_handle_p) {
765                 if (*resume_handle_p >= *total_entries) {
766                         *resume_handle_p = 0;
767                 } else {
768                         *resume_handle_p = resume_handle;
769                 }
770         }
771
772         return WERR_OK;
773 }
774
775 /*******************************************************************
776 ********************************************************************/
777
778 static void sess_file_fn( const struct share_mode_entry *e,
779                           const char *sharepath, const char *fname,
780                           void *data )
781 {
782         struct sess_file_count *sess = (struct sess_file_count *)data;
783
784         if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
785                 sess->count++;
786         }
787
788         return;
789 }
790
791 /*******************************************************************
792 ********************************************************************/
793
794 static int net_count_files( uid_t uid, struct server_id pid )
795 {
796         struct sess_file_count s_file_cnt;
797
798         s_file_cnt.count = 0;
799         s_file_cnt.uid = uid;
800         s_file_cnt.pid = pid;
801
802         share_mode_forall( sess_file_fn, &s_file_cnt );
803
804         return s_file_cnt.count;
805 }
806
807 /*******************************************************************
808  fill in a sess info level 1 structure.
809  ********************************************************************/
810
811 static WERROR init_srv_sess_info_1(pipes_struct *p,
812                                    struct srvsvc_NetSessCtr1 *ctr1,
813                                    uint32_t *resume_handle_p,
814                                    uint32_t *total_entries)
815 {
816         struct sessionid *session_list;
817         uint32_t num_entries = 0;
818         time_t now = time(NULL);
819         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
820
821         ZERO_STRUCTP(ctr1);
822
823         if (ctr1 == NULL) {
824                 if (resume_handle_p) {
825                         *resume_handle_p = 0;
826                 }
827                 return WERR_OK;
828         }
829
830         *total_entries = list_sessions(p->mem_ctx, &session_list);
831
832         for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
833                 uint32 num_files;
834                 uint32 connect_time;
835                 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
836                 bool guest;
837
838                 if ( !pw ) {
839                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
840                                 session_list[resume_handle].username));
841                         continue;
842                 }
843
844                 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
845                 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
846                 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
847
848                 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
849                                                    ctr1->array,
850                                                    struct srvsvc_NetSessInfo1,
851                                                    num_entries+1);
852                 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
853
854                 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
855                                          session_list[resume_handle].remote_machine,
856                                          session_list[resume_handle].username,
857                                          num_files,
858                                          connect_time,
859                                          0,
860                                          guest);
861                 num_entries++;
862         }
863
864         ctr1->count = num_entries;
865
866         if (resume_handle_p) {
867                 if (*resume_handle_p >= *total_entries) {
868                         *resume_handle_p = 0;
869                 } else {
870                         *resume_handle_p = resume_handle;
871                 }
872         }
873
874         return WERR_OK;
875 }
876
877 /*******************************************************************
878  fill in a conn info level 0 structure.
879  ********************************************************************/
880
881 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
882                                    uint32_t *resume_handle_p,
883                                    uint32_t *total_entries)
884 {
885         uint32_t num_entries = 0;
886         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
887
888         DEBUG(5,("init_srv_conn_info_0\n"));
889
890         if (ctr0 == NULL) {
891                 if (resume_handle_p) {
892                         *resume_handle_p = 0;
893                 }
894                 return WERR_OK;
895         }
896
897         *total_entries = 1;
898
899         ZERO_STRUCTP(ctr0);
900
901         for (; resume_handle < *total_entries && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
902
903                 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
904                                                    ctr0->array,
905                                                    struct srvsvc_NetConnInfo0,
906                                                    num_entries+1);
907                 if (!ctr0->array) {
908                         return WERR_NOMEM;
909                 }
910
911                 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
912                                          (*total_entries));
913
914                 /* move on to creating next connection */
915                 num_entries++;
916         }
917
918         ctr0->count = num_entries;
919         *total_entries = num_entries;
920
921         if (resume_handle_p) {
922                 if (*resume_handle_p >= *total_entries) {
923                         *resume_handle_p = 0;
924                 } else {
925                         *resume_handle_p = resume_handle;
926                 }
927         }
928
929         return WERR_OK;
930 }
931
932 /*******************************************************************
933  fill in a conn info level 1 structure.
934  ********************************************************************/
935
936 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
937                                    uint32_t *resume_handle_p,
938                                    uint32_t *total_entries)
939 {
940         uint32_t num_entries = 0;
941         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
942
943         DEBUG(5,("init_srv_conn_info_1\n"));
944
945         if (ctr1 == NULL) {
946                 if (resume_handle_p) {
947                         *resume_handle_p = 0;
948                 }
949                 return WERR_OK;
950         }
951
952         *total_entries = 1;
953
954         ZERO_STRUCTP(ctr1);
955
956         for (; (resume_handle < *total_entries) && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
957
958                 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
959                                                    ctr1->array,
960                                                    struct srvsvc_NetConnInfo1,
961                                                    num_entries+1);
962                 if (!ctr1->array) {
963                         return WERR_NOMEM;
964                 }
965
966                 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
967                                          (*total_entries),
968                                          0x3,
969                                          1,
970                                          1,
971                                          3,
972                                          "dummy_user",
973                                          "IPC$");
974
975                 /* move on to creating next connection */
976                 num_entries++;
977         }
978
979         ctr1->count = num_entries;
980         *total_entries = num_entries;
981
982         if (resume_handle_p) {
983                 if (*resume_handle_p >= *total_entries) {
984                         *resume_handle_p = 0;
985                 } else {
986                         *resume_handle_p = resume_handle;
987                 }
988         }
989
990         return WERR_OK;
991 }
992
993 /*******************************************************************
994  _srvsvc_NetFileEnum
995 *******************************************************************/
996
997 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
998                            struct srvsvc_NetFileEnum *r)
999 {
1000         TALLOC_CTX *ctx = NULL;
1001         struct srvsvc_NetFileCtr3 *ctr3;
1002         uint32_t resume_hnd = 0;
1003         WERROR werr;
1004
1005         switch (r->in.info_ctr->level) {
1006         case 3:
1007                 break;
1008         default:
1009                 return WERR_UNKNOWN_LEVEL;
1010         }
1011
1012         ctx = talloc_tos();
1013         ctr3 = r->in.info_ctr->ctr.ctr3;
1014         if (!ctr3) {
1015                 werr = WERR_INVALID_PARAM;
1016                 goto done;
1017         }
1018
1019         /* TODO -- Windows enumerates
1020            (b) active pipes
1021            (c) open directories and files */
1022
1023         werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1024         if (!W_ERROR_IS_OK(werr)) {
1025                 goto done;
1026         }
1027
1028         werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1029         if (!W_ERROR_IS_OK(werr)) {
1030                 goto done;
1031         }
1032
1033         *r->out.totalentries = ctr3->count;
1034         r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1035         r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1036
1037         werr = WERR_OK;
1038
1039  done:
1040         return werr;
1041 }
1042
1043 /*******************************************************************
1044  _srvsvc_NetSrvGetInfo
1045 ********************************************************************/
1046
1047 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1048                              struct srvsvc_NetSrvGetInfo *r)
1049 {
1050         WERROR status = WERR_OK;
1051
1052         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1053
1054         if (!pipe_access_check(p)) {
1055                 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1056                 return WERR_ACCESS_DENIED;
1057         }
1058
1059         switch (r->in.level) {
1060
1061                 /* Technically level 102 should only be available to
1062                    Administrators but there isn't anything super-secret
1063                    here, as most of it is made up. */
1064
1065         case 102: {
1066                 struct srvsvc_NetSrvInfo102 *info102;
1067
1068                 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1069                 if (!info102) {
1070                         return WERR_NOMEM;
1071                 }
1072
1073                 init_srvsvc_NetSrvInfo102(info102,
1074                                           PLATFORM_ID_NT,
1075                                           global_myname(),
1076                                           lp_major_announce_version(),
1077                                           lp_minor_announce_version(),
1078                                           lp_default_server_announce(),
1079                                           string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1080                                           0xffffffff, /* users */
1081                                           0xf, /* disc */
1082                                           0, /* hidden */
1083                                           240, /* announce */
1084                                           3000, /* announce delta */
1085                                           100000, /* licenses */
1086                                           "c:\\"); /* user path */
1087                 r->out.info->info102 = info102;
1088                 break;
1089         }
1090         case 101: {
1091                 struct srvsvc_NetSrvInfo101 *info101;
1092
1093                 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1094                 if (!info101) {
1095                         return WERR_NOMEM;
1096                 }
1097
1098                 init_srvsvc_NetSrvInfo101(info101,
1099                                           PLATFORM_ID_NT,
1100                                           global_myname(),
1101                                           lp_major_announce_version(),
1102                                           lp_minor_announce_version(),
1103                                           lp_default_server_announce(),
1104                                           string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1105                 r->out.info->info101 = info101;
1106                 break;
1107         }
1108         case 100: {
1109                 struct srvsvc_NetSrvInfo100 *info100;
1110
1111                 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1112                 if (!info100) {
1113                         return WERR_NOMEM;
1114                 }
1115
1116                 init_srvsvc_NetSrvInfo100(info100,
1117                                           PLATFORM_ID_NT,
1118                                           global_myname());
1119                 r->out.info->info100 = info100;
1120
1121                 break;
1122         }
1123         default:
1124                 status = WERR_UNKNOWN_LEVEL;
1125                 break;
1126         }
1127
1128         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1129
1130         return status;
1131 }
1132
1133 /*******************************************************************
1134  _srvsvc_NetSrvSetInfo
1135 ********************************************************************/
1136
1137 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1138                              struct srvsvc_NetSrvSetInfo *r)
1139 {
1140         WERROR status = WERR_OK;
1141
1142         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1143
1144         /* Set up the net server set info structure. */
1145
1146         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1147
1148         return status;
1149 }
1150
1151 /*******************************************************************
1152  _srvsvc_NetConnEnum
1153 ********************************************************************/
1154
1155 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1156                            struct srvsvc_NetConnEnum *r)
1157 {
1158         WERROR werr;
1159
1160         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1161
1162         switch (r->in.info_ctr->level) {
1163                 case 0:
1164                         werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1165                                                     r->in.resume_handle,
1166                                                     r->out.totalentries);
1167                         break;
1168                 case 1:
1169                         werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1170                                                     r->in.resume_handle,
1171                                                     r->out.totalentries);
1172                         break;
1173                 default:
1174                         return WERR_UNKNOWN_LEVEL;
1175         }
1176
1177         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1178
1179         return werr;
1180 }
1181
1182 /*******************************************************************
1183  _srvsvc_NetSessEnum
1184 ********************************************************************/
1185
1186 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1187                            struct srvsvc_NetSessEnum *r)
1188 {
1189         WERROR werr;
1190
1191         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1192
1193         switch (r->in.info_ctr->level) {
1194                 case 0:
1195                         werr = init_srv_sess_info_0(p,
1196                                                     r->in.info_ctr->ctr.ctr0,
1197                                                     r->in.resume_handle,
1198                                                     r->out.totalentries);
1199                         break;
1200                 case 1:
1201                         werr = init_srv_sess_info_1(p,
1202                                                     r->in.info_ctr->ctr.ctr1,
1203                                                     r->in.resume_handle,
1204                                                     r->out.totalentries);
1205                         break;
1206                 default:
1207                         return WERR_UNKNOWN_LEVEL;
1208         }
1209
1210         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1211
1212         return werr;
1213 }
1214
1215 /*******************************************************************
1216  _srvsvc_NetSessDel
1217 ********************************************************************/
1218
1219 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1220                           struct srvsvc_NetSessDel *r)
1221 {
1222         struct sessionid *session_list;
1223         struct current_user user;
1224         int num_sessions, snum;
1225         const char *username;
1226         const char *machine;
1227         bool not_root = False;
1228         WERROR werr;
1229
1230         username = r->in.user;
1231         machine = r->in.client;
1232
1233         /* strip leading backslashes if any */
1234         if (machine && machine[0] == '\\' && machine[1] == '\\') {
1235                 machine += 2;
1236         }
1237
1238         num_sessions = list_sessions(p->mem_ctx, &session_list);
1239
1240         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1241
1242         werr = WERR_ACCESS_DENIED;
1243
1244         get_current_user(&user, p);
1245
1246         /* fail out now if you are not root or not a domain admin */
1247
1248         if ((user.ut.uid != sec_initial_uid()) &&
1249                 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1250
1251                 goto done;
1252         }
1253
1254         for (snum = 0; snum < num_sessions; snum++) {
1255
1256                 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1257                     strequal(session_list[snum].remote_machine, machine)) {
1258
1259                         NTSTATUS ntstat;
1260
1261                         if (user.ut.uid != sec_initial_uid()) {
1262                                 not_root = True;
1263                                 become_root();
1264                         }
1265
1266                         ntstat = messaging_send(smbd_messaging_context(),
1267                                                 session_list[snum].pid,
1268                                                 MSG_SHUTDOWN, &data_blob_null);
1269
1270                         if (NT_STATUS_IS_OK(ntstat))
1271                                 werr = WERR_OK;
1272
1273                         if (not_root)
1274                                 unbecome_root();
1275                 }
1276         }
1277
1278         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1279
1280 done:
1281
1282         return werr;
1283 }
1284
1285 /*******************************************************************
1286  _srvsvc_NetShareEnumAll
1287 ********************************************************************/
1288
1289 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1290                                struct srvsvc_NetShareEnumAll *r)
1291 {
1292         WERROR werr;
1293
1294         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1295
1296         if (!pipe_access_check(p)) {
1297                 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1298                 return WERR_ACCESS_DENIED;
1299         }
1300
1301         /* Create the list of shares for the response. */
1302         werr = init_srv_share_info_ctr(p,
1303                                        r->in.info_ctr,
1304                                        r->in.resume_handle,
1305                                        r->out.totalentries,
1306                                        true);
1307
1308         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1309
1310         return werr;
1311 }
1312
1313 /*******************************************************************
1314  _srvsvc_NetShareEnum
1315 ********************************************************************/
1316
1317 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1318                             struct srvsvc_NetShareEnum *r)
1319 {
1320         WERROR werr;
1321
1322         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1323
1324         if (!pipe_access_check(p)) {
1325                 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1326                 return WERR_ACCESS_DENIED;
1327         }
1328
1329         /* Create the list of shares for the response. */
1330         werr = init_srv_share_info_ctr(p,
1331                                        r->in.info_ctr,
1332                                        r->in.resume_handle,
1333                                        r->out.totalentries,
1334                                        false);
1335
1336         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1337
1338         return werr;
1339 }
1340
1341 /*******************************************************************
1342  _srvsvc_NetShareGetInfo
1343 ********************************************************************/
1344
1345 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1346                                struct srvsvc_NetShareGetInfo *r)
1347 {
1348         WERROR status = WERR_OK;
1349         fstring share_name;
1350         int snum;
1351         union srvsvc_NetShareInfo *info = r->out.info;
1352
1353         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1354
1355         fstrcpy(share_name, r->in.share_name);
1356
1357         snum = find_service(share_name);
1358         if (snum < 0) {
1359                 return WERR_INVALID_NAME;
1360         }
1361
1362         switch (r->in.level) {
1363                 case 0:
1364                         info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1365                         W_ERROR_HAVE_NO_MEMORY(info->info0);
1366                         init_srv_share_info_0(p, info->info0, snum);
1367                         break;
1368                 case 1:
1369                         info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1370                         W_ERROR_HAVE_NO_MEMORY(info->info1);
1371                         init_srv_share_info_1(p, info->info1, snum);
1372                         break;
1373                 case 2:
1374                         info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1375                         W_ERROR_HAVE_NO_MEMORY(info->info2);
1376                         init_srv_share_info_2(p, info->info2, snum);
1377                         break;
1378                 case 501:
1379                         info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1380                         W_ERROR_HAVE_NO_MEMORY(info->info501);
1381                         init_srv_share_info_501(p, info->info501, snum);
1382                         break;
1383                 case 502:
1384                         info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1385                         W_ERROR_HAVE_NO_MEMORY(info->info502);
1386                         init_srv_share_info_502(p, info->info502, snum);
1387                         break;
1388                 case 1004:
1389                         info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1390                         W_ERROR_HAVE_NO_MEMORY(info->info1004);
1391                         init_srv_share_info_1004(p, info->info1004, snum);
1392                         break;
1393                 case 1005:
1394                         info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1395                         W_ERROR_HAVE_NO_MEMORY(info->info1005);
1396                         init_srv_share_info_1005(p, info->info1005, snum);
1397                         break;
1398                 case 1006:
1399                         info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1400                         W_ERROR_HAVE_NO_MEMORY(info->info1006);
1401                         init_srv_share_info_1006(p, info->info1006, snum);
1402                         break;
1403                 case 1007:
1404                         info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1405                         W_ERROR_HAVE_NO_MEMORY(info->info1007);
1406                         init_srv_share_info_1007(p, info->info1007, snum);
1407                         break;
1408                 case 1501:
1409                         init_srv_share_info_1501(p, info->info1501, snum);
1410                         break;
1411                 default:
1412                         DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1413                                 r->in.level));
1414                         status = WERR_UNKNOWN_LEVEL;
1415                         break;
1416         }
1417
1418         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1419
1420         return status;
1421 }
1422
1423 /*******************************************************************
1424  Check a given DOS pathname is valid for a share.
1425 ********************************************************************/
1426
1427 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1428 {
1429         char *ptr = NULL;
1430
1431         if (!dos_pathname) {
1432                 return NULL;
1433         }
1434
1435         ptr = talloc_strdup(ctx, dos_pathname);
1436         if (!ptr) {
1437                 return NULL;
1438         }
1439         /* Convert any '\' paths to '/' */
1440         unix_format(ptr);
1441         ptr = unix_clean_name(ctx, ptr);
1442         if (!ptr) {
1443                 return NULL;
1444         }
1445
1446         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1447         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1448                 ptr += 2;
1449
1450         /* Only absolute paths allowed. */
1451         if (*ptr != '/')
1452                 return NULL;
1453
1454         return ptr;
1455 }
1456
1457 /*******************************************************************
1458  _srvsvc_NetShareSetInfo. Modify share details.
1459 ********************************************************************/
1460
1461 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1462                                struct srvsvc_NetShareSetInfo *r)
1463 {
1464         struct current_user user;
1465         char *command = NULL;
1466         char *share_name = NULL;
1467         char *comment = NULL;
1468         const char *pathname = NULL;
1469         int type;
1470         int snum;
1471         int ret;
1472         char *path = NULL;
1473         SEC_DESC *psd = NULL;
1474         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1475         bool is_disk_op = False;
1476         int max_connections = 0;
1477         TALLOC_CTX *ctx = p->mem_ctx;
1478         union srvsvc_NetShareInfo *info = r->in.info;
1479
1480         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1481
1482         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1483         if (!share_name) {
1484                 return WERR_NOMEM;
1485         }
1486
1487         *r->out.parm_error = 0;
1488
1489         if ( strequal(share_name,"IPC$")
1490                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1491                 || strequal(share_name,"global") )
1492         {
1493                 return WERR_ACCESS_DENIED;
1494         }
1495
1496         snum = find_service(share_name);
1497
1498         /* Does this share exist ? */
1499         if (snum < 0)
1500                 return WERR_NET_NAME_NOT_FOUND;
1501
1502         /* No change to printer shares. */
1503         if (lp_print_ok(snum))
1504                 return WERR_ACCESS_DENIED;
1505
1506         get_current_user(&user,p);
1507
1508         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1509
1510         /* fail out now if you are not root and not a disk op */
1511
1512         if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1513                 return WERR_ACCESS_DENIED;
1514
1515         switch (r->in.level) {
1516         case 1:
1517                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1518                 comment = talloc_strdup(ctx, info->info2->comment);
1519                 type = info->info2->type;
1520                 psd = NULL;
1521                 break;
1522         case 2:
1523                 comment = talloc_strdup(ctx, info->info2->comment);
1524                 pathname = info->info2->path;
1525                 type = info->info2->type;
1526                 max_connections = (info->info2->max_users == 0xffffffff) ?
1527                         0 : info->info2->max_users;
1528                 psd = NULL;
1529                 break;
1530 #if 0
1531                 /* not supported on set but here for completeness */
1532         case 501:
1533                 comment = talloc_strdup(ctx, info->info501->comment);
1534                 type = info->info501->type;
1535                 psd = NULL;
1536                 break;
1537 #endif
1538         case 502:
1539                 comment = talloc_strdup(ctx, info->info502->comment);
1540                 pathname = info->info502->path;
1541                 type = info->info502->type;
1542                 psd = info->info502->sd;
1543                 map_generic_share_sd_bits(psd);
1544                 break;
1545         case 1004:
1546                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1547                 comment = talloc_strdup(ctx, info->info1004->comment);
1548                 type = STYPE_DISKTREE;
1549                 break;
1550         case 1005:
1551                 /* XP re-sets the csc policy even if it wasn't changed by the
1552                    user, so we must compare it to see if it's what is set in
1553                    smb.conf, so that we can contine other ops like setting
1554                    ACLs on a share */
1555                 if (((info->info1005->dfs_flags &
1556                       SHARE_1005_CSC_POLICY_MASK) >>
1557                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1558                         return WERR_OK;
1559                 else {
1560                         DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1561                         return WERR_ACCESS_DENIED;
1562                 }
1563         case 1006:
1564         case 1007:
1565                 return WERR_ACCESS_DENIED;
1566         case 1501:
1567                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1568                 comment = talloc_strdup(ctx, lp_comment(snum));
1569                 psd = info->info1501->sd;
1570                 map_generic_share_sd_bits(psd);
1571                 type = STYPE_DISKTREE;
1572                 break;
1573         default:
1574                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1575                         r->in.level));
1576                 return WERR_UNKNOWN_LEVEL;
1577         }
1578
1579         /* We can only modify disk shares. */
1580         if (type != STYPE_DISKTREE)
1581                 return WERR_ACCESS_DENIED;
1582
1583         /* Check if the pathname is valid. */
1584         if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1585                 return WERR_OBJECT_PATH_INVALID;
1586
1587         /* Ensure share name, pathname and comment don't contain '"' characters. */
1588         string_replace(share_name, '"', ' ');
1589         string_replace(path, '"', ' ');
1590         if (comment) {
1591                 string_replace(comment, '"', ' ');
1592         }
1593
1594         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1595                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1596
1597         /* Only call modify function if something changed. */
1598
1599         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1600                         || (lp_max_connections(snum) != max_connections)) {
1601                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1602                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1603                         return WERR_ACCESS_DENIED;
1604                 }
1605
1606                 command = talloc_asprintf(p->mem_ctx,
1607                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1608                                 lp_change_share_cmd(),
1609                                 get_dyn_CONFIGFILE(),
1610                                 share_name,
1611                                 path,
1612                                 comment ? comment : "",
1613                                 max_connections);
1614                 if (!command) {
1615                         return WERR_NOMEM;
1616                 }
1617
1618                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1619
1620                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1621
1622                 if (is_disk_op)
1623                         become_root();
1624
1625                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1626                         /* Tell everyone we updated smb.conf. */
1627                         message_send_all(smbd_messaging_context(),
1628                                          MSG_SMB_CONF_UPDATED, NULL, 0,
1629                                          NULL);
1630                 }
1631
1632                 if ( is_disk_op )
1633                         unbecome_root();
1634
1635                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1636
1637                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1638                         command, ret ));
1639
1640                 TALLOC_FREE(command);
1641
1642                 if ( ret != 0 )
1643                         return WERR_ACCESS_DENIED;
1644         } else {
1645                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1646                         share_name ));
1647         }
1648
1649         /* Replace SD if changed. */
1650         if (psd) {
1651                 SEC_DESC *old_sd;
1652                 size_t sd_size;
1653
1654                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1655
1656                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1657                         if (!set_share_security(share_name, psd))
1658                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1659                                         share_name ));
1660                 }
1661         }
1662
1663         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1664
1665         return WERR_OK;
1666 }
1667
1668 /*******************************************************************
1669  _srvsvc_NetShareAdd.
1670  Call 'add_share_command "sharename" "pathname"
1671  "comment" "max connections = "
1672 ********************************************************************/
1673
1674 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1675                            struct srvsvc_NetShareAdd *r)
1676 {
1677         struct current_user user;
1678         char *command = NULL;
1679         char *share_name = NULL;
1680         char *comment = NULL;
1681         char *pathname = NULL;
1682         int type;
1683         int snum;
1684         int ret;
1685         char *path;
1686         SEC_DESC *psd = NULL;
1687         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1688         bool is_disk_op;
1689         int max_connections = 0;
1690         TALLOC_CTX *ctx = p->mem_ctx;
1691
1692         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1693
1694         *r->out.parm_error = 0;
1695
1696         get_current_user(&user,p);
1697
1698         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1699
1700         if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1701                 return WERR_ACCESS_DENIED;
1702
1703         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1704                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1705                 return WERR_ACCESS_DENIED;
1706         }
1707
1708         switch (r->in.level) {
1709         case 0:
1710                 /* No path. Not enough info in a level 0 to do anything. */
1711                 return WERR_ACCESS_DENIED;
1712         case 1:
1713                 /* Not enough info in a level 1 to do anything. */
1714                 return WERR_ACCESS_DENIED;
1715         case 2:
1716                 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1717                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1718                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1719                 max_connections = (r->in.info->info2->max_users == 0xffffffff) ?
1720                         0 : r->in.info->info2->max_users;
1721                 type = r->in.info->info2->type;
1722                 break;
1723         case 501:
1724                 /* No path. Not enough info in a level 501 to do anything. */
1725                 return WERR_ACCESS_DENIED;
1726         case 502:
1727                 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1728                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1729                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1730                 max_connections = (r->in.info->info502->max_users == 0xffffffff) ?
1731                         0 : r->in.info->info502->max_users;
1732                 type = r->in.info->info502->type;
1733                 psd = r->in.info->info502->sd;
1734                 map_generic_share_sd_bits(psd);
1735                 break;
1736
1737                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1738
1739         case 1004:
1740         case 1005:
1741         case 1006:
1742         case 1007:
1743                 return WERR_ACCESS_DENIED;
1744         case 1501:
1745                 /* DFS only level. */
1746                 return WERR_ACCESS_DENIED;
1747         default:
1748                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1749                         r->in.level));
1750                 return WERR_UNKNOWN_LEVEL;
1751         }
1752
1753         /* check for invalid share names */
1754
1755         if (!share_name || !validate_net_name(share_name,
1756                                 INVALID_SHARENAME_CHARS,
1757                                 strlen(share_name))) {
1758                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1759                                         share_name ? share_name : ""));
1760                 return WERR_INVALID_NAME;
1761         }
1762
1763         if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1764                         || (lp_enable_asu_support() &&
1765                                         strequal(share_name,"ADMIN$"))) {
1766                 return WERR_ACCESS_DENIED;
1767         }
1768
1769         snum = find_service(share_name);
1770
1771         /* Share already exists. */
1772         if (snum >= 0) {
1773                 return WERR_ALREADY_EXISTS;
1774         }
1775
1776         /* We can only add disk shares. */
1777         if (type != STYPE_DISKTREE) {
1778                 return WERR_ACCESS_DENIED;
1779         }
1780
1781         /* Check if the pathname is valid. */
1782         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1783                 return WERR_OBJECT_PATH_INVALID;
1784         }
1785
1786         /* Ensure share name, pathname and comment don't contain '"' characters. */
1787         string_replace(share_name, '"', ' ');
1788         string_replace(path, '"', ' ');
1789         if (comment) {
1790                 string_replace(comment, '"', ' ');
1791         }
1792
1793         command = talloc_asprintf(ctx,
1794                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1795                         lp_add_share_cmd(),
1796                         get_dyn_CONFIGFILE(),
1797                         share_name,
1798                         path,
1799                         comment ? comment : "",
1800                         max_connections);
1801         if (!command) {
1802                 return WERR_NOMEM;
1803         }
1804
1805         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1806
1807         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1808
1809         if ( is_disk_op )
1810                 become_root();
1811
1812         /* FIXME: use libnetconf here - gd */
1813
1814         if ( (ret = smbrun(command, NULL)) == 0 ) {
1815                 /* Tell everyone we updated smb.conf. */
1816                 message_send_all(smbd_messaging_context(),
1817                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1818         }
1819
1820         if ( is_disk_op )
1821                 unbecome_root();
1822
1823         /********* END SeDiskOperatorPrivilege BLOCK *********/
1824
1825         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1826                 command, ret ));
1827
1828         TALLOC_FREE(command);
1829
1830         if ( ret != 0 )
1831                 return WERR_ACCESS_DENIED;
1832
1833         if (psd) {
1834                 if (!set_share_security(share_name, psd)) {
1835                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1836                                 share_name ));
1837                 }
1838         }
1839
1840         /*
1841          * We don't call reload_services() here, the message will
1842          * cause this to be done before the next packet is read
1843          * from the client. JRA.
1844          */
1845
1846         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1847
1848         return WERR_OK;
1849 }
1850
1851 /*******************************************************************
1852  _srvsvc_NetShareDel
1853  Call "delete share command" with the share name as
1854  a parameter.
1855 ********************************************************************/
1856
1857 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1858                            struct srvsvc_NetShareDel *r)
1859 {
1860         struct current_user user;
1861         char *command = NULL;
1862         char *share_name = NULL;
1863         int ret;
1864         int snum;
1865         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1866         bool is_disk_op;
1867         struct share_params *params;
1868         TALLOC_CTX *ctx = p->mem_ctx;
1869
1870         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1871
1872         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1873         if (!share_name) {
1874                 return WERR_NET_NAME_NOT_FOUND;
1875         }
1876         if ( strequal(share_name,"IPC$")
1877                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1878                 || strequal(share_name,"global") )
1879         {
1880                 return WERR_ACCESS_DENIED;
1881         }
1882
1883         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1884                 return WERR_NO_SUCH_SHARE;
1885         }
1886
1887         snum = find_service(share_name);
1888
1889         /* No change to printer shares. */
1890         if (lp_print_ok(snum))
1891                 return WERR_ACCESS_DENIED;
1892
1893         get_current_user(&user,p);
1894
1895         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1896
1897         if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1898                 return WERR_ACCESS_DENIED;
1899
1900         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1901                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1902                 return WERR_ACCESS_DENIED;
1903         }
1904
1905         command = talloc_asprintf(ctx,
1906                         "%s \"%s\" \"%s\"",
1907                         lp_delete_share_cmd(),
1908                         get_dyn_CONFIGFILE(),
1909                         lp_servicename(snum));
1910         if (!command) {
1911                 return WERR_NOMEM;
1912         }
1913
1914         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1915
1916         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1917
1918         if ( is_disk_op )
1919                 become_root();
1920
1921         if ( (ret = smbrun(command, NULL)) == 0 ) {
1922                 /* Tell everyone we updated smb.conf. */
1923                 message_send_all(smbd_messaging_context(),
1924                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1925         }
1926
1927         if ( is_disk_op )
1928                 unbecome_root();
1929
1930         /********* END SeDiskOperatorPrivilege BLOCK *********/
1931
1932         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1933
1934         if ( ret != 0 )
1935                 return WERR_ACCESS_DENIED;
1936
1937         /* Delete the SD in the database. */
1938         delete_share_security(lp_servicename(params->service));
1939
1940         lp_killservice(params->service);
1941
1942         return WERR_OK;
1943 }
1944
1945 /*******************************************************************
1946  _srvsvc_NetShareDelSticky
1947 ********************************************************************/
1948
1949 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1950                                  struct srvsvc_NetShareDelSticky *r)
1951 {
1952         struct srvsvc_NetShareDel q;
1953
1954         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1955
1956         q.in.server_unc         = r->in.server_unc;
1957         q.in.share_name         = r->in.share_name;
1958         q.in.reserved           = r->in.reserved;
1959
1960         return _srvsvc_NetShareDel(p, &q);
1961 }
1962
1963 /*******************************************************************
1964  _srvsvc_NetRemoteTOD
1965 ********************************************************************/
1966
1967 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1968                             struct srvsvc_NetRemoteTOD *r)
1969 {
1970         struct srvsvc_NetRemoteTODInfo *tod;
1971         struct tm *t;
1972         time_t unixdate = time(NULL);
1973
1974         /* We do this call first as if we do it *after* the gmtime call
1975            it overwrites the pointed-to values. JRA */
1976
1977         uint32 zone = get_time_zone(unixdate)/60;
1978
1979         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1980
1981         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1982                 return WERR_NOMEM;
1983
1984         *r->out.info = tod;
1985
1986         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1987
1988         t = gmtime(&unixdate);
1989
1990         /* set up the */
1991         init_srvsvc_NetRemoteTODInfo(tod,
1992                                      unixdate,
1993                                      0,
1994                                      t->tm_hour,
1995                                      t->tm_min,
1996                                      t->tm_sec,
1997                                      0,
1998                                      zone,
1999                                      10000,
2000                                      t->tm_mday,
2001                                      t->tm_mon + 1,
2002                                      1900+t->tm_year,
2003                                      t->tm_wday);
2004
2005         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2006
2007         return WERR_OK;
2008 }
2009
2010 /***********************************************************************************
2011  _srvsvc_NetGetFileSecurity
2012  Win9x NT tools get security descriptor.
2013 ***********************************************************************************/
2014
2015 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2016                                   struct srvsvc_NetGetFileSecurity *r)
2017 {
2018         SEC_DESC *psd = NULL;
2019         size_t sd_size;
2020         DATA_BLOB null_pw;
2021         char *filename_in = NULL;
2022         char *filename = NULL;
2023         char *qualname = NULL;
2024         SMB_STRUCT_STAT st;
2025         NTSTATUS nt_status;
2026         WERROR werr;
2027         struct current_user user;
2028         connection_struct *conn = NULL;
2029         bool became_user = False;
2030         TALLOC_CTX *ctx = p->mem_ctx;
2031         struct sec_desc_buf *sd_buf;
2032
2033         ZERO_STRUCT(st);
2034
2035         werr = WERR_OK;
2036
2037         qualname = talloc_strdup(ctx, r->in.share);
2038         if (!qualname) {
2039                 werr = WERR_ACCESS_DENIED;
2040                 goto error_exit;
2041         }
2042
2043         /* Null password is ok - we are already an authenticated user... */
2044         null_pw = data_blob_null;
2045
2046         get_current_user(&user, p);
2047
2048         become_root();
2049         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2050         unbecome_root();
2051
2052         if (conn == NULL) {
2053                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2054                         qualname));
2055                 werr = ntstatus_to_werror(nt_status);
2056                 goto error_exit;
2057         }
2058
2059         if (!become_user(conn, conn->vuid)) {
2060                 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2061                 werr = WERR_ACCESS_DENIED;
2062                 goto error_exit;
2063         }
2064         became_user = True;
2065
2066         filename_in = talloc_strdup(ctx, r->in.file);
2067         if (!filename_in) {
2068                 werr = WERR_ACCESS_DENIED;
2069                 goto error_exit;
2070         }
2071
2072         nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2073         if (!NT_STATUS_IS_OK(nt_status)) {
2074                 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2075                         filename));
2076                 werr = WERR_ACCESS_DENIED;
2077                 goto error_exit;
2078         }
2079
2080         nt_status = check_name(conn, filename);
2081         if (!NT_STATUS_IS_OK(nt_status)) {
2082                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2083                         filename));
2084                 werr = WERR_ACCESS_DENIED;
2085                 goto error_exit;
2086         }
2087
2088         nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2089                                        (OWNER_SECURITY_INFORMATION
2090                                         |GROUP_SECURITY_INFORMATION
2091                                         |DACL_SECURITY_INFORMATION), &psd);
2092
2093         if (!NT_STATUS_IS_OK(nt_status)) {
2094                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2095                         filename));
2096                 werr = ntstatus_to_werror(nt_status);
2097                 goto error_exit;
2098         }
2099
2100         sd_size = ndr_size_security_descriptor(psd, 0);
2101
2102         sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2103         if (!sd_buf) {
2104                 werr = WERR_NOMEM;
2105                 goto error_exit;
2106         }
2107
2108         sd_buf->sd_size = sd_size;
2109         sd_buf->sd = psd;
2110
2111         *r->out.sd_buf = sd_buf;
2112
2113         psd->dacl->revision = NT4_ACL_REVISION;
2114
2115         unbecome_user();
2116         close_cnum(conn, user.vuid);
2117         return werr;
2118
2119 error_exit:
2120
2121         if (became_user)
2122                 unbecome_user();
2123
2124         if (conn)
2125                 close_cnum(conn, user.vuid);
2126
2127         return werr;
2128 }
2129
2130 /***********************************************************************************
2131  _srvsvc_NetSetFileSecurity
2132  Win9x NT tools set security descriptor.
2133 ***********************************************************************************/
2134
2135 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2136                                   struct srvsvc_NetSetFileSecurity *r)
2137 {
2138         char *filename_in = NULL;
2139         char *filename = NULL;
2140         char *qualname = NULL;
2141         DATA_BLOB null_pw;
2142         files_struct *fsp = NULL;
2143         SMB_STRUCT_STAT st;
2144         NTSTATUS nt_status;
2145         WERROR werr;
2146         struct current_user user;
2147         connection_struct *conn = NULL;
2148         bool became_user = False;
2149         TALLOC_CTX *ctx = p->mem_ctx;
2150
2151         ZERO_STRUCT(st);
2152
2153         werr = WERR_OK;
2154
2155         qualname = talloc_strdup(ctx, r->in.share);
2156         if (!qualname) {
2157                 werr = WERR_ACCESS_DENIED;
2158                 goto error_exit;
2159         }
2160
2161         /* Null password is ok - we are already an authenticated user... */
2162         null_pw = data_blob_null;
2163
2164         get_current_user(&user, p);
2165
2166         become_root();
2167         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2168         unbecome_root();
2169
2170         if (conn == NULL) {
2171                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2172                 werr = ntstatus_to_werror(nt_status);
2173                 goto error_exit;
2174         }
2175
2176         if (!become_user(conn, conn->vuid)) {
2177                 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2178                 werr = WERR_ACCESS_DENIED;
2179                 goto error_exit;
2180         }
2181         became_user = True;
2182
2183         filename_in = talloc_strdup(ctx, r->in.file);
2184         if (!filename_in) {
2185                 werr = WERR_ACCESS_DENIED;
2186                 goto error_exit;
2187         }
2188
2189         nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2190         if (!NT_STATUS_IS_OK(nt_status)) {
2191                 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2192                 werr = WERR_ACCESS_DENIED;
2193                 goto error_exit;
2194         }
2195
2196         nt_status = check_name(conn, filename);
2197         if (!NT_STATUS_IS_OK(nt_status)) {
2198                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2199                 werr = WERR_ACCESS_DENIED;
2200                 goto error_exit;
2201         }
2202
2203         nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2204
2205         if ( !NT_STATUS_IS_OK(nt_status) ) {
2206                 /* Perhaps it is a directory */
2207                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2208                         nt_status = open_directory(conn, NULL, filename, &st,
2209                                                 FILE_READ_ATTRIBUTES,
2210                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2211                                                 FILE_OPEN,
2212                                                 0,
2213                                                 FILE_ATTRIBUTE_DIRECTORY,
2214                                                 NULL, &fsp);
2215
2216                 if ( !NT_STATUS_IS_OK(nt_status) ) {
2217                         DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2218                         werr = ntstatus_to_werror(nt_status);
2219                         goto error_exit;
2220                 }
2221         }
2222
2223         nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2224                                        r->in.securityinformation,
2225                                        r->in.sd_buf->sd);
2226
2227         if (!NT_STATUS_IS_OK(nt_status) ) {
2228                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2229                 werr = WERR_ACCESS_DENIED;
2230                 goto error_exit;
2231         }
2232
2233         close_file(fsp, NORMAL_CLOSE);
2234         unbecome_user();
2235         close_cnum(conn, user.vuid);
2236         return werr;
2237
2238 error_exit:
2239
2240         if(fsp) {
2241                 close_file(fsp, NORMAL_CLOSE);
2242         }
2243
2244         if (became_user) {
2245                 unbecome_user();
2246         }
2247
2248         if (conn) {
2249                 close_cnum(conn, user.vuid);
2250         }
2251
2252         return werr;
2253 }
2254
2255 /***********************************************************************************
2256  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2257  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2258  These disks would the disks listed by this function.
2259  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2260  "Nigel Williams" <nigel@veritas.com>.
2261 ***********************************************************************************/
2262
2263 static const char *server_disks[] = {"C:"};
2264
2265 static uint32 get_server_disk_count(void)
2266 {
2267         return sizeof(server_disks)/sizeof(server_disks[0]);
2268 }
2269
2270 static uint32 init_server_disk_enum(uint32 *resume)
2271 {
2272         uint32 server_disk_count = get_server_disk_count();
2273
2274         /*resume can be an offset into the list for now*/
2275
2276         if(*resume & 0x80000000)
2277                 *resume = 0;
2278
2279         if(*resume > server_disk_count)
2280                 *resume = server_disk_count;
2281
2282         return server_disk_count - *resume;
2283 }
2284
2285 static const char *next_server_disk_enum(uint32 *resume)
2286 {
2287         const char *disk;
2288
2289         if(init_server_disk_enum(resume) == 0)
2290                 return NULL;
2291
2292         disk = server_disks[*resume];
2293
2294         (*resume)++;
2295
2296         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2297
2298         return disk;
2299 }
2300
2301 /********************************************************************
2302  _srvsvc_NetDiskEnum
2303 ********************************************************************/
2304
2305 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2306                            struct srvsvc_NetDiskEnum *r)
2307 {
2308         uint32 i;
2309         const char *disk_name;
2310         TALLOC_CTX *ctx = p->mem_ctx;
2311         WERROR werr;
2312         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2313
2314         werr = WERR_OK;
2315
2316         *r->out.totalentries = init_server_disk_enum(&resume);
2317
2318         r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2319                                                MAX_SERVER_DISK_ENTRIES);
2320         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2321
2322         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2323
2324         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2325
2326                 r->out.info->count++;
2327
2328                 /*copy disk name into a unicode string*/
2329
2330                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2331                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2332         }
2333
2334         /* add a terminating null string.  Is this there if there is more data to come? */
2335
2336         r->out.info->count++;
2337
2338         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2339         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2340
2341         if (r->out.resume_handle) {
2342                 *r->out.resume_handle = resume;
2343         }
2344
2345         return werr;
2346 }
2347
2348 /********************************************************************
2349  _srvsvc_NetNameValidate
2350 ********************************************************************/
2351
2352 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2353                                struct srvsvc_NetNameValidate *r)
2354 {
2355         switch (r->in.name_type) {
2356         case 0x9:
2357                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2358                                        strlen_m(r->in.name)))
2359                 {
2360                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2361                                 r->in.name));
2362                         return WERR_INVALID_NAME;
2363                 }
2364                 break;
2365
2366         default:
2367                 return WERR_UNKNOWN_LEVEL;
2368         }
2369
2370         return WERR_OK;
2371 }
2372
2373 /********************************************************************
2374 ********************************************************************/
2375
2376 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2377 {
2378         return WERR_ACCESS_DENIED;
2379 }
2380
2381
2382 /********************************************************************
2383 ********************************************************************/
2384
2385 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2386 {
2387         p->rng_fault_state = True;
2388         return WERR_NOT_SUPPORTED;
2389 }
2390
2391 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2392 {
2393         p->rng_fault_state = True;
2394         return WERR_NOT_SUPPORTED;
2395 }
2396
2397 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2398 {
2399         p->rng_fault_state = True;
2400         return WERR_NOT_SUPPORTED;
2401 }
2402
2403 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2404 {
2405         p->rng_fault_state = True;
2406         return WERR_NOT_SUPPORTED;
2407 }
2408
2409 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2410 {
2411         p->rng_fault_state = True;
2412         return WERR_NOT_SUPPORTED;
2413 }
2414
2415 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2416 {
2417         p->rng_fault_state = True;
2418         return WERR_NOT_SUPPORTED;
2419 }
2420
2421 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2422 {
2423         p->rng_fault_state = True;
2424         return WERR_NOT_SUPPORTED;
2425 }
2426
2427 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2428 {
2429         p->rng_fault_state = True;
2430         return WERR_NOT_SUPPORTED;
2431 }
2432
2433 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2434 {
2435         p->rng_fault_state = True;
2436         return WERR_NOT_SUPPORTED;
2437 }
2438
2439 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2440 {
2441         p->rng_fault_state = True;
2442         return WERR_NOT_SUPPORTED;
2443 }
2444
2445 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2446 {
2447         p->rng_fault_state = True;
2448         return WERR_NOT_SUPPORTED;
2449 }
2450
2451 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2452 {
2453         p->rng_fault_state = True;
2454         return WERR_NOT_SUPPORTED;
2455 }
2456
2457 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2458 {
2459         p->rng_fault_state = True;
2460         return WERR_NOT_SUPPORTED;
2461 }
2462
2463 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2464 {
2465         p->rng_fault_state = True;
2466         return WERR_NOT_SUPPORTED;
2467 }
2468
2469 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2470 {
2471         p->rng_fault_state = True;
2472         return WERR_NOT_SUPPORTED;
2473 }
2474
2475 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2476 {
2477         p->rng_fault_state = True;
2478         return WERR_NOT_SUPPORTED;
2479 }
2480
2481 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2482 {
2483         p->rng_fault_state = True;
2484         return WERR_NOT_SUPPORTED;
2485 }
2486
2487 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2488 {
2489         p->rng_fault_state = True;
2490         return WERR_NOT_SUPPORTED;
2491 }
2492
2493 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2494 {
2495         p->rng_fault_state = True;
2496         return WERR_NOT_SUPPORTED;
2497 }
2498
2499 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2500 {
2501         p->rng_fault_state = True;
2502         return WERR_NOT_SUPPORTED;
2503 }
2504
2505 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2506 {
2507         p->rng_fault_state = True;
2508         return WERR_NOT_SUPPORTED;
2509 }
2510
2511 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2512 {
2513         p->rng_fault_state = True;
2514         return WERR_NOT_SUPPORTED;
2515 }
2516
2517 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2518 {
2519         p->rng_fault_state = True;
2520         return WERR_NOT_SUPPORTED;
2521 }
2522
2523 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2524 {
2525         p->rng_fault_state = True;
2526         return WERR_NOT_SUPPORTED;
2527 }
2528
2529 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2530 {
2531         p->rng_fault_state = True;
2532         return WERR_NOT_SUPPORTED;
2533 }
2534
2535 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2536 {
2537         p->rng_fault_state = True;
2538         return WERR_NOT_SUPPORTED;
2539 }
2540
2541 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2542 {
2543         p->rng_fault_state = True;
2544         return WERR_NOT_SUPPORTED;
2545 }
2546
2547 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2548 {
2549         p->rng_fault_state = True;
2550         return WERR_NOT_SUPPORTED;
2551 }
2552
2553 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2554 {
2555         p->rng_fault_state = True;
2556         return WERR_NOT_SUPPORTED;
2557 }
2558
2559 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2560 {
2561         p->rng_fault_state = True;
2562         return WERR_NOT_SUPPORTED;
2563 }
2564
2565 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2566 {
2567         p->rng_fault_state = True;
2568         return WERR_NOT_SUPPORTED;
2569 }
2570
2571 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2572 {
2573         p->rng_fault_state = True;
2574         return WERR_NOT_SUPPORTED;
2575 }
2576
2577 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2578 {
2579         p->rng_fault_state = True;
2580         return WERR_NOT_SUPPORTED;
2581 }
2582
2583 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2584 {
2585         p->rng_fault_state = True;
2586         return WERR_NOT_SUPPORTED;
2587 }
2588
2589 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2590 {
2591         p->rng_fault_state = True;
2592         return WERR_NOT_SUPPORTED;
2593 }
2594