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