Fix SRVSVC ShareInfo max_users handling server side.
[samba.git] / source / 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_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
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                                     (uint32_t)-1,
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, (uint32_t)-1);
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         if (r->out.parm_error) {
1488                 *r->out.parm_error = 0;
1489         }
1490
1491         if ( strequal(share_name,"IPC$")
1492                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1493                 || strequal(share_name,"global") )
1494         {
1495                 return WERR_ACCESS_DENIED;
1496         }
1497
1498         snum = find_service(share_name);
1499
1500         /* Does this share exist ? */
1501         if (snum < 0)
1502                 return WERR_NET_NAME_NOT_FOUND;
1503
1504         /* No change to printer shares. */
1505         if (lp_print_ok(snum))
1506                 return WERR_ACCESS_DENIED;
1507
1508         get_current_user(&user,p);
1509
1510         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1511
1512         /* fail out now if you are not root and not a disk op */
1513
1514         if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1515                 return WERR_ACCESS_DENIED;
1516
1517         switch (r->in.level) {
1518         case 1:
1519                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1520                 comment = talloc_strdup(ctx, info->info1->comment);
1521                 type = info->info1->type;
1522                 psd = NULL;
1523                 break;
1524         case 2:
1525                 comment = talloc_strdup(ctx, info->info2->comment);
1526                 pathname = info->info2->path;
1527                 type = info->info2->type;
1528                 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1529                         0 : info->info2->max_users;
1530                 psd = NULL;
1531                 break;
1532 #if 0
1533                 /* not supported on set but here for completeness */
1534         case 501:
1535                 comment = talloc_strdup(ctx, info->info501->comment);
1536                 type = info->info501->type;
1537                 psd = NULL;
1538                 break;
1539 #endif
1540         case 502:
1541                 comment = talloc_strdup(ctx, info->info502->comment);
1542                 pathname = info->info502->path;
1543                 type = info->info502->type;
1544                 psd = info->info502->sd;
1545                 map_generic_share_sd_bits(psd);
1546                 break;
1547         case 1004:
1548                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1549                 comment = talloc_strdup(ctx, info->info1004->comment);
1550                 type = STYPE_DISKTREE;
1551                 break;
1552         case 1005:
1553                 /* XP re-sets the csc policy even if it wasn't changed by the
1554                    user, so we must compare it to see if it's what is set in
1555                    smb.conf, so that we can contine other ops like setting
1556                    ACLs on a share */
1557                 if (((info->info1005->dfs_flags &
1558                       SHARE_1005_CSC_POLICY_MASK) >>
1559                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1560                         return WERR_OK;
1561                 else {
1562                         DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1563                         return WERR_ACCESS_DENIED;
1564                 }
1565         case 1006:
1566         case 1007:
1567                 return WERR_ACCESS_DENIED;
1568         case 1501:
1569                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1570                 comment = talloc_strdup(ctx, lp_comment(snum));
1571                 psd = info->info1501->sd;
1572                 map_generic_share_sd_bits(psd);
1573                 type = STYPE_DISKTREE;
1574                 break;
1575         default:
1576                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1577                         r->in.level));
1578                 return WERR_UNKNOWN_LEVEL;
1579         }
1580
1581         /* We can only modify disk shares. */
1582         if (type != STYPE_DISKTREE)
1583                 return WERR_ACCESS_DENIED;
1584
1585         if (comment == NULL) {
1586                 return WERR_NOMEM;
1587         }
1588
1589         /* Check if the pathname is valid. */
1590         if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1591                 return WERR_OBJECT_PATH_INVALID;
1592
1593         /* Ensure share name, pathname and comment don't contain '"' characters. */
1594         string_replace(share_name, '"', ' ');
1595         string_replace(path, '"', ' ');
1596         string_replace(comment, '"', ' ');
1597
1598         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1599                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1600
1601         /* Only call modify function if something changed. */
1602
1603         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1604                         || (lp_max_connections(snum) != max_connections)) {
1605                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1606                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1607                         return WERR_ACCESS_DENIED;
1608                 }
1609
1610                 command = talloc_asprintf(p->mem_ctx,
1611                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1612                                 lp_change_share_cmd(),
1613                                 get_dyn_CONFIGFILE(),
1614                                 share_name,
1615                                 path,
1616                                 comment ? comment : "",
1617                                 max_connections);
1618                 if (!command) {
1619                         return WERR_NOMEM;
1620                 }
1621
1622                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1623
1624                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1625
1626                 if (is_disk_op)
1627                         become_root();
1628
1629                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1630                         /* Tell everyone we updated smb.conf. */
1631                         message_send_all(smbd_messaging_context(),
1632                                          MSG_SMB_CONF_UPDATED, NULL, 0,
1633                                          NULL);
1634                 }
1635
1636                 if ( is_disk_op )
1637                         unbecome_root();
1638
1639                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1640
1641                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1642                         command, ret ));
1643
1644                 TALLOC_FREE(command);
1645
1646                 if ( ret != 0 )
1647                         return WERR_ACCESS_DENIED;
1648         } else {
1649                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1650                         share_name ));
1651         }
1652
1653         /* Replace SD if changed. */
1654         if (psd) {
1655                 SEC_DESC *old_sd;
1656                 size_t sd_size;
1657
1658                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1659
1660                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1661                         if (!set_share_security(share_name, psd))
1662                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1663                                         share_name ));
1664                 }
1665         }
1666
1667         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1668
1669         return WERR_OK;
1670 }
1671
1672 /*******************************************************************
1673  _srvsvc_NetShareAdd.
1674  Call 'add_share_command "sharename" "pathname"
1675  "comment" "max connections = "
1676 ********************************************************************/
1677
1678 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1679                            struct srvsvc_NetShareAdd *r)
1680 {
1681         struct current_user user;
1682         char *command = NULL;
1683         char *share_name = NULL;
1684         char *comment = NULL;
1685         char *pathname = NULL;
1686         int type;
1687         int snum;
1688         int ret;
1689         char *path;
1690         SEC_DESC *psd = NULL;
1691         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1692         bool is_disk_op;
1693         int max_connections = 0;
1694         TALLOC_CTX *ctx = p->mem_ctx;
1695
1696         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1697
1698         *r->out.parm_error = 0;
1699
1700         get_current_user(&user,p);
1701
1702         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1703
1704         if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1705                 return WERR_ACCESS_DENIED;
1706
1707         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1708                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1709                 return WERR_ACCESS_DENIED;
1710         }
1711
1712         switch (r->in.level) {
1713         case 0:
1714                 /* No path. Not enough info in a level 0 to do anything. */
1715                 return WERR_ACCESS_DENIED;
1716         case 1:
1717                 /* Not enough info in a level 1 to do anything. */
1718                 return WERR_ACCESS_DENIED;
1719         case 2:
1720                 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1721                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1722                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1723                 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1724                         0 : r->in.info->info2->max_users;
1725                 type = r->in.info->info2->type;
1726                 break;
1727         case 501:
1728                 /* No path. Not enough info in a level 501 to do anything. */
1729                 return WERR_ACCESS_DENIED;
1730         case 502:
1731                 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1732                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1733                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1734                 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1735                         0 : r->in.info->info502->max_users;
1736                 type = r->in.info->info502->type;
1737                 psd = r->in.info->info502->sd;
1738                 map_generic_share_sd_bits(psd);
1739                 break;
1740
1741                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1742
1743         case 1004:
1744         case 1005:
1745         case 1006:
1746         case 1007:
1747                 return WERR_ACCESS_DENIED;
1748         case 1501:
1749                 /* DFS only level. */
1750                 return WERR_ACCESS_DENIED;
1751         default:
1752                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1753                         r->in.level));
1754                 return WERR_UNKNOWN_LEVEL;
1755         }
1756
1757         /* check for invalid share names */
1758
1759         if (!share_name || !validate_net_name(share_name,
1760                                 INVALID_SHARENAME_CHARS,
1761                                 strlen(share_name))) {
1762                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1763                                         share_name ? share_name : ""));
1764                 return WERR_INVALID_NAME;
1765         }
1766
1767         if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1768                         || (lp_enable_asu_support() &&
1769                                         strequal(share_name,"ADMIN$"))) {
1770                 return WERR_ACCESS_DENIED;
1771         }
1772
1773         snum = find_service(share_name);
1774
1775         /* Share already exists. */
1776         if (snum >= 0) {
1777                 return WERR_ALREADY_EXISTS;
1778         }
1779
1780         /* We can only add disk shares. */
1781         if (type != STYPE_DISKTREE) {
1782                 return WERR_ACCESS_DENIED;
1783         }
1784
1785         /* Check if the pathname is valid. */
1786         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1787                 return WERR_OBJECT_PATH_INVALID;
1788         }
1789
1790         /* Ensure share name, pathname and comment don't contain '"' characters. */
1791         string_replace(share_name, '"', ' ');
1792         string_replace(path, '"', ' ');
1793         if (comment) {
1794                 string_replace(comment, '"', ' ');
1795         }
1796
1797         command = talloc_asprintf(ctx,
1798                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1799                         lp_add_share_cmd(),
1800                         get_dyn_CONFIGFILE(),
1801                         share_name,
1802                         path,
1803                         comment ? comment : "",
1804                         max_connections);
1805         if (!command) {
1806                 return WERR_NOMEM;
1807         }
1808
1809         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1810
1811         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1812
1813         if ( is_disk_op )
1814                 become_root();
1815
1816         /* FIXME: use libnetconf here - gd */
1817
1818         if ( (ret = smbrun(command, NULL)) == 0 ) {
1819                 /* Tell everyone we updated smb.conf. */
1820                 message_send_all(smbd_messaging_context(),
1821                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1822         }
1823
1824         if ( is_disk_op )
1825                 unbecome_root();
1826
1827         /********* END SeDiskOperatorPrivilege BLOCK *********/
1828
1829         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1830                 command, ret ));
1831
1832         TALLOC_FREE(command);
1833
1834         if ( ret != 0 )
1835                 return WERR_ACCESS_DENIED;
1836
1837         if (psd) {
1838                 if (!set_share_security(share_name, psd)) {
1839                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1840                                 share_name ));
1841                 }
1842         }
1843
1844         /*
1845          * We don't call reload_services() here, the message will
1846          * cause this to be done before the next packet is read
1847          * from the client. JRA.
1848          */
1849
1850         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1851
1852         return WERR_OK;
1853 }
1854
1855 /*******************************************************************
1856  _srvsvc_NetShareDel
1857  Call "delete share command" with the share name as
1858  a parameter.
1859 ********************************************************************/
1860
1861 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1862                            struct srvsvc_NetShareDel *r)
1863 {
1864         struct current_user user;
1865         char *command = NULL;
1866         char *share_name = NULL;
1867         int ret;
1868         int snum;
1869         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1870         bool is_disk_op;
1871         struct share_params *params;
1872         TALLOC_CTX *ctx = p->mem_ctx;
1873
1874         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1875
1876         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1877         if (!share_name) {
1878                 return WERR_NET_NAME_NOT_FOUND;
1879         }
1880         if ( strequal(share_name,"IPC$")
1881                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1882                 || strequal(share_name,"global") )
1883         {
1884                 return WERR_ACCESS_DENIED;
1885         }
1886
1887         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1888                 return WERR_NO_SUCH_SHARE;
1889         }
1890
1891         snum = find_service(share_name);
1892
1893         /* No change to printer shares. */
1894         if (lp_print_ok(snum))
1895                 return WERR_ACCESS_DENIED;
1896
1897         get_current_user(&user,p);
1898
1899         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1900
1901         if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1902                 return WERR_ACCESS_DENIED;
1903
1904         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1905                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1906                 return WERR_ACCESS_DENIED;
1907         }
1908
1909         command = talloc_asprintf(ctx,
1910                         "%s \"%s\" \"%s\"",
1911                         lp_delete_share_cmd(),
1912                         get_dyn_CONFIGFILE(),
1913                         lp_servicename(snum));
1914         if (!command) {
1915                 return WERR_NOMEM;
1916         }
1917
1918         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1919
1920         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1921
1922         if ( is_disk_op )
1923                 become_root();
1924
1925         if ( (ret = smbrun(command, NULL)) == 0 ) {
1926                 /* Tell everyone we updated smb.conf. */
1927                 message_send_all(smbd_messaging_context(),
1928                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1929         }
1930
1931         if ( is_disk_op )
1932                 unbecome_root();
1933
1934         /********* END SeDiskOperatorPrivilege BLOCK *********/
1935
1936         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1937
1938         if ( ret != 0 )
1939                 return WERR_ACCESS_DENIED;
1940
1941         /* Delete the SD in the database. */
1942         delete_share_security(lp_servicename(params->service));
1943
1944         lp_killservice(params->service);
1945
1946         return WERR_OK;
1947 }
1948
1949 /*******************************************************************
1950  _srvsvc_NetShareDelSticky
1951 ********************************************************************/
1952
1953 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1954                                  struct srvsvc_NetShareDelSticky *r)
1955 {
1956         struct srvsvc_NetShareDel q;
1957
1958         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1959
1960         q.in.server_unc         = r->in.server_unc;
1961         q.in.share_name         = r->in.share_name;
1962         q.in.reserved           = r->in.reserved;
1963
1964         return _srvsvc_NetShareDel(p, &q);
1965 }
1966
1967 /*******************************************************************
1968  _srvsvc_NetRemoteTOD
1969 ********************************************************************/
1970
1971 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1972                             struct srvsvc_NetRemoteTOD *r)
1973 {
1974         struct srvsvc_NetRemoteTODInfo *tod;
1975         struct tm *t;
1976         time_t unixdate = time(NULL);
1977
1978         /* We do this call first as if we do it *after* the gmtime call
1979            it overwrites the pointed-to values. JRA */
1980
1981         uint32 zone = get_time_zone(unixdate)/60;
1982
1983         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1984
1985         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1986                 return WERR_NOMEM;
1987
1988         *r->out.info = tod;
1989
1990         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1991
1992         t = gmtime(&unixdate);
1993
1994         /* set up the */
1995         init_srvsvc_NetRemoteTODInfo(tod,
1996                                      unixdate,
1997                                      0,
1998                                      t->tm_hour,
1999                                      t->tm_min,
2000                                      t->tm_sec,
2001                                      0,
2002                                      zone,
2003                                      10000,
2004                                      t->tm_mday,
2005                                      t->tm_mon + 1,
2006                                      1900+t->tm_year,
2007                                      t->tm_wday);
2008
2009         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2010
2011         return WERR_OK;
2012 }
2013
2014 /***********************************************************************************
2015  _srvsvc_NetGetFileSecurity
2016  Win9x NT tools get security descriptor.
2017 ***********************************************************************************/
2018
2019 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2020                                   struct srvsvc_NetGetFileSecurity *r)
2021 {
2022         SEC_DESC *psd = NULL;
2023         size_t sd_size;
2024         DATA_BLOB null_pw;
2025         char *filename_in = NULL;
2026         char *filename = NULL;
2027         char *qualname = NULL;
2028         SMB_STRUCT_STAT st;
2029         NTSTATUS nt_status;
2030         WERROR werr;
2031         struct current_user user;
2032         connection_struct *conn = NULL;
2033         bool became_user = False;
2034         TALLOC_CTX *ctx = p->mem_ctx;
2035         struct sec_desc_buf *sd_buf;
2036
2037         ZERO_STRUCT(st);
2038
2039         werr = WERR_OK;
2040
2041         qualname = talloc_strdup(ctx, r->in.share);
2042         if (!qualname) {
2043                 werr = WERR_ACCESS_DENIED;
2044                 goto error_exit;
2045         }
2046
2047         /* Null password is ok - we are already an authenticated user... */
2048         null_pw = data_blob_null;
2049
2050         get_current_user(&user, p);
2051
2052         become_root();
2053         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2054         unbecome_root();
2055
2056         if (conn == NULL) {
2057                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2058                         qualname));
2059                 werr = ntstatus_to_werror(nt_status);
2060                 goto error_exit;
2061         }
2062
2063         if (!become_user(conn, conn->vuid)) {
2064                 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2065                 werr = WERR_ACCESS_DENIED;
2066                 goto error_exit;
2067         }
2068         became_user = True;
2069
2070         filename_in = talloc_strdup(ctx, r->in.file);
2071         if (!filename_in) {
2072                 werr = WERR_ACCESS_DENIED;
2073                 goto error_exit;
2074         }
2075
2076         nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2077         if (!NT_STATUS_IS_OK(nt_status)) {
2078                 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2079                         filename));
2080                 werr = WERR_ACCESS_DENIED;
2081                 goto error_exit;
2082         }
2083
2084         nt_status = check_name(conn, filename);
2085         if (!NT_STATUS_IS_OK(nt_status)) {
2086                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2087                         filename));
2088                 werr = WERR_ACCESS_DENIED;
2089                 goto error_exit;
2090         }
2091
2092         nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2093                                        (OWNER_SECURITY_INFORMATION
2094                                         |GROUP_SECURITY_INFORMATION
2095                                         |DACL_SECURITY_INFORMATION), &psd);
2096
2097         if (!NT_STATUS_IS_OK(nt_status)) {
2098                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2099                         filename));
2100                 werr = ntstatus_to_werror(nt_status);
2101                 goto error_exit;
2102         }
2103
2104         sd_size = ndr_size_security_descriptor(psd, 0);
2105
2106         sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2107         if (!sd_buf) {
2108                 werr = WERR_NOMEM;
2109                 goto error_exit;
2110         }
2111
2112         sd_buf->sd_size = sd_size;
2113         sd_buf->sd = psd;
2114
2115         *r->out.sd_buf = sd_buf;
2116
2117         psd->dacl->revision = NT4_ACL_REVISION;
2118
2119         unbecome_user();
2120         close_cnum(conn, user.vuid);
2121         return werr;
2122
2123 error_exit:
2124
2125         if (became_user)
2126                 unbecome_user();
2127
2128         if (conn)
2129                 close_cnum(conn, user.vuid);
2130
2131         return werr;
2132 }
2133
2134 /***********************************************************************************
2135  _srvsvc_NetSetFileSecurity
2136  Win9x NT tools set security descriptor.
2137 ***********************************************************************************/
2138
2139 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2140                                   struct srvsvc_NetSetFileSecurity *r)
2141 {
2142         char *filename_in = NULL;
2143         char *filename = NULL;
2144         char *qualname = NULL;
2145         DATA_BLOB null_pw;
2146         files_struct *fsp = NULL;
2147         SMB_STRUCT_STAT st;
2148         NTSTATUS nt_status;
2149         WERROR werr;
2150         struct current_user user;
2151         connection_struct *conn = NULL;
2152         bool became_user = False;
2153         TALLOC_CTX *ctx = p->mem_ctx;
2154
2155         ZERO_STRUCT(st);
2156
2157         werr = WERR_OK;
2158
2159         qualname = talloc_strdup(ctx, r->in.share);
2160         if (!qualname) {
2161                 werr = WERR_ACCESS_DENIED;
2162                 goto error_exit;
2163         }
2164
2165         /* Null password is ok - we are already an authenticated user... */
2166         null_pw = data_blob_null;
2167
2168         get_current_user(&user, p);
2169
2170         become_root();
2171         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2172         unbecome_root();
2173
2174         if (conn == NULL) {
2175                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2176                 werr = ntstatus_to_werror(nt_status);
2177                 goto error_exit;
2178         }
2179
2180         if (!become_user(conn, conn->vuid)) {
2181                 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2182                 werr = WERR_ACCESS_DENIED;
2183                 goto error_exit;
2184         }
2185         became_user = True;
2186
2187         filename_in = talloc_strdup(ctx, r->in.file);
2188         if (!filename_in) {
2189                 werr = WERR_ACCESS_DENIED;
2190                 goto error_exit;
2191         }
2192
2193         nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2194         if (!NT_STATUS_IS_OK(nt_status)) {
2195                 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2196                 werr = WERR_ACCESS_DENIED;
2197                 goto error_exit;
2198         }
2199
2200         nt_status = check_name(conn, filename);
2201         if (!NT_STATUS_IS_OK(nt_status)) {
2202                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2203                 werr = WERR_ACCESS_DENIED;
2204                 goto error_exit;
2205         }
2206
2207         nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2208
2209         if ( !NT_STATUS_IS_OK(nt_status) ) {
2210                 /* Perhaps it is a directory */
2211                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2212                         nt_status = open_directory(conn, NULL, filename, &st,
2213                                                 FILE_READ_ATTRIBUTES,
2214                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2215                                                 FILE_OPEN,
2216                                                 0,
2217                                                 FILE_ATTRIBUTE_DIRECTORY,
2218                                                 NULL, &fsp);
2219
2220                 if ( !NT_STATUS_IS_OK(nt_status) ) {
2221                         DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2222                         werr = ntstatus_to_werror(nt_status);
2223                         goto error_exit;
2224                 }
2225         }
2226
2227         nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2228                                        r->in.securityinformation,
2229                                        r->in.sd_buf->sd);
2230
2231         if (!NT_STATUS_IS_OK(nt_status) ) {
2232                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2233                 werr = WERR_ACCESS_DENIED;
2234                 goto error_exit;
2235         }
2236
2237         close_file(fsp, NORMAL_CLOSE);
2238         unbecome_user();
2239         close_cnum(conn, user.vuid);
2240         return werr;
2241
2242 error_exit:
2243
2244         if(fsp) {
2245                 close_file(fsp, NORMAL_CLOSE);
2246         }
2247
2248         if (became_user) {
2249                 unbecome_user();
2250         }
2251
2252         if (conn) {
2253                 close_cnum(conn, user.vuid);
2254         }
2255
2256         return werr;
2257 }
2258
2259 /***********************************************************************************
2260  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2261  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2262  These disks would the disks listed by this function.
2263  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2264  "Nigel Williams" <nigel@veritas.com>.
2265 ***********************************************************************************/
2266
2267 static const char *server_disks[] = {"C:"};
2268
2269 static uint32 get_server_disk_count(void)
2270 {
2271         return sizeof(server_disks)/sizeof(server_disks[0]);
2272 }
2273
2274 static uint32 init_server_disk_enum(uint32 *resume)
2275 {
2276         uint32 server_disk_count = get_server_disk_count();
2277
2278         /*resume can be an offset into the list for now*/
2279
2280         if(*resume & 0x80000000)
2281                 *resume = 0;
2282
2283         if(*resume > server_disk_count)
2284                 *resume = server_disk_count;
2285
2286         return server_disk_count - *resume;
2287 }
2288
2289 static const char *next_server_disk_enum(uint32 *resume)
2290 {
2291         const char *disk;
2292
2293         if(init_server_disk_enum(resume) == 0)
2294                 return NULL;
2295
2296         disk = server_disks[*resume];
2297
2298         (*resume)++;
2299
2300         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2301
2302         return disk;
2303 }
2304
2305 /********************************************************************
2306  _srvsvc_NetDiskEnum
2307 ********************************************************************/
2308
2309 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2310                            struct srvsvc_NetDiskEnum *r)
2311 {
2312         uint32 i;
2313         const char *disk_name;
2314         TALLOC_CTX *ctx = p->mem_ctx;
2315         WERROR werr;
2316         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2317
2318         werr = WERR_OK;
2319
2320         *r->out.totalentries = init_server_disk_enum(&resume);
2321
2322         r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2323                                                MAX_SERVER_DISK_ENTRIES);
2324         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2325
2326         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2327
2328         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2329
2330                 r->out.info->count++;
2331
2332                 /*copy disk name into a unicode string*/
2333
2334                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2335                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2336         }
2337
2338         /* add a terminating null string.  Is this there if there is more data to come? */
2339
2340         r->out.info->count++;
2341
2342         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2343         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2344
2345         if (r->out.resume_handle) {
2346                 *r->out.resume_handle = resume;
2347         }
2348
2349         return werr;
2350 }
2351
2352 /********************************************************************
2353  _srvsvc_NetNameValidate
2354 ********************************************************************/
2355
2356 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2357                                struct srvsvc_NetNameValidate *r)
2358 {
2359         switch (r->in.name_type) {
2360         case 0x9:
2361                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2362                                        strlen_m(r->in.name)))
2363                 {
2364                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2365                                 r->in.name));
2366                         return WERR_INVALID_NAME;
2367                 }
2368                 break;
2369
2370         default:
2371                 return WERR_UNKNOWN_LEVEL;
2372         }
2373
2374         return WERR_OK;
2375 }
2376
2377 /********************************************************************
2378 ********************************************************************/
2379
2380 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2381 {
2382         return WERR_ACCESS_DENIED;
2383 }
2384
2385
2386 /********************************************************************
2387 ********************************************************************/
2388
2389 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2390 {
2391         p->rng_fault_state = True;
2392         return WERR_NOT_SUPPORTED;
2393 }
2394
2395 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2396 {
2397         p->rng_fault_state = True;
2398         return WERR_NOT_SUPPORTED;
2399 }
2400
2401 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2402 {
2403         p->rng_fault_state = True;
2404         return WERR_NOT_SUPPORTED;
2405 }
2406
2407 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2408 {
2409         p->rng_fault_state = True;
2410         return WERR_NOT_SUPPORTED;
2411 }
2412
2413 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2414 {
2415         p->rng_fault_state = True;
2416         return WERR_NOT_SUPPORTED;
2417 }
2418
2419 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2420 {
2421         p->rng_fault_state = True;
2422         return WERR_NOT_SUPPORTED;
2423 }
2424
2425 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2426 {
2427         p->rng_fault_state = True;
2428         return WERR_NOT_SUPPORTED;
2429 }
2430
2431 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2432 {
2433         p->rng_fault_state = True;
2434         return WERR_NOT_SUPPORTED;
2435 }
2436
2437 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2438 {
2439         p->rng_fault_state = True;
2440         return WERR_NOT_SUPPORTED;
2441 }
2442
2443 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2444 {
2445         p->rng_fault_state = True;
2446         return WERR_NOT_SUPPORTED;
2447 }
2448
2449 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2450 {
2451         p->rng_fault_state = True;
2452         return WERR_NOT_SUPPORTED;
2453 }
2454
2455 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2456 {
2457         p->rng_fault_state = True;
2458         return WERR_NOT_SUPPORTED;
2459 }
2460
2461 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2462 {
2463         p->rng_fault_state = True;
2464         return WERR_NOT_SUPPORTED;
2465 }
2466
2467 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2468 {
2469         p->rng_fault_state = True;
2470         return WERR_NOT_SUPPORTED;
2471 }
2472
2473 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2474 {
2475         p->rng_fault_state = True;
2476         return WERR_NOT_SUPPORTED;
2477 }
2478
2479 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2480 {
2481         p->rng_fault_state = True;
2482         return WERR_NOT_SUPPORTED;
2483 }
2484
2485 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2486 {
2487         p->rng_fault_state = True;
2488         return WERR_NOT_SUPPORTED;
2489 }
2490
2491 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2492 {
2493         p->rng_fault_state = True;
2494         return WERR_NOT_SUPPORTED;
2495 }
2496
2497 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2498 {
2499         p->rng_fault_state = True;
2500         return WERR_NOT_SUPPORTED;
2501 }
2502
2503 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2504 {
2505         p->rng_fault_state = True;
2506         return WERR_NOT_SUPPORTED;
2507 }
2508
2509 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2510 {
2511         p->rng_fault_state = True;
2512         return WERR_NOT_SUPPORTED;
2513 }
2514
2515 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2516 {
2517         p->rng_fault_state = True;
2518         return WERR_NOT_SUPPORTED;
2519 }
2520
2521 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2522 {
2523         p->rng_fault_state = True;
2524         return WERR_NOT_SUPPORTED;
2525 }
2526
2527 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2528 {
2529         p->rng_fault_state = True;
2530         return WERR_NOT_SUPPORTED;
2531 }
2532
2533 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2534 {
2535         p->rng_fault_state = True;
2536         return WERR_NOT_SUPPORTED;
2537 }
2538
2539 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2540 {
2541         p->rng_fault_state = True;
2542         return WERR_NOT_SUPPORTED;
2543 }
2544
2545 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2546 {
2547         p->rng_fault_state = True;
2548         return WERR_NOT_SUPPORTED;
2549 }
2550
2551 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2552 {
2553         p->rng_fault_state = True;
2554         return WERR_NOT_SUPPORTED;
2555 }
2556
2557 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2558 {
2559         p->rng_fault_state = True;
2560         return WERR_NOT_SUPPORTED;
2561 }
2562
2563 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2564 {
2565         p->rng_fault_state = True;
2566         return WERR_NOT_SUPPORTED;
2567 }
2568
2569 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2570 {
2571         p->rng_fault_state = True;
2572         return WERR_NOT_SUPPORTED;
2573 }
2574
2575 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2576 {
2577         p->rng_fault_state = True;
2578         return WERR_NOT_SUPPORTED;
2579 }
2580
2581 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2582 {
2583         p->rng_fault_state = True;
2584         return WERR_NOT_SUPPORTED;
2585 }
2586
2587 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2588 {
2589         p->rng_fault_state = True;
2590         return WERR_NOT_SUPPORTED;
2591 }
2592
2593 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2594 {
2595         p->rng_fault_state = True;
2596         return WERR_NOT_SUPPORTED;
2597 }
2598