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