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