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