S3: Small fix to get rid of annoying log message.
[kai/samba.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",
544                                 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
545                         allowed[snum] = true;
546                         num_entries++;
547                 } else {
548                         DEBUG(10, ("NOT counting service %s\n",
549                                 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
550                 }
551         }
552
553         if (!num_entries || (resume_handle >= num_entries)) {
554                 return WERR_OK;
555         }
556
557         /* Calculate alloc entries. */
558         alloc_entries = num_entries - resume_handle;
559         switch (info_ctr->level) {
560         case 0:
561                 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
562                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
563
564                 ctr.ctr0->count = alloc_entries;
565                 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
566                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
567
568                 for (snum = 0; snum < num_services; snum++) {
569                         if (allowed[snum] &&
570                             (resume_handle <= (i + valid_share_count++)) ) {
571                                 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
572                         }
573                 }
574
575                 break;
576
577         case 1:
578                 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
579                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
580
581                 ctr.ctr1->count = alloc_entries;
582                 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
583                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
584
585                 for (snum = 0; snum < num_services; snum++) {
586                         if (allowed[snum] &&
587                             (resume_handle <= (i + valid_share_count++)) ) {
588                                 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
589                         }
590                 }
591
592                 break;
593
594         case 2:
595                 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
596                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
597
598                 ctr.ctr2->count = alloc_entries;
599                 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
600                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
601
602                 for (snum = 0; snum < num_services; snum++) {
603                         if (allowed[snum] &&
604                             (resume_handle <= (i + valid_share_count++)) ) {
605                                 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
606                         }
607                 }
608
609                 break;
610
611         case 501:
612                 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
613                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
614
615                 ctr.ctr501->count = alloc_entries;
616                 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
617                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
618
619                 for (snum = 0; snum < num_services; snum++) {
620                         if (allowed[snum] &&
621                             (resume_handle <= (i + valid_share_count++)) ) {
622                                 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
623                         }
624                 }
625
626                 break;
627
628         case 502:
629                 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
630                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
631
632                 ctr.ctr502->count = alloc_entries;
633                 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
634                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
635
636                 for (snum = 0; snum < num_services; snum++) {
637                         if (allowed[snum] &&
638                             (resume_handle <= (i + valid_share_count++)) ) {
639                                 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
640                         }
641                 }
642
643                 break;
644
645         case 1004:
646                 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
647                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
648
649                 ctr.ctr1004->count = alloc_entries;
650                 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
651                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
652
653                 for (snum = 0; snum < num_services; snum++) {
654                         if (allowed[snum] &&
655                             (resume_handle <= (i + valid_share_count++)) ) {
656                                 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
657                         }
658                 }
659
660                 break;
661
662         case 1005:
663                 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
664                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
665
666                 ctr.ctr1005->count = alloc_entries;
667                 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
668                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
669
670                 for (snum = 0; snum < num_services; snum++) {
671                         if (allowed[snum] &&
672                             (resume_handle <= (i + valid_share_count++)) ) {
673                                 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
674                         }
675                 }
676
677                 break;
678
679         case 1006:
680                 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
681                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
682
683                 ctr.ctr1006->count = alloc_entries;
684                 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
685                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
686
687                 for (snum = 0; snum < num_services; snum++) {
688                         if (allowed[snum] &&
689                             (resume_handle <= (i + valid_share_count++)) ) {
690                                 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
691                         }
692                 }
693
694                 break;
695
696         case 1007:
697                 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
698                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
699
700                 ctr.ctr1007->count = alloc_entries;
701                 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
702                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
703
704                 for (snum = 0; snum < num_services; snum++) {
705                         if (allowed[snum] &&
706                             (resume_handle <= (i + valid_share_count++)) ) {
707                                 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
708                         }
709                 }
710
711                 break;
712
713         case 1501:
714                 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
715                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
716
717                 ctr.ctr1501->count = alloc_entries;
718                 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
719                 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
720
721                 for (snum = 0; snum < num_services; snum++) {
722                         if (allowed[snum] &&
723                             (resume_handle <= (i + valid_share_count++)) ) {
724                                 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
725                         }
726                 }
727
728                 break;
729
730         default:
731                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
732                         info_ctr->level));
733                 return WERR_UNKNOWN_LEVEL;
734         }
735
736         *total_entries = alloc_entries;
737         if (resume_handle_p) {
738                 if (all_shares) {
739                         *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
740                 } else {
741                         *resume_handle_p = num_entries;
742                 }
743         }
744
745         info_ctr->ctr = ctr;
746
747         return WERR_OK;
748 }
749
750 /*******************************************************************
751  fill in a sess info level 0 structure.
752  ********************************************************************/
753
754 static WERROR init_srv_sess_info_0(pipes_struct *p,
755                                    struct srvsvc_NetSessCtr0 *ctr0,
756                                    uint32_t *resume_handle_p,
757                                    uint32_t *total_entries)
758 {
759         struct sessionid *session_list;
760         uint32_t num_entries = 0;
761         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
762         *total_entries = list_sessions(p->mem_ctx, &session_list);
763
764         DEBUG(5,("init_srv_sess_info_0\n"));
765
766         if (ctr0 == NULL) {
767                 if (resume_handle_p) {
768                         *resume_handle_p = 0;
769                 }
770                 return WERR_OK;
771         }
772
773         for (; resume_handle < *total_entries; resume_handle++) {
774
775                 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
776                                                    ctr0->array,
777                                                    struct srvsvc_NetSessInfo0,
778                                                    num_entries+1);
779                 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
780
781                 ctr0->array[num_entries].client =
782                         session_list[resume_handle].remote_machine;
783
784                 num_entries++;
785         }
786
787         ctr0->count = num_entries;
788
789         if (resume_handle_p) {
790                 if (*resume_handle_p >= *total_entries) {
791                         *resume_handle_p = 0;
792                 } else {
793                         *resume_handle_p = resume_handle;
794                 }
795         }
796
797         return WERR_OK;
798 }
799
800 /*******************************************************************
801 ********************************************************************/
802
803 static void sess_file_fn( const struct share_mode_entry *e,
804                           const char *sharepath, const char *fname,
805                           void *data )
806 {
807         struct sess_file_count *sess = (struct sess_file_count *)data;
808
809         if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
810                 sess->count++;
811         }
812
813         return;
814 }
815
816 /*******************************************************************
817 ********************************************************************/
818
819 static int net_count_files( uid_t uid, struct server_id pid )
820 {
821         struct sess_file_count s_file_cnt;
822
823         s_file_cnt.count = 0;
824         s_file_cnt.uid = uid;
825         s_file_cnt.pid = pid;
826
827         share_mode_forall( sess_file_fn, &s_file_cnt );
828
829         return s_file_cnt.count;
830 }
831
832 /*******************************************************************
833  fill in a sess info level 1 structure.
834  ********************************************************************/
835
836 static WERROR init_srv_sess_info_1(pipes_struct *p,
837                                    struct srvsvc_NetSessCtr1 *ctr1,
838                                    uint32_t *resume_handle_p,
839                                    uint32_t *total_entries)
840 {
841         struct sessionid *session_list;
842         uint32_t num_entries = 0;
843         time_t now = time(NULL);
844         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
845
846         ZERO_STRUCTP(ctr1);
847
848         if (ctr1 == NULL) {
849                 if (resume_handle_p) {
850                         *resume_handle_p = 0;
851                 }
852                 return WERR_OK;
853         }
854
855         *total_entries = list_sessions(p->mem_ctx, &session_list);
856
857         for (; resume_handle < *total_entries; resume_handle++) {
858                 uint32 num_files;
859                 uint32 connect_time;
860                 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
861                 bool guest;
862
863                 if ( !pw ) {
864                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
865                                 session_list[resume_handle].username));
866                         continue;
867                 }
868
869                 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
870                 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
871                 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
872
873                 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
874                                                    ctr1->array,
875                                                    struct srvsvc_NetSessInfo1,
876                                                    num_entries+1);
877                 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
878
879                 ctr1->array[num_entries].client         = session_list[resume_handle].remote_machine;
880                 ctr1->array[num_entries].user           = session_list[resume_handle].username;
881                 ctr1->array[num_entries].num_open       = num_files;
882                 ctr1->array[num_entries].time           = connect_time;
883                 ctr1->array[num_entries].idle_time      = 0;
884                 ctr1->array[num_entries].user_flags     = guest;
885
886                 num_entries++;
887         }
888
889         ctr1->count = num_entries;
890
891         if (resume_handle_p) {
892                 if (*resume_handle_p >= *total_entries) {
893                         *resume_handle_p = 0;
894                 } else {
895                         *resume_handle_p = resume_handle;
896                 }
897         }
898
899         return WERR_OK;
900 }
901
902 /*******************************************************************
903  fill in a conn info level 0 structure.
904  ********************************************************************/
905
906 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
907                                    uint32_t *resume_handle_p,
908                                    uint32_t *total_entries)
909 {
910         uint32_t num_entries = 0;
911         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
912
913         DEBUG(5,("init_srv_conn_info_0\n"));
914
915         if (ctr0 == NULL) {
916                 if (resume_handle_p) {
917                         *resume_handle_p = 0;
918                 }
919                 return WERR_OK;
920         }
921
922         *total_entries = 1;
923
924         ZERO_STRUCTP(ctr0);
925
926         for (; resume_handle < *total_entries; resume_handle++) {
927
928                 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
929                                                    ctr0->array,
930                                                    struct srvsvc_NetConnInfo0,
931                                                    num_entries+1);
932                 if (!ctr0->array) {
933                         return WERR_NOMEM;
934                 }
935
936                 ctr0->array[num_entries].conn_id = *total_entries;
937
938                 /* move on to creating next connection */
939                 num_entries++;
940         }
941
942         ctr0->count = num_entries;
943         *total_entries = num_entries;
944
945         if (resume_handle_p) {
946                 if (*resume_handle_p >= *total_entries) {
947                         *resume_handle_p = 0;
948                 } else {
949                         *resume_handle_p = resume_handle;
950                 }
951         }
952
953         return WERR_OK;
954 }
955
956 /*******************************************************************
957  fill in a conn info level 1 structure.
958  ********************************************************************/
959
960 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
961                                    uint32_t *resume_handle_p,
962                                    uint32_t *total_entries)
963 {
964         uint32_t num_entries = 0;
965         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
966
967         DEBUG(5,("init_srv_conn_info_1\n"));
968
969         if (ctr1 == NULL) {
970                 if (resume_handle_p) {
971                         *resume_handle_p = 0;
972                 }
973                 return WERR_OK;
974         }
975
976         *total_entries = 1;
977
978         ZERO_STRUCTP(ctr1);
979
980         for (; resume_handle < *total_entries; resume_handle++) {
981
982                 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
983                                                    ctr1->array,
984                                                    struct srvsvc_NetConnInfo1,
985                                                    num_entries+1);
986                 if (!ctr1->array) {
987                         return WERR_NOMEM;
988                 }
989
990                 ctr1->array[num_entries].conn_id        = *total_entries;
991                 ctr1->array[num_entries].conn_type      = 0x3;
992                 ctr1->array[num_entries].num_open       = 1;
993                 ctr1->array[num_entries].num_users      = 1;
994                 ctr1->array[num_entries].conn_time      = 3;
995                 ctr1->array[num_entries].user           = "dummy_user";
996                 ctr1->array[num_entries].share          = "IPC$";
997
998                 /* move on to creating next connection */
999                 num_entries++;
1000         }
1001
1002         ctr1->count = num_entries;
1003         *total_entries = num_entries;
1004
1005         if (resume_handle_p) {
1006                 if (*resume_handle_p >= *total_entries) {
1007                         *resume_handle_p = 0;
1008                 } else {
1009                         *resume_handle_p = resume_handle;
1010                 }
1011         }
1012
1013         return WERR_OK;
1014 }
1015
1016 /*******************************************************************
1017  _srvsvc_NetFileEnum
1018 *******************************************************************/
1019
1020 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
1021                            struct srvsvc_NetFileEnum *r)
1022 {
1023         TALLOC_CTX *ctx = NULL;
1024         struct srvsvc_NetFileCtr3 *ctr3;
1025         uint32_t resume_hnd = 0;
1026         WERROR werr;
1027
1028         switch (r->in.info_ctr->level) {
1029         case 3:
1030                 break;
1031         default:
1032                 return WERR_UNKNOWN_LEVEL;
1033         }
1034
1035         ctx = talloc_tos();
1036         ctr3 = r->in.info_ctr->ctr.ctr3;
1037         if (!ctr3) {
1038                 werr = WERR_INVALID_PARAM;
1039                 goto done;
1040         }
1041
1042         /* TODO -- Windows enumerates
1043            (b) active pipes
1044            (c) open directories and files */
1045
1046         werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1047         if (!W_ERROR_IS_OK(werr)) {
1048                 goto done;
1049         }
1050
1051         werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1052         if (!W_ERROR_IS_OK(werr)) {
1053                 goto done;
1054         }
1055
1056         *r->out.totalentries = ctr3->count;
1057         r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1058         r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1059
1060         werr = WERR_OK;
1061
1062  done:
1063         return werr;
1064 }
1065
1066 /*******************************************************************
1067  _srvsvc_NetSrvGetInfo
1068 ********************************************************************/
1069
1070 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1071                              struct srvsvc_NetSrvGetInfo *r)
1072 {
1073         WERROR status = WERR_OK;
1074
1075         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1076
1077         if (!pipe_access_check(p)) {
1078                 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1079                 return WERR_ACCESS_DENIED;
1080         }
1081
1082         switch (r->in.level) {
1083
1084                 /* Technically level 102 should only be available to
1085                    Administrators but there isn't anything super-secret
1086                    here, as most of it is made up. */
1087
1088         case 102: {
1089                 struct srvsvc_NetSrvInfo102 *info102;
1090
1091                 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1092                 if (!info102) {
1093                         return WERR_NOMEM;
1094                 }
1095
1096                 info102->platform_id    = PLATFORM_ID_NT;
1097                 info102->server_name    = global_myname();
1098                 info102->version_major  = lp_major_announce_version();
1099                 info102->version_minor  = lp_minor_announce_version();
1100                 info102->server_type    = lp_default_server_announce();
1101                 info102->comment        = string_truncate(lp_serverstring(),
1102                                                 MAX_SERVER_STRING_LENGTH);
1103                 info102->users          = 0xffffffff;
1104                 info102->disc           = 0xf;
1105                 info102->hidden         = 0;
1106                 info102->announce       = 240;
1107                 info102->anndelta       = 3000;
1108                 info102->licenses       = 100000;
1109                 info102->userpath       = "C:\\";
1110
1111                 r->out.info->info102 = info102;
1112                 break;
1113         }
1114         case 101: {
1115                 struct srvsvc_NetSrvInfo101 *info101;
1116
1117                 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1118                 if (!info101) {
1119                         return WERR_NOMEM;
1120                 }
1121
1122                 info101->platform_id    = PLATFORM_ID_NT;
1123                 info101->server_name    = global_myname();
1124                 info101->version_major  = lp_major_announce_version();
1125                 info101->version_minor  = lp_minor_announce_version();
1126                 info101->server_type    = lp_default_server_announce();
1127                 info101->comment        = string_truncate(lp_serverstring(),
1128                                                 MAX_SERVER_STRING_LENGTH);
1129
1130                 r->out.info->info101 = info101;
1131                 break;
1132         }
1133         case 100: {
1134                 struct srvsvc_NetSrvInfo100 *info100;
1135
1136                 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1137                 if (!info100) {
1138                         return WERR_NOMEM;
1139                 }
1140
1141                 info100->platform_id    = PLATFORM_ID_NT;
1142                 info100->server_name    = global_myname();
1143
1144                 r->out.info->info100 = info100;
1145
1146                 break;
1147         }
1148         default:
1149                 status = WERR_UNKNOWN_LEVEL;
1150                 break;
1151         }
1152
1153         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1154
1155         return status;
1156 }
1157
1158 /*******************************************************************
1159  _srvsvc_NetSrvSetInfo
1160 ********************************************************************/
1161
1162 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1163                              struct srvsvc_NetSrvSetInfo *r)
1164 {
1165         WERROR status = WERR_OK;
1166
1167         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1168
1169         /* Set up the net server set info structure. */
1170
1171         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1172
1173         return status;
1174 }
1175
1176 /*******************************************************************
1177  _srvsvc_NetConnEnum
1178 ********************************************************************/
1179
1180 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1181                            struct srvsvc_NetConnEnum *r)
1182 {
1183         WERROR werr;
1184
1185         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1186
1187         switch (r->in.info_ctr->level) {
1188                 case 0:
1189                         werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1190                                                     r->in.resume_handle,
1191                                                     r->out.totalentries);
1192                         break;
1193                 case 1:
1194                         werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1195                                                     r->in.resume_handle,
1196                                                     r->out.totalentries);
1197                         break;
1198                 default:
1199                         return WERR_UNKNOWN_LEVEL;
1200         }
1201
1202         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1203
1204         return werr;
1205 }
1206
1207 /*******************************************************************
1208  _srvsvc_NetSessEnum
1209 ********************************************************************/
1210
1211 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1212                            struct srvsvc_NetSessEnum *r)
1213 {
1214         WERROR werr;
1215
1216         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1217
1218         switch (r->in.info_ctr->level) {
1219                 case 0:
1220                         werr = init_srv_sess_info_0(p,
1221                                                     r->in.info_ctr->ctr.ctr0,
1222                                                     r->in.resume_handle,
1223                                                     r->out.totalentries);
1224                         break;
1225                 case 1:
1226                         werr = init_srv_sess_info_1(p,
1227                                                     r->in.info_ctr->ctr.ctr1,
1228                                                     r->in.resume_handle,
1229                                                     r->out.totalentries);
1230                         break;
1231                 default:
1232                         return WERR_UNKNOWN_LEVEL;
1233         }
1234
1235         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1236
1237         return werr;
1238 }
1239
1240 /*******************************************************************
1241  _srvsvc_NetSessDel
1242 ********************************************************************/
1243
1244 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1245                           struct srvsvc_NetSessDel *r)
1246 {
1247         struct sessionid *session_list;
1248         int num_sessions, snum;
1249         const char *username;
1250         const char *machine;
1251         bool not_root = False;
1252         WERROR werr;
1253
1254         username = r->in.user;
1255         machine = r->in.client;
1256
1257         /* strip leading backslashes if any */
1258         if (machine && machine[0] == '\\' && machine[1] == '\\') {
1259                 machine += 2;
1260         }
1261
1262         num_sessions = list_sessions(p->mem_ctx, &session_list);
1263
1264         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1265
1266         werr = WERR_ACCESS_DENIED;
1267
1268         /* fail out now if you are not root or not a domain admin */
1269
1270         if ((p->server_info->utok.uid != sec_initial_uid()) &&
1271                 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1272                                               DOMAIN_GROUP_RID_ADMINS))) {
1273
1274                 goto done;
1275         }
1276
1277         for (snum = 0; snum < num_sessions; snum++) {
1278
1279                 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1280                     strequal(session_list[snum].remote_machine, machine)) {
1281
1282                         NTSTATUS ntstat;
1283
1284                         if (p->server_info->utok.uid != sec_initial_uid()) {
1285                                 not_root = True;
1286                                 become_root();
1287                         }
1288
1289                         ntstat = messaging_send(smbd_messaging_context(),
1290                                                 session_list[snum].pid,
1291                                                 MSG_SHUTDOWN, &data_blob_null);
1292
1293                         if (NT_STATUS_IS_OK(ntstat))
1294                                 werr = WERR_OK;
1295
1296                         if (not_root)
1297                                 unbecome_root();
1298                 }
1299         }
1300
1301         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1302
1303 done:
1304
1305         return werr;
1306 }
1307
1308 /*******************************************************************
1309  _srvsvc_NetShareEnumAll
1310 ********************************************************************/
1311
1312 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1313                                struct srvsvc_NetShareEnumAll *r)
1314 {
1315         WERROR werr;
1316
1317         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1318
1319         if (!pipe_access_check(p)) {
1320                 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1321                 return WERR_ACCESS_DENIED;
1322         }
1323
1324         /* Create the list of shares for the response. */
1325         werr = init_srv_share_info_ctr(p,
1326                                        r->in.info_ctr,
1327                                        r->in.resume_handle,
1328                                        r->out.totalentries,
1329                                        true);
1330
1331         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1332
1333         return werr;
1334 }
1335
1336 /*******************************************************************
1337  _srvsvc_NetShareEnum
1338 ********************************************************************/
1339
1340 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1341                             struct srvsvc_NetShareEnum *r)
1342 {
1343         WERROR werr;
1344
1345         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1346
1347         if (!pipe_access_check(p)) {
1348                 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1349                 return WERR_ACCESS_DENIED;
1350         }
1351
1352         /* Create the list of shares for the response. */
1353         werr = init_srv_share_info_ctr(p,
1354                                        r->in.info_ctr,
1355                                        r->in.resume_handle,
1356                                        r->out.totalentries,
1357                                        false);
1358
1359         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1360
1361         return werr;
1362 }
1363
1364 /*******************************************************************
1365  _srvsvc_NetShareGetInfo
1366 ********************************************************************/
1367
1368 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1369                                struct srvsvc_NetShareGetInfo *r)
1370 {
1371         WERROR status = WERR_OK;
1372         fstring share_name;
1373         int snum;
1374         union srvsvc_NetShareInfo *info = r->out.info;
1375
1376         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1377
1378         fstrcpy(share_name, r->in.share_name);
1379
1380         snum = find_service(share_name);
1381         if (snum < 0) {
1382                 return WERR_INVALID_NAME;
1383         }
1384
1385         switch (r->in.level) {
1386                 case 0:
1387                         info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1388                         W_ERROR_HAVE_NO_MEMORY(info->info0);
1389                         init_srv_share_info_0(p, info->info0, snum);
1390                         break;
1391                 case 1:
1392                         info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1393                         W_ERROR_HAVE_NO_MEMORY(info->info1);
1394                         init_srv_share_info_1(p, info->info1, snum);
1395                         break;
1396                 case 2:
1397                         info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1398                         W_ERROR_HAVE_NO_MEMORY(info->info2);
1399                         init_srv_share_info_2(p, info->info2, snum);
1400                         break;
1401                 case 501:
1402                         info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1403                         W_ERROR_HAVE_NO_MEMORY(info->info501);
1404                         init_srv_share_info_501(p, info->info501, snum);
1405                         break;
1406                 case 502:
1407                         info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1408                         W_ERROR_HAVE_NO_MEMORY(info->info502);
1409                         init_srv_share_info_502(p, info->info502, snum);
1410                         break;
1411                 case 1004:
1412                         info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1413                         W_ERROR_HAVE_NO_MEMORY(info->info1004);
1414                         init_srv_share_info_1004(p, info->info1004, snum);
1415                         break;
1416                 case 1005:
1417                         info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1418                         W_ERROR_HAVE_NO_MEMORY(info->info1005);
1419                         init_srv_share_info_1005(p, info->info1005, snum);
1420                         break;
1421                 case 1006:
1422                         info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1423                         W_ERROR_HAVE_NO_MEMORY(info->info1006);
1424                         init_srv_share_info_1006(p, info->info1006, snum);
1425                         break;
1426                 case 1007:
1427                         info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1428                         W_ERROR_HAVE_NO_MEMORY(info->info1007);
1429                         init_srv_share_info_1007(p, info->info1007, snum);
1430                         break;
1431                 case 1501:
1432                         init_srv_share_info_1501(p, info->info1501, snum);
1433                         break;
1434                 default:
1435                         DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1436                                 r->in.level));
1437                         status = WERR_UNKNOWN_LEVEL;
1438                         break;
1439         }
1440
1441         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1442
1443         return status;
1444 }
1445
1446 /*******************************************************************
1447  Check a given DOS pathname is valid for a share.
1448 ********************************************************************/
1449
1450 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1451 {
1452         char *ptr = NULL;
1453
1454         if (!dos_pathname) {
1455                 return NULL;
1456         }
1457
1458         ptr = talloc_strdup(ctx, dos_pathname);
1459         if (!ptr) {
1460                 return NULL;
1461         }
1462         /* Convert any '\' paths to '/' */
1463         unix_format(ptr);
1464         ptr = unix_clean_name(ctx, ptr);
1465         if (!ptr) {
1466                 return NULL;
1467         }
1468
1469         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1470         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1471                 ptr += 2;
1472
1473         /* Only absolute paths allowed. */
1474         if (*ptr != '/')
1475                 return NULL;
1476
1477         return ptr;
1478 }
1479
1480 /*******************************************************************
1481  _srvsvc_NetShareSetInfo. Modify share details.
1482 ********************************************************************/
1483
1484 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1485                                struct srvsvc_NetShareSetInfo *r)
1486 {
1487         char *command = NULL;
1488         char *share_name = NULL;
1489         char *comment = NULL;
1490         const char *pathname = NULL;
1491         int type;
1492         int snum;
1493         int ret;
1494         char *path = NULL;
1495         SEC_DESC *psd = NULL;
1496         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1497         bool is_disk_op = False;
1498         int max_connections = 0;
1499         TALLOC_CTX *ctx = p->mem_ctx;
1500         union srvsvc_NetShareInfo *info = r->in.info;
1501
1502         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1503
1504         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1505         if (!share_name) {
1506                 return WERR_NOMEM;
1507         }
1508
1509         if (r->out.parm_error) {
1510                 *r->out.parm_error = 0;
1511         }
1512
1513         if ( strequal(share_name,"IPC$")
1514                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1515                 || strequal(share_name,"global") )
1516         {
1517                 return WERR_ACCESS_DENIED;
1518         }
1519
1520         snum = find_service(share_name);
1521
1522         /* Does this share exist ? */
1523         if (snum < 0)
1524                 return WERR_NET_NAME_NOT_FOUND;
1525
1526         /* No change to printer shares. */
1527         if (lp_print_ok(snum))
1528                 return WERR_ACCESS_DENIED;
1529
1530         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1531
1532         /* fail out now if you are not root and not a disk op */
1533
1534         if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1535                 return WERR_ACCESS_DENIED;
1536
1537         switch (r->in.level) {
1538         case 1:
1539                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1540                 comment = talloc_strdup(ctx, info->info1->comment);
1541                 type = info->info1->type;
1542                 psd = NULL;
1543                 break;
1544         case 2:
1545                 comment = talloc_strdup(ctx, info->info2->comment);
1546                 pathname = info->info2->path;
1547                 type = info->info2->type;
1548                 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1549                         0 : info->info2->max_users;
1550                 psd = NULL;
1551                 break;
1552 #if 0
1553                 /* not supported on set but here for completeness */
1554         case 501:
1555                 comment = talloc_strdup(ctx, info->info501->comment);
1556                 type = info->info501->type;
1557                 psd = NULL;
1558                 break;
1559 #endif
1560         case 502:
1561                 comment = talloc_strdup(ctx, info->info502->comment);
1562                 pathname = info->info502->path;
1563                 type = info->info502->type;
1564                 psd = info->info502->sd_buf.sd;
1565                 map_generic_share_sd_bits(psd);
1566                 break;
1567         case 1004:
1568                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1569                 comment = talloc_strdup(ctx, info->info1004->comment);
1570                 type = STYPE_DISKTREE;
1571                 break;
1572         case 1005:
1573                 /* XP re-sets the csc policy even if it wasn't changed by the
1574                    user, so we must compare it to see if it's what is set in
1575                    smb.conf, so that we can contine other ops like setting
1576                    ACLs on a share */
1577                 if (((info->info1005->dfs_flags &
1578                       SHARE_1005_CSC_POLICY_MASK) >>
1579                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1580                         return WERR_OK;
1581                 else {
1582                         DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1583                         return WERR_ACCESS_DENIED;
1584                 }
1585         case 1006:
1586         case 1007:
1587                 return WERR_ACCESS_DENIED;
1588         case 1501:
1589                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1590                 comment = talloc_strdup(ctx, lp_comment(snum));
1591                 psd = info->info1501->sd;
1592                 map_generic_share_sd_bits(psd);
1593                 type = STYPE_DISKTREE;
1594                 break;
1595         default:
1596                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1597                         r->in.level));
1598                 return WERR_UNKNOWN_LEVEL;
1599         }
1600
1601         /* We can only modify disk shares. */
1602         if (type != STYPE_DISKTREE)
1603                 return WERR_ACCESS_DENIED;
1604
1605         if (comment == NULL) {
1606                 return WERR_NOMEM;
1607         }
1608
1609         /* Check if the pathname is valid. */
1610         if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1611                 return WERR_OBJECT_PATH_INVALID;
1612
1613         /* Ensure share name, pathname and comment don't contain '"' characters. */
1614         string_replace(share_name, '"', ' ');
1615         string_replace(path, '"', ' ');
1616         string_replace(comment, '"', ' ');
1617
1618         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1619                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1620
1621         /* Only call modify function if something changed. */
1622
1623         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1624                         || (lp_max_connections(snum) != max_connections)) {
1625                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1626                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1627                         return WERR_ACCESS_DENIED;
1628                 }
1629
1630                 command = talloc_asprintf(p->mem_ctx,
1631                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1632                                 lp_change_share_cmd(),
1633                                 get_dyn_CONFIGFILE(),
1634                                 share_name,
1635                                 path,
1636                                 comment ? comment : "",
1637                                 max_connections);
1638                 if (!command) {
1639                         return WERR_NOMEM;
1640                 }
1641
1642                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1643
1644                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1645
1646                 if (is_disk_op)
1647                         become_root();
1648
1649                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1650                         /* Tell everyone we updated smb.conf. */
1651                         message_send_all(smbd_messaging_context(),
1652                                          MSG_SMB_CONF_UPDATED, NULL, 0,
1653                                          NULL);
1654                 }
1655
1656                 if ( is_disk_op )
1657                         unbecome_root();
1658
1659                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1660
1661                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1662                         command, ret ));
1663
1664                 TALLOC_FREE(command);
1665
1666                 if ( ret != 0 )
1667                         return WERR_ACCESS_DENIED;
1668         } else {
1669                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1670                         share_name ));
1671         }
1672
1673         /* Replace SD if changed. */
1674         if (psd) {
1675                 SEC_DESC *old_sd;
1676                 size_t sd_size;
1677
1678                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1679
1680                 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1681                         if (!set_share_security(share_name, psd))
1682                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1683                                         share_name ));
1684                 }
1685         }
1686
1687         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1688
1689         return WERR_OK;
1690 }
1691
1692 /*******************************************************************
1693  _srvsvc_NetShareAdd.
1694  Call 'add_share_command "sharename" "pathname"
1695  "comment" "max connections = "
1696 ********************************************************************/
1697
1698 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1699                            struct srvsvc_NetShareAdd *r)
1700 {
1701         char *command = NULL;
1702         char *share_name = NULL;
1703         char *comment = NULL;
1704         char *pathname = NULL;
1705         int type;
1706         int snum;
1707         int ret;
1708         char *path;
1709         SEC_DESC *psd = NULL;
1710         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1711         bool is_disk_op;
1712         int max_connections = 0;
1713         TALLOC_CTX *ctx = p->mem_ctx;
1714
1715         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1716
1717         if (r->out.parm_error) {
1718                 *r->out.parm_error = 0;
1719         }
1720
1721         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1722
1723         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1724                 return WERR_ACCESS_DENIED;
1725
1726         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1727                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1728                 return WERR_ACCESS_DENIED;
1729         }
1730
1731         switch (r->in.level) {
1732         case 0:
1733                 /* No path. Not enough info in a level 0 to do anything. */
1734                 return WERR_ACCESS_DENIED;
1735         case 1:
1736                 /* Not enough info in a level 1 to do anything. */
1737                 return WERR_ACCESS_DENIED;
1738         case 2:
1739                 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1740                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1741                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1742                 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1743                         0 : r->in.info->info2->max_users;
1744                 type = r->in.info->info2->type;
1745                 break;
1746         case 501:
1747                 /* No path. Not enough info in a level 501 to do anything. */
1748                 return WERR_ACCESS_DENIED;
1749         case 502:
1750                 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1751                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1752                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1753                 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1754                         0 : r->in.info->info502->max_users;
1755                 type = r->in.info->info502->type;
1756                 psd = r->in.info->info502->sd_buf.sd;
1757                 map_generic_share_sd_bits(psd);
1758                 break;
1759
1760                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1761
1762         case 1004:
1763         case 1005:
1764         case 1006:
1765         case 1007:
1766                 return WERR_ACCESS_DENIED;
1767         case 1501:
1768                 /* DFS only level. */
1769                 return WERR_ACCESS_DENIED;
1770         default:
1771                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1772                         r->in.level));
1773                 return WERR_UNKNOWN_LEVEL;
1774         }
1775
1776         /* check for invalid share names */
1777
1778         if (!share_name || !validate_net_name(share_name,
1779                                 INVALID_SHARENAME_CHARS,
1780                                 strlen(share_name))) {
1781                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1782                                         share_name ? share_name : ""));
1783                 return WERR_INVALID_NAME;
1784         }
1785
1786         if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1787                         || (lp_enable_asu_support() &&
1788                                         strequal(share_name,"ADMIN$"))) {
1789                 return WERR_ACCESS_DENIED;
1790         }
1791
1792         snum = find_service(share_name);
1793
1794         /* Share already exists. */
1795         if (snum >= 0) {
1796                 return WERR_FILE_EXISTS;
1797         }
1798
1799         /* We can only add disk shares. */
1800         if (type != STYPE_DISKTREE) {
1801                 return WERR_ACCESS_DENIED;
1802         }
1803
1804         /* Check if the pathname is valid. */
1805         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1806                 return WERR_OBJECT_PATH_INVALID;
1807         }
1808
1809         /* Ensure share name, pathname and comment don't contain '"' characters. */
1810         string_replace(share_name, '"', ' ');
1811         string_replace(path, '"', ' ');
1812         if (comment) {
1813                 string_replace(comment, '"', ' ');
1814         }
1815
1816         command = talloc_asprintf(ctx,
1817                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1818                         lp_add_share_cmd(),
1819                         get_dyn_CONFIGFILE(),
1820                         share_name,
1821                         path,
1822                         comment ? comment : "",
1823                         max_connections);
1824         if (!command) {
1825                 return WERR_NOMEM;
1826         }
1827
1828         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1829
1830         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1831
1832         if ( is_disk_op )
1833                 become_root();
1834
1835         /* FIXME: use libnetconf here - gd */
1836
1837         if ( (ret = smbrun(command, NULL)) == 0 ) {
1838                 /* Tell everyone we updated smb.conf. */
1839                 message_send_all(smbd_messaging_context(),
1840                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1841         }
1842
1843         if ( is_disk_op )
1844                 unbecome_root();
1845
1846         /********* END SeDiskOperatorPrivilege BLOCK *********/
1847
1848         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1849                 command, ret ));
1850
1851         TALLOC_FREE(command);
1852
1853         if ( ret != 0 )
1854                 return WERR_ACCESS_DENIED;
1855
1856         if (psd) {
1857                 if (!set_share_security(share_name, psd)) {
1858                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1859                                 share_name ));
1860                 }
1861         }
1862
1863         /*
1864          * We don't call reload_services() here, the message will
1865          * cause this to be done before the next packet is read
1866          * from the client. JRA.
1867          */
1868
1869         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1870
1871         return WERR_OK;
1872 }
1873
1874 /*******************************************************************
1875  _srvsvc_NetShareDel
1876  Call "delete share command" with the share name as
1877  a parameter.
1878 ********************************************************************/
1879
1880 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1881                            struct srvsvc_NetShareDel *r)
1882 {
1883         char *command = NULL;
1884         char *share_name = NULL;
1885         int ret;
1886         int snum;
1887         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1888         bool is_disk_op;
1889         struct share_params *params;
1890         TALLOC_CTX *ctx = p->mem_ctx;
1891
1892         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1893
1894         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1895         if (!share_name) {
1896                 return WERR_NET_NAME_NOT_FOUND;
1897         }
1898         if ( strequal(share_name,"IPC$")
1899                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1900                 || strequal(share_name,"global") )
1901         {
1902                 return WERR_ACCESS_DENIED;
1903         }
1904
1905         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1906                 return WERR_NO_SUCH_SHARE;
1907         }
1908
1909         snum = find_service(share_name);
1910
1911         /* No change to printer shares. */
1912         if (lp_print_ok(snum))
1913                 return WERR_ACCESS_DENIED;
1914
1915         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1916
1917         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1918                 return WERR_ACCESS_DENIED;
1919
1920         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1921                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1922                 return WERR_ACCESS_DENIED;
1923         }
1924
1925         command = talloc_asprintf(ctx,
1926                         "%s \"%s\" \"%s\"",
1927                         lp_delete_share_cmd(),
1928                         get_dyn_CONFIGFILE(),
1929                         lp_servicename(snum));
1930         if (!command) {
1931                 return WERR_NOMEM;
1932         }
1933
1934         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1935
1936         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1937
1938         if ( is_disk_op )
1939                 become_root();
1940
1941         if ( (ret = smbrun(command, NULL)) == 0 ) {
1942                 /* Tell everyone we updated smb.conf. */
1943                 message_send_all(smbd_messaging_context(),
1944                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1945         }
1946
1947         if ( is_disk_op )
1948                 unbecome_root();
1949
1950         /********* END SeDiskOperatorPrivilege BLOCK *********/
1951
1952         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1953
1954         if ( ret != 0 )
1955                 return WERR_ACCESS_DENIED;
1956
1957         /* Delete the SD in the database. */
1958         delete_share_security(lp_servicename(params->service));
1959
1960         lp_killservice(params->service);
1961
1962         return WERR_OK;
1963 }
1964
1965 /*******************************************************************
1966  _srvsvc_NetShareDelSticky
1967 ********************************************************************/
1968
1969 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1970                                  struct srvsvc_NetShareDelSticky *r)
1971 {
1972         struct srvsvc_NetShareDel q;
1973
1974         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1975
1976         q.in.server_unc         = r->in.server_unc;
1977         q.in.share_name         = r->in.share_name;
1978         q.in.reserved           = r->in.reserved;
1979
1980         return _srvsvc_NetShareDel(p, &q);
1981 }
1982
1983 /*******************************************************************
1984  _srvsvc_NetRemoteTOD
1985 ********************************************************************/
1986
1987 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1988                             struct srvsvc_NetRemoteTOD *r)
1989 {
1990         struct srvsvc_NetRemoteTODInfo *tod;
1991         struct tm *t;
1992         time_t unixdate = time(NULL);
1993
1994         /* We do this call first as if we do it *after* the gmtime call
1995            it overwrites the pointed-to values. JRA */
1996
1997         uint32 zone = get_time_zone(unixdate)/60;
1998
1999         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2000
2001         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2002                 return WERR_NOMEM;
2003
2004         *r->out.info = tod;
2005
2006         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2007
2008         t = gmtime(&unixdate);
2009
2010         /* set up the */
2011         tod->elapsed    = unixdate;
2012         tod->msecs      = 0;
2013         tod->hours      = t->tm_hour;
2014         tod->mins       = t->tm_min;
2015         tod->secs       = t->tm_sec;
2016         tod->hunds      = 0;
2017         tod->timezone   = zone;
2018         tod->tinterval  = 10000;
2019         tod->day        = t->tm_mday;
2020         tod->month      = t->tm_mon + 1;
2021         tod->year       = 1900+t->tm_year;
2022         tod->weekday    = t->tm_wday;
2023
2024         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2025
2026         return WERR_OK;
2027 }
2028
2029 /***********************************************************************************
2030  _srvsvc_NetGetFileSecurity
2031  Win9x NT tools get security descriptor.
2032 ***********************************************************************************/
2033
2034 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2035                                   struct srvsvc_NetGetFileSecurity *r)
2036 {
2037         struct smb_filename *smb_fname = NULL;
2038         SEC_DESC *psd = NULL;
2039         size_t sd_size;
2040         fstring servicename;
2041         SMB_STRUCT_STAT st;
2042         NTSTATUS nt_status;
2043         WERROR werr;
2044         connection_struct *conn = NULL;
2045         struct sec_desc_buf *sd_buf = NULL;
2046         files_struct *fsp = NULL;
2047         int snum;
2048         char *oldcwd = NULL;
2049
2050         ZERO_STRUCT(st);
2051
2052         fstrcpy(servicename, r->in.share);
2053
2054         snum = find_service(servicename);
2055         if (snum == -1) {
2056                 DEBUG(10, ("Could not find service %s\n", servicename));
2057                 werr = WERR_NET_NAME_NOT_FOUND;
2058                 goto error_exit;
2059         }
2060
2061         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2062                                        lp_pathname(snum), p->server_info,
2063                                        &oldcwd);
2064         if (!NT_STATUS_IS_OK(nt_status)) {
2065                 DEBUG(10, ("create_conn_struct failed: %s\n",
2066                            nt_errstr(nt_status)));
2067                 werr = ntstatus_to_werror(nt_status);
2068                 goto error_exit;
2069         }
2070
2071         nt_status = filename_convert(talloc_tos(),
2072                                         conn,
2073                                         false,
2074                                         r->in.file,
2075                                         &smb_fname,
2076                                         NULL);
2077         if (!NT_STATUS_IS_OK(nt_status)) {
2078                 werr = ntstatus_to_werror(nt_status);
2079                 goto error_exit;
2080         }
2081
2082         nt_status = SMB_VFS_CREATE_FILE(
2083                 conn,                                   /* conn */
2084                 NULL,                                   /* req */
2085                 0,                                      /* root_dir_fid */
2086                 smb_fname,                              /* fname */
2087                 FILE_READ_ATTRIBUTES,                   /* access_mask */
2088                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2089                 FILE_OPEN,                              /* create_disposition*/
2090                 0,                                      /* create_options */
2091                 0,                                      /* file_attributes */
2092                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2093                 0,                                      /* allocation_size */
2094                 NULL,                                   /* sd */
2095                 NULL,                                   /* ea_list */
2096                 &fsp,                                   /* result */
2097                 NULL);                                  /* pinfo */
2098
2099         if (!NT_STATUS_IS_OK(nt_status)) {
2100                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2101                          smb_fname_str_dbg(smb_fname)));
2102                 werr = ntstatus_to_werror(nt_status);
2103                 goto error_exit;
2104         }
2105
2106         nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2107                                        (OWNER_SECURITY_INFORMATION
2108                                         |GROUP_SECURITY_INFORMATION
2109                                         |DACL_SECURITY_INFORMATION), &psd);
2110
2111         if (!NT_STATUS_IS_OK(nt_status)) {
2112                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2113                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
2114                 werr = ntstatus_to_werror(nt_status);
2115                 goto error_exit;
2116         }
2117
2118         sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2119
2120         sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2121         if (!sd_buf) {
2122                 werr = WERR_NOMEM;
2123                 goto error_exit;
2124         }
2125
2126         sd_buf->sd_size = sd_size;
2127         sd_buf->sd = psd;
2128
2129         *r->out.sd_buf = sd_buf;
2130
2131         psd->dacl->revision = NT4_ACL_REVISION;
2132
2133         close_file(NULL, fsp, NORMAL_CLOSE);
2134         vfs_ChDir(conn, oldcwd);
2135         conn_free_internal(conn);
2136         werr = WERR_OK;
2137         goto done;
2138
2139 error_exit:
2140
2141         if (fsp) {
2142                 close_file(NULL, fsp, NORMAL_CLOSE);
2143         }
2144
2145         if (oldcwd) {
2146                 vfs_ChDir(conn, oldcwd);
2147         }
2148
2149         if (conn) {
2150                 conn_free_internal(conn);
2151         }
2152
2153  done:
2154         TALLOC_FREE(smb_fname);
2155
2156         return werr;
2157 }
2158
2159 /***********************************************************************************
2160  _srvsvc_NetSetFileSecurity
2161  Win9x NT tools set security descriptor.
2162 ***********************************************************************************/
2163
2164 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2165                                   struct srvsvc_NetSetFileSecurity *r)
2166 {
2167         struct smb_filename *smb_fname = NULL;
2168         fstring servicename;
2169         files_struct *fsp = NULL;
2170         SMB_STRUCT_STAT st;
2171         NTSTATUS nt_status;
2172         WERROR werr;
2173         connection_struct *conn = NULL;
2174         int snum;
2175         char *oldcwd = NULL;
2176         struct security_descriptor *psd = NULL;
2177         uint32_t security_info_sent = 0;
2178
2179         ZERO_STRUCT(st);
2180
2181         fstrcpy(servicename, r->in.share);
2182
2183         snum = find_service(servicename);
2184         if (snum == -1) {
2185                 DEBUG(10, ("Could not find service %s\n", servicename));
2186                 werr = WERR_NET_NAME_NOT_FOUND;
2187                 goto error_exit;
2188         }
2189
2190         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2191                                        lp_pathname(snum), p->server_info,
2192                                        &oldcwd);
2193         if (!NT_STATUS_IS_OK(nt_status)) {
2194                 DEBUG(10, ("create_conn_struct failed: %s\n",
2195                            nt_errstr(nt_status)));
2196                 werr = ntstatus_to_werror(nt_status);
2197                 goto error_exit;
2198         }
2199
2200         nt_status = filename_convert(talloc_tos(),
2201                                         conn,
2202                                         false,
2203                                         r->in.file,
2204                                         &smb_fname,
2205                                         NULL);
2206         if (!NT_STATUS_IS_OK(nt_status)) {
2207                 werr = ntstatus_to_werror(nt_status);
2208                 goto error_exit;
2209         }
2210
2211         nt_status = SMB_VFS_CREATE_FILE(
2212                 conn,                                   /* conn */
2213                 NULL,                                   /* req */
2214                 0,                                      /* root_dir_fid */
2215                 smb_fname,                              /* fname */
2216                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
2217                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2218                 FILE_OPEN,                              /* create_disposition*/
2219                 0,                                      /* create_options */
2220                 0,                                      /* file_attributes */
2221                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2222                 0,                                      /* allocation_size */
2223                 NULL,                                   /* sd */
2224                 NULL,                                   /* ea_list */
2225                 &fsp,                                   /* result */
2226                 NULL);                                  /* pinfo */
2227
2228         if (!NT_STATUS_IS_OK(nt_status)) {
2229                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2230                          smb_fname_str_dbg(smb_fname)));
2231                 werr = ntstatus_to_werror(nt_status);
2232                 goto error_exit;
2233         }
2234
2235         psd = r->in.sd_buf->sd;
2236         security_info_sent = r->in.securityinformation;
2237
2238         if (psd->owner_sid==0) {
2239                 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2240         }
2241         if (psd->group_sid==0) {
2242                 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2243         }
2244         if (psd->sacl==0) {
2245                 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2246         }
2247         if (psd->dacl==0) {
2248                 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2249         }
2250
2251         /* Convert all the generic bits. */
2252         security_acl_map_generic(psd->dacl, &file_generic_mapping);
2253         security_acl_map_generic(psd->sacl, &file_generic_mapping);
2254
2255         nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2256                                         security_info_sent,
2257                                         psd);
2258
2259         if (!NT_STATUS_IS_OK(nt_status) ) {
2260                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2261                          "on file %s\n", r->in.share));
2262                 werr = WERR_ACCESS_DENIED;
2263                 goto error_exit;
2264         }
2265
2266         close_file(NULL, fsp, NORMAL_CLOSE);
2267         vfs_ChDir(conn, oldcwd);
2268         conn_free_internal(conn);
2269         werr = WERR_OK;
2270         goto done;
2271
2272 error_exit:
2273
2274         if (fsp) {
2275                 close_file(NULL, fsp, NORMAL_CLOSE);
2276         }
2277
2278         if (oldcwd) {
2279                 vfs_ChDir(conn, oldcwd);
2280         }
2281
2282         if (conn) {
2283                 conn_free_internal(conn);
2284         }
2285
2286  done:
2287         TALLOC_FREE(smb_fname);
2288
2289         return werr;
2290 }
2291
2292 /***********************************************************************************
2293  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2294  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2295  These disks would the disks listed by this function.
2296  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2297  "Nigel Williams" <nigel@veritas.com>.
2298 ***********************************************************************************/
2299
2300 static const char *server_disks[] = {"C:"};
2301
2302 static uint32 get_server_disk_count(void)
2303 {
2304         return sizeof(server_disks)/sizeof(server_disks[0]);
2305 }
2306
2307 static uint32 init_server_disk_enum(uint32 *resume)
2308 {
2309         uint32 server_disk_count = get_server_disk_count();
2310
2311         /*resume can be an offset into the list for now*/
2312
2313         if(*resume & 0x80000000)
2314                 *resume = 0;
2315
2316         if(*resume > server_disk_count)
2317                 *resume = server_disk_count;
2318
2319         return server_disk_count - *resume;
2320 }
2321
2322 static const char *next_server_disk_enum(uint32 *resume)
2323 {
2324         const char *disk;
2325
2326         if(init_server_disk_enum(resume) == 0)
2327                 return NULL;
2328
2329         disk = server_disks[*resume];
2330
2331         (*resume)++;
2332
2333         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2334
2335         return disk;
2336 }
2337
2338 /********************************************************************
2339  _srvsvc_NetDiskEnum
2340 ********************************************************************/
2341
2342 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2343                            struct srvsvc_NetDiskEnum *r)
2344 {
2345         uint32 i;
2346         const char *disk_name;
2347         TALLOC_CTX *ctx = p->mem_ctx;
2348         WERROR werr;
2349         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2350
2351         werr = WERR_OK;
2352
2353         *r->out.totalentries = init_server_disk_enum(&resume);
2354
2355         r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2356                                                MAX_SERVER_DISK_ENTRIES);
2357         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2358
2359         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2360
2361         r->out.info->count = 0;
2362
2363         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2364
2365                 r->out.info->count++;
2366
2367                 /*copy disk name into a unicode string*/
2368
2369                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2370                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2371         }
2372
2373         /* add a terminating null string.  Is this there if there is more data to come? */
2374
2375         r->out.info->count++;
2376
2377         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2378         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2379
2380         if (r->out.resume_handle) {
2381                 *r->out.resume_handle = resume;
2382         }
2383
2384         return werr;
2385 }
2386
2387 /********************************************************************
2388  _srvsvc_NetNameValidate
2389 ********************************************************************/
2390
2391 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2392                                struct srvsvc_NetNameValidate *r)
2393 {
2394         switch (r->in.name_type) {
2395         case 0x9:
2396                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2397                                        strlen_m(r->in.name)))
2398                 {
2399                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2400                                 r->in.name));
2401                         return WERR_INVALID_NAME;
2402                 }
2403                 break;
2404
2405         default:
2406                 return WERR_UNKNOWN_LEVEL;
2407         }
2408
2409         return WERR_OK;
2410 }
2411
2412 /*******************************************************************
2413 ********************************************************************/
2414
2415 static void enum_file_close_fn( const struct share_mode_entry *e,
2416                           const char *sharepath, const char *fname,
2417                           void *private_data )
2418 {
2419         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2420         struct srvsvc_NetFileClose *r =
2421                 (struct srvsvc_NetFileClose *)private_data;
2422         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2423
2424         if (fid != r->in.fid) {
2425                 return; /* Not this file. */
2426         }
2427
2428         if (!process_exists(e->pid) ) {
2429                 return;
2430         }
2431
2432         /* Ok - send the close message. */
2433         DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2434                 sharepath,
2435                 share_mode_str(talloc_tos(), 0, e) ));
2436
2437         share_mode_entry_to_message(msg, e);
2438
2439         r->out.result = ntstatus_to_werror(
2440                         messaging_send_buf(smbd_messaging_context(),
2441                                 e->pid, MSG_SMB_CLOSE_FILE,
2442                                 (uint8 *)msg,
2443                                 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2444 }
2445
2446 /********************************************************************
2447  Close a file given a 32-bit file id.
2448 ********************************************************************/
2449
2450 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2451 {
2452         SE_PRIV se_diskop = SE_DISK_OPERATOR;
2453         bool is_disk_op;
2454
2455         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2456
2457         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2458
2459         if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2460                 return WERR_ACCESS_DENIED;
2461         }
2462
2463         /* enum_file_close_fn sends the close message to
2464          * the relevent smbd process. */
2465
2466         r->out.result = WERR_BADFILE;
2467         share_mode_forall( enum_file_close_fn, (void *)r);
2468         return r->out.result;
2469 }
2470
2471 /********************************************************************
2472 ********************************************************************/
2473
2474 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2475 {
2476         p->rng_fault_state = True;
2477         return WERR_NOT_SUPPORTED;
2478 }
2479
2480 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2481 {
2482         p->rng_fault_state = True;
2483         return WERR_NOT_SUPPORTED;
2484 }
2485
2486 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2487 {
2488         p->rng_fault_state = True;
2489         return WERR_NOT_SUPPORTED;
2490 }
2491
2492 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2493 {
2494         p->rng_fault_state = True;
2495         return WERR_NOT_SUPPORTED;
2496 }
2497
2498 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2499 {
2500         p->rng_fault_state = True;
2501         return WERR_NOT_SUPPORTED;
2502 }
2503
2504 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2505 {
2506         p->rng_fault_state = True;
2507         return WERR_NOT_SUPPORTED;
2508 }
2509
2510 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2511 {
2512         p->rng_fault_state = True;
2513         return WERR_NOT_SUPPORTED;
2514 }
2515
2516 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2517 {
2518         p->rng_fault_state = True;
2519         return WERR_NOT_SUPPORTED;
2520 }
2521
2522 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2523 {
2524         p->rng_fault_state = True;
2525         return WERR_NOT_SUPPORTED;
2526 }
2527
2528 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2529 {
2530         p->rng_fault_state = True;
2531         return WERR_NOT_SUPPORTED;
2532 }
2533
2534 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2535 {
2536         p->rng_fault_state = True;
2537         return WERR_NOT_SUPPORTED;
2538 }
2539
2540 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2541 {
2542         p->rng_fault_state = True;
2543         return WERR_NOT_SUPPORTED;
2544 }
2545
2546 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2547 {
2548         p->rng_fault_state = True;
2549         return WERR_NOT_SUPPORTED;
2550 }
2551
2552 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2553 {
2554         p->rng_fault_state = True;
2555         return WERR_NOT_SUPPORTED;
2556 }
2557
2558 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2559 {
2560         p->rng_fault_state = True;
2561         return WERR_NOT_SUPPORTED;
2562 }
2563
2564 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2565 {
2566         p->rng_fault_state = True;
2567         return WERR_NOT_SUPPORTED;
2568 }
2569
2570 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2571 {
2572         p->rng_fault_state = True;
2573         return WERR_NOT_SUPPORTED;
2574 }
2575
2576 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2577 {
2578         p->rng_fault_state = True;
2579         return WERR_NOT_SUPPORTED;
2580 }
2581
2582 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2583 {
2584         p->rng_fault_state = True;
2585         return WERR_NOT_SUPPORTED;
2586 }
2587
2588 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2589 {
2590         p->rng_fault_state = True;
2591         return WERR_NOT_SUPPORTED;
2592 }
2593
2594 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2595 {
2596         p->rng_fault_state = True;
2597         return WERR_NOT_SUPPORTED;
2598 }
2599
2600 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2601 {
2602         p->rng_fault_state = True;
2603         return WERR_NOT_SUPPORTED;
2604 }
2605
2606 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2607 {
2608         p->rng_fault_state = True;
2609         return WERR_NOT_SUPPORTED;
2610 }
2611
2612 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2613 {
2614         p->rng_fault_state = True;
2615         return WERR_NOT_SUPPORTED;
2616 }
2617
2618 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2619 {
2620         p->rng_fault_state = True;
2621         return WERR_NOT_SUPPORTED;
2622 }
2623
2624 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2625 {
2626         p->rng_fault_state = True;
2627         return WERR_NOT_SUPPORTED;
2628 }
2629
2630 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2631 {
2632         p->rng_fault_state = True;
2633         return WERR_NOT_SUPPORTED;
2634 }
2635
2636 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2637 {
2638         p->rng_fault_state = True;
2639         return WERR_NOT_SUPPORTED;
2640 }
2641
2642 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2643 {
2644         p->rng_fault_state = True;
2645         return WERR_NOT_SUPPORTED;
2646 }
2647
2648 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2649 {
2650         p->rng_fault_state = True;
2651         return WERR_NOT_SUPPORTED;
2652 }
2653
2654 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2655 {
2656         p->rng_fault_state = True;
2657         return WERR_NOT_SUPPORTED;
2658 }
2659
2660 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2661 {
2662         p->rng_fault_state = True;
2663         return WERR_NOT_SUPPORTED;
2664 }
2665
2666 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2667 {
2668         p->rng_fault_state = True;
2669         return WERR_NOT_SUPPORTED;
2670 }
2671
2672 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2673 {
2674         p->rng_fault_state = True;
2675         return WERR_NOT_SUPPORTED;
2676 }
2677
2678 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2679 {
2680         p->rng_fault_state = True;
2681         return WERR_NOT_SUPPORTED;
2682 }
2683