Merge branch 'master' of /home/tridge/samba/git/combined
[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                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1518                         "modified by a remote user.\n",
1519                         share_name ));
1520                 return WERR_ACCESS_DENIED;
1521         }
1522
1523         snum = find_service(share_name);
1524
1525         /* Does this share exist ? */
1526         if (snum < 0)
1527                 return WERR_NET_NAME_NOT_FOUND;
1528
1529         /* No change to printer shares. */
1530         if (lp_print_ok(snum))
1531                 return WERR_ACCESS_DENIED;
1532
1533         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1534
1535         /* fail out now if you are not root and not a disk op */
1536
1537         if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1538                 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1539                         "SeDiskOperatorPrivilege privilege needed to modify "
1540                         "share %s\n",
1541                         (unsigned int)p->server_info->utok.uid,
1542                         share_name ));
1543                 return WERR_ACCESS_DENIED;
1544         }
1545
1546         switch (r->in.level) {
1547         case 1:
1548                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1549                 comment = talloc_strdup(ctx, info->info1->comment);
1550                 type = info->info1->type;
1551                 psd = NULL;
1552                 break;
1553         case 2:
1554                 comment = talloc_strdup(ctx, info->info2->comment);
1555                 pathname = info->info2->path;
1556                 type = info->info2->type;
1557                 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1558                         0 : info->info2->max_users;
1559                 psd = NULL;
1560                 break;
1561 #if 0
1562                 /* not supported on set but here for completeness */
1563         case 501:
1564                 comment = talloc_strdup(ctx, info->info501->comment);
1565                 type = info->info501->type;
1566                 psd = NULL;
1567                 break;
1568 #endif
1569         case 502:
1570                 comment = talloc_strdup(ctx, info->info502->comment);
1571                 pathname = info->info502->path;
1572                 type = info->info502->type;
1573                 psd = info->info502->sd_buf.sd;
1574                 map_generic_share_sd_bits(psd);
1575                 break;
1576         case 1004:
1577                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1578                 comment = talloc_strdup(ctx, info->info1004->comment);
1579                 type = STYPE_DISKTREE;
1580                 break;
1581         case 1005:
1582                 /* XP re-sets the csc policy even if it wasn't changed by the
1583                    user, so we must compare it to see if it's what is set in
1584                    smb.conf, so that we can contine other ops like setting
1585                    ACLs on a share */
1586                 if (((info->info1005->dfs_flags &
1587                       SHARE_1005_CSC_POLICY_MASK) >>
1588                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1589                         return WERR_OK;
1590                 else {
1591                         DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1592                         return WERR_ACCESS_DENIED;
1593                 }
1594         case 1006:
1595         case 1007:
1596                 return WERR_ACCESS_DENIED;
1597         case 1501:
1598                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1599                 comment = talloc_strdup(ctx, lp_comment(snum));
1600                 psd = info->info1501->sd;
1601                 map_generic_share_sd_bits(psd);
1602                 type = STYPE_DISKTREE;
1603                 break;
1604         default:
1605                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1606                         r->in.level));
1607                 return WERR_UNKNOWN_LEVEL;
1608         }
1609
1610         /* We can only modify disk shares. */
1611         if (type != STYPE_DISKTREE) {
1612                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1613                         "disk share\n",
1614                         share_name ));
1615                 return WERR_ACCESS_DENIED;
1616         }
1617
1618         if (comment == NULL) {
1619                 return WERR_NOMEM;
1620         }
1621
1622         /* Check if the pathname is valid. */
1623         if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1624                 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1625                         pathname ));
1626                 return WERR_OBJECT_PATH_INVALID;
1627         }
1628
1629         /* Ensure share name, pathname and comment don't contain '"' characters. */
1630         string_replace(share_name, '"', ' ');
1631         string_replace(path, '"', ' ');
1632         string_replace(comment, '"', ' ');
1633
1634         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1635                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1636
1637         /* Only call modify function if something changed. */
1638
1639         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1640                         || (lp_max_connections(snum) != max_connections)) {
1641                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1642                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1643                         return WERR_ACCESS_DENIED;
1644                 }
1645
1646                 command = talloc_asprintf(p->mem_ctx,
1647                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1648                                 lp_change_share_cmd(),
1649                                 get_dyn_CONFIGFILE(),
1650                                 share_name,
1651                                 path,
1652                                 comment ? comment : "",
1653                                 max_connections);
1654                 if (!command) {
1655                         return WERR_NOMEM;
1656                 }
1657
1658                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1659
1660                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1661
1662                 if (is_disk_op)
1663                         become_root();
1664
1665                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1666                         /* Tell everyone we updated smb.conf. */
1667                         message_send_all(smbd_messaging_context(),
1668                                          MSG_SMB_CONF_UPDATED, NULL, 0,
1669                                          NULL);
1670                 }
1671
1672                 if ( is_disk_op )
1673                         unbecome_root();
1674
1675                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1676
1677                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1678                         command, ret ));
1679
1680                 TALLOC_FREE(command);
1681
1682                 if ( ret != 0 )
1683                         return WERR_ACCESS_DENIED;
1684         } else {
1685                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1686                         share_name ));
1687         }
1688
1689         /* Replace SD if changed. */
1690         if (psd) {
1691                 SEC_DESC *old_sd;
1692                 size_t sd_size;
1693
1694                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1695
1696                 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1697                         if (!set_share_security(share_name, psd))
1698                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1699                                         share_name ));
1700                 }
1701         }
1702
1703         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1704
1705         return WERR_OK;
1706 }
1707
1708 /*******************************************************************
1709  _srvsvc_NetShareAdd.
1710  Call 'add_share_command "sharename" "pathname"
1711  "comment" "max connections = "
1712 ********************************************************************/
1713
1714 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1715                            struct srvsvc_NetShareAdd *r)
1716 {
1717         char *command = NULL;
1718         char *share_name = NULL;
1719         char *comment = NULL;
1720         char *pathname = NULL;
1721         int type;
1722         int snum;
1723         int ret;
1724         char *path;
1725         SEC_DESC *psd = NULL;
1726         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1727         bool is_disk_op;
1728         int max_connections = 0;
1729         TALLOC_CTX *ctx = p->mem_ctx;
1730
1731         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1732
1733         if (r->out.parm_error) {
1734                 *r->out.parm_error = 0;
1735         }
1736
1737         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1738
1739         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1740                 return WERR_ACCESS_DENIED;
1741
1742         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1743                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1744                 return WERR_ACCESS_DENIED;
1745         }
1746
1747         switch (r->in.level) {
1748         case 0:
1749                 /* No path. Not enough info in a level 0 to do anything. */
1750                 return WERR_ACCESS_DENIED;
1751         case 1:
1752                 /* Not enough info in a level 1 to do anything. */
1753                 return WERR_ACCESS_DENIED;
1754         case 2:
1755                 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1756                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1757                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1758                 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1759                         0 : r->in.info->info2->max_users;
1760                 type = r->in.info->info2->type;
1761                 break;
1762         case 501:
1763                 /* No path. Not enough info in a level 501 to do anything. */
1764                 return WERR_ACCESS_DENIED;
1765         case 502:
1766                 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1767                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1768                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1769                 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1770                         0 : r->in.info->info502->max_users;
1771                 type = r->in.info->info502->type;
1772                 psd = r->in.info->info502->sd_buf.sd;
1773                 map_generic_share_sd_bits(psd);
1774                 break;
1775
1776                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1777
1778         case 1004:
1779         case 1005:
1780         case 1006:
1781         case 1007:
1782                 return WERR_ACCESS_DENIED;
1783         case 1501:
1784                 /* DFS only level. */
1785                 return WERR_ACCESS_DENIED;
1786         default:
1787                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1788                         r->in.level));
1789                 return WERR_UNKNOWN_LEVEL;
1790         }
1791
1792         /* check for invalid share names */
1793
1794         if (!share_name || !validate_net_name(share_name,
1795                                 INVALID_SHARENAME_CHARS,
1796                                 strlen(share_name))) {
1797                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1798                                         share_name ? share_name : ""));
1799                 return WERR_INVALID_NAME;
1800         }
1801
1802         if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1803                         || (lp_enable_asu_support() &&
1804                                         strequal(share_name,"ADMIN$"))) {
1805                 return WERR_ACCESS_DENIED;
1806         }
1807
1808         snum = find_service(share_name);
1809
1810         /* Share already exists. */
1811         if (snum >= 0) {
1812                 return WERR_FILE_EXISTS;
1813         }
1814
1815         /* We can only add disk shares. */
1816         if (type != STYPE_DISKTREE) {
1817                 return WERR_ACCESS_DENIED;
1818         }
1819
1820         /* Check if the pathname is valid. */
1821         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1822                 return WERR_OBJECT_PATH_INVALID;
1823         }
1824
1825         /* Ensure share name, pathname and comment don't contain '"' characters. */
1826         string_replace(share_name, '"', ' ');
1827         string_replace(path, '"', ' ');
1828         if (comment) {
1829                 string_replace(comment, '"', ' ');
1830         }
1831
1832         command = talloc_asprintf(ctx,
1833                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1834                         lp_add_share_cmd(),
1835                         get_dyn_CONFIGFILE(),
1836                         share_name,
1837                         path,
1838                         comment ? comment : "",
1839                         max_connections);
1840         if (!command) {
1841                 return WERR_NOMEM;
1842         }
1843
1844         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1845
1846         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1847
1848         if ( is_disk_op )
1849                 become_root();
1850
1851         /* FIXME: use libnetconf here - gd */
1852
1853         if ( (ret = smbrun(command, NULL)) == 0 ) {
1854                 /* Tell everyone we updated smb.conf. */
1855                 message_send_all(smbd_messaging_context(),
1856                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1857         }
1858
1859         if ( is_disk_op )
1860                 unbecome_root();
1861
1862         /********* END SeDiskOperatorPrivilege BLOCK *********/
1863
1864         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1865                 command, ret ));
1866
1867         TALLOC_FREE(command);
1868
1869         if ( ret != 0 )
1870                 return WERR_ACCESS_DENIED;
1871
1872         if (psd) {
1873                 if (!set_share_security(share_name, psd)) {
1874                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1875                                 share_name ));
1876                 }
1877         }
1878
1879         /*
1880          * We don't call reload_services() here, the message will
1881          * cause this to be done before the next packet is read
1882          * from the client. JRA.
1883          */
1884
1885         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1886
1887         return WERR_OK;
1888 }
1889
1890 /*******************************************************************
1891  _srvsvc_NetShareDel
1892  Call "delete share command" with the share name as
1893  a parameter.
1894 ********************************************************************/
1895
1896 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1897                            struct srvsvc_NetShareDel *r)
1898 {
1899         char *command = NULL;
1900         char *share_name = NULL;
1901         int ret;
1902         int snum;
1903         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1904         bool is_disk_op;
1905         struct share_params *params;
1906         TALLOC_CTX *ctx = p->mem_ctx;
1907
1908         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1909
1910         share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1911         if (!share_name) {
1912                 return WERR_NET_NAME_NOT_FOUND;
1913         }
1914         if ( strequal(share_name,"IPC$")
1915                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1916                 || strequal(share_name,"global") )
1917         {
1918                 return WERR_ACCESS_DENIED;
1919         }
1920
1921         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1922                 return WERR_NO_SUCH_SHARE;
1923         }
1924
1925         snum = find_service(share_name);
1926
1927         /* No change to printer shares. */
1928         if (lp_print_ok(snum))
1929                 return WERR_ACCESS_DENIED;
1930
1931         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1932
1933         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1934                 return WERR_ACCESS_DENIED;
1935
1936         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1937                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1938                 return WERR_ACCESS_DENIED;
1939         }
1940
1941         command = talloc_asprintf(ctx,
1942                         "%s \"%s\" \"%s\"",
1943                         lp_delete_share_cmd(),
1944                         get_dyn_CONFIGFILE(),
1945                         lp_servicename(snum));
1946         if (!command) {
1947                 return WERR_NOMEM;
1948         }
1949
1950         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1951
1952         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1953
1954         if ( is_disk_op )
1955                 become_root();
1956
1957         if ( (ret = smbrun(command, NULL)) == 0 ) {
1958                 /* Tell everyone we updated smb.conf. */
1959                 message_send_all(smbd_messaging_context(),
1960                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1961         }
1962
1963         if ( is_disk_op )
1964                 unbecome_root();
1965
1966         /********* END SeDiskOperatorPrivilege BLOCK *********/
1967
1968         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1969
1970         if ( ret != 0 )
1971                 return WERR_ACCESS_DENIED;
1972
1973         /* Delete the SD in the database. */
1974         delete_share_security(lp_servicename(params->service));
1975
1976         lp_killservice(params->service);
1977
1978         return WERR_OK;
1979 }
1980
1981 /*******************************************************************
1982  _srvsvc_NetShareDelSticky
1983 ********************************************************************/
1984
1985 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1986                                  struct srvsvc_NetShareDelSticky *r)
1987 {
1988         struct srvsvc_NetShareDel q;
1989
1990         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1991
1992         q.in.server_unc         = r->in.server_unc;
1993         q.in.share_name         = r->in.share_name;
1994         q.in.reserved           = r->in.reserved;
1995
1996         return _srvsvc_NetShareDel(p, &q);
1997 }
1998
1999 /*******************************************************************
2000  _srvsvc_NetRemoteTOD
2001 ********************************************************************/
2002
2003 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2004                             struct srvsvc_NetRemoteTOD *r)
2005 {
2006         struct srvsvc_NetRemoteTODInfo *tod;
2007         struct tm *t;
2008         time_t unixdate = time(NULL);
2009
2010         /* We do this call first as if we do it *after* the gmtime call
2011            it overwrites the pointed-to values. JRA */
2012
2013         uint32 zone = get_time_zone(unixdate)/60;
2014
2015         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2016
2017         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2018                 return WERR_NOMEM;
2019
2020         *r->out.info = tod;
2021
2022         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2023
2024         t = gmtime(&unixdate);
2025
2026         /* set up the */
2027         tod->elapsed    = unixdate;
2028         tod->msecs      = 0;
2029         tod->hours      = t->tm_hour;
2030         tod->mins       = t->tm_min;
2031         tod->secs       = t->tm_sec;
2032         tod->hunds      = 0;
2033         tod->timezone   = zone;
2034         tod->tinterval  = 10000;
2035         tod->day        = t->tm_mday;
2036         tod->month      = t->tm_mon + 1;
2037         tod->year       = 1900+t->tm_year;
2038         tod->weekday    = t->tm_wday;
2039
2040         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2041
2042         return WERR_OK;
2043 }
2044
2045 /***********************************************************************************
2046  _srvsvc_NetGetFileSecurity
2047  Win9x NT tools get security descriptor.
2048 ***********************************************************************************/
2049
2050 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2051                                   struct srvsvc_NetGetFileSecurity *r)
2052 {
2053         struct smb_filename *smb_fname = NULL;
2054         SEC_DESC *psd = NULL;
2055         size_t sd_size;
2056         fstring servicename;
2057         SMB_STRUCT_STAT st;
2058         NTSTATUS nt_status;
2059         WERROR werr;
2060         connection_struct *conn = NULL;
2061         struct sec_desc_buf *sd_buf = NULL;
2062         files_struct *fsp = NULL;
2063         int snum;
2064         char *oldcwd = NULL;
2065
2066         ZERO_STRUCT(st);
2067
2068         fstrcpy(servicename, r->in.share);
2069
2070         snum = find_service(servicename);
2071         if (snum == -1) {
2072                 DEBUG(10, ("Could not find service %s\n", servicename));
2073                 werr = WERR_NET_NAME_NOT_FOUND;
2074                 goto error_exit;
2075         }
2076
2077         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2078                                        lp_pathname(snum), p->server_info,
2079                                        &oldcwd);
2080         if (!NT_STATUS_IS_OK(nt_status)) {
2081                 DEBUG(10, ("create_conn_struct failed: %s\n",
2082                            nt_errstr(nt_status)));
2083                 werr = ntstatus_to_werror(nt_status);
2084                 goto error_exit;
2085         }
2086
2087         nt_status = filename_convert(talloc_tos(),
2088                                         conn,
2089                                         false,
2090                                         r->in.file,
2091                                         0,
2092                                         NULL,
2093                                         &smb_fname);
2094         if (!NT_STATUS_IS_OK(nt_status)) {
2095                 werr = ntstatus_to_werror(nt_status);
2096                 goto error_exit;
2097         }
2098
2099         nt_status = SMB_VFS_CREATE_FILE(
2100                 conn,                                   /* conn */
2101                 NULL,                                   /* req */
2102                 0,                                      /* root_dir_fid */
2103                 smb_fname,                              /* fname */
2104                 FILE_READ_ATTRIBUTES,                   /* access_mask */
2105                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2106                 FILE_OPEN,                              /* create_disposition*/
2107                 0,                                      /* create_options */
2108                 0,                                      /* file_attributes */
2109                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2110                 0,                                      /* allocation_size */
2111                 NULL,                                   /* sd */
2112                 NULL,                                   /* ea_list */
2113                 &fsp,                                   /* result */
2114                 NULL);                                  /* pinfo */
2115
2116         if (!NT_STATUS_IS_OK(nt_status)) {
2117                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2118                          smb_fname_str_dbg(smb_fname)));
2119                 werr = ntstatus_to_werror(nt_status);
2120                 goto error_exit;
2121         }
2122
2123         nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2124                                        (OWNER_SECURITY_INFORMATION
2125                                         |GROUP_SECURITY_INFORMATION
2126                                         |DACL_SECURITY_INFORMATION), &psd);
2127
2128         if (!NT_STATUS_IS_OK(nt_status)) {
2129                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2130                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
2131                 werr = ntstatus_to_werror(nt_status);
2132                 goto error_exit;
2133         }
2134
2135         sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2136
2137         sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2138         if (!sd_buf) {
2139                 werr = WERR_NOMEM;
2140                 goto error_exit;
2141         }
2142
2143         sd_buf->sd_size = sd_size;
2144         sd_buf->sd = psd;
2145
2146         *r->out.sd_buf = sd_buf;
2147
2148         psd->dacl->revision = NT4_ACL_REVISION;
2149
2150         close_file(NULL, fsp, NORMAL_CLOSE);
2151         vfs_ChDir(conn, oldcwd);
2152         conn_free(conn);
2153         werr = WERR_OK;
2154         goto done;
2155
2156 error_exit:
2157
2158         if (fsp) {
2159                 close_file(NULL, fsp, NORMAL_CLOSE);
2160         }
2161
2162         if (oldcwd) {
2163                 vfs_ChDir(conn, oldcwd);
2164         }
2165
2166         if (conn) {
2167                 conn_free(conn);
2168         }
2169
2170  done:
2171         TALLOC_FREE(smb_fname);
2172
2173         return werr;
2174 }
2175
2176 /***********************************************************************************
2177  _srvsvc_NetSetFileSecurity
2178  Win9x NT tools set security descriptor.
2179 ***********************************************************************************/
2180
2181 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2182                                   struct srvsvc_NetSetFileSecurity *r)
2183 {
2184         struct smb_filename *smb_fname = NULL;
2185         fstring servicename;
2186         files_struct *fsp = NULL;
2187         SMB_STRUCT_STAT st;
2188         NTSTATUS nt_status;
2189         WERROR werr;
2190         connection_struct *conn = NULL;
2191         int snum;
2192         char *oldcwd = NULL;
2193         struct security_descriptor *psd = NULL;
2194         uint32_t security_info_sent = 0;
2195
2196         ZERO_STRUCT(st);
2197
2198         fstrcpy(servicename, r->in.share);
2199
2200         snum = find_service(servicename);
2201         if (snum == -1) {
2202                 DEBUG(10, ("Could not find service %s\n", servicename));
2203                 werr = WERR_NET_NAME_NOT_FOUND;
2204                 goto error_exit;
2205         }
2206
2207         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2208                                        lp_pathname(snum), p->server_info,
2209                                        &oldcwd);
2210         if (!NT_STATUS_IS_OK(nt_status)) {
2211                 DEBUG(10, ("create_conn_struct failed: %s\n",
2212                            nt_errstr(nt_status)));
2213                 werr = ntstatus_to_werror(nt_status);
2214                 goto error_exit;
2215         }
2216
2217         nt_status = filename_convert(talloc_tos(),
2218                                         conn,
2219                                         false,
2220                                         r->in.file,
2221                                         0,
2222                                         NULL,
2223                                         &smb_fname);
2224         if (!NT_STATUS_IS_OK(nt_status)) {
2225                 werr = ntstatus_to_werror(nt_status);
2226                 goto error_exit;
2227         }
2228
2229         nt_status = SMB_VFS_CREATE_FILE(
2230                 conn,                                   /* conn */
2231                 NULL,                                   /* req */
2232                 0,                                      /* root_dir_fid */
2233                 smb_fname,                              /* fname */
2234                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
2235                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2236                 FILE_OPEN,                              /* create_disposition*/
2237                 0,                                      /* create_options */
2238                 0,                                      /* file_attributes */
2239                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2240                 0,                                      /* allocation_size */
2241                 NULL,                                   /* sd */
2242                 NULL,                                   /* ea_list */
2243                 &fsp,                                   /* result */
2244                 NULL);                                  /* pinfo */
2245
2246         if (!NT_STATUS_IS_OK(nt_status)) {
2247                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2248                          smb_fname_str_dbg(smb_fname)));
2249                 werr = ntstatus_to_werror(nt_status);
2250                 goto error_exit;
2251         }
2252
2253         psd = r->in.sd_buf->sd;
2254         security_info_sent = r->in.securityinformation;
2255
2256         if (psd->owner_sid==0) {
2257                 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2258         }
2259         if (psd->group_sid==0) {
2260                 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2261         }
2262         if (psd->sacl==0) {
2263                 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2264         }
2265         if (psd->dacl==0) {
2266                 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2267         }
2268
2269         /* Convert all the generic bits. */
2270         security_acl_map_generic(psd->dacl, &file_generic_mapping);
2271         security_acl_map_generic(psd->sacl, &file_generic_mapping);
2272
2273         nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2274                                         security_info_sent,
2275                                         psd);
2276
2277         if (!NT_STATUS_IS_OK(nt_status) ) {
2278                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2279                          "on file %s\n", r->in.share));
2280                 werr = WERR_ACCESS_DENIED;
2281                 goto error_exit;
2282         }
2283
2284         close_file(NULL, fsp, NORMAL_CLOSE);
2285         vfs_ChDir(conn, oldcwd);
2286         conn_free(conn);
2287         werr = WERR_OK;
2288         goto done;
2289
2290 error_exit:
2291
2292         if (fsp) {
2293                 close_file(NULL, fsp, NORMAL_CLOSE);
2294         }
2295
2296         if (oldcwd) {
2297                 vfs_ChDir(conn, oldcwd);
2298         }
2299
2300         if (conn) {
2301                 conn_free(conn);
2302         }
2303
2304  done:
2305         TALLOC_FREE(smb_fname);
2306
2307         return werr;
2308 }
2309
2310 /***********************************************************************************
2311  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2312  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2313  These disks would the disks listed by this function.
2314  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2315  "Nigel Williams" <nigel@veritas.com>.
2316 ***********************************************************************************/
2317
2318 static const char *server_disks[] = {"C:"};
2319
2320 static uint32 get_server_disk_count(void)
2321 {
2322         return sizeof(server_disks)/sizeof(server_disks[0]);
2323 }
2324
2325 static uint32 init_server_disk_enum(uint32 *resume)
2326 {
2327         uint32 server_disk_count = get_server_disk_count();
2328
2329         /*resume can be an offset into the list for now*/
2330
2331         if(*resume & 0x80000000)
2332                 *resume = 0;
2333
2334         if(*resume > server_disk_count)
2335                 *resume = server_disk_count;
2336
2337         return server_disk_count - *resume;
2338 }
2339
2340 static const char *next_server_disk_enum(uint32 *resume)
2341 {
2342         const char *disk;
2343
2344         if(init_server_disk_enum(resume) == 0)
2345                 return NULL;
2346
2347         disk = server_disks[*resume];
2348
2349         (*resume)++;
2350
2351         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2352
2353         return disk;
2354 }
2355
2356 /********************************************************************
2357  _srvsvc_NetDiskEnum
2358 ********************************************************************/
2359
2360 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2361                            struct srvsvc_NetDiskEnum *r)
2362 {
2363         uint32 i;
2364         const char *disk_name;
2365         TALLOC_CTX *ctx = p->mem_ctx;
2366         WERROR werr;
2367         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2368
2369         werr = WERR_OK;
2370
2371         *r->out.totalentries = init_server_disk_enum(&resume);
2372
2373         r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2374                                                MAX_SERVER_DISK_ENTRIES);
2375         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2376
2377         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2378
2379         r->out.info->count = 0;
2380
2381         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2382
2383                 r->out.info->count++;
2384
2385                 /*copy disk name into a unicode string*/
2386
2387                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2388                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2389         }
2390
2391         /* add a terminating null string.  Is this there if there is more data to come? */
2392
2393         r->out.info->count++;
2394
2395         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2396         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2397
2398         if (r->out.resume_handle) {
2399                 *r->out.resume_handle = resume;
2400         }
2401
2402         return werr;
2403 }
2404
2405 /********************************************************************
2406  _srvsvc_NetNameValidate
2407 ********************************************************************/
2408
2409 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2410                                struct srvsvc_NetNameValidate *r)
2411 {
2412         switch (r->in.name_type) {
2413         case 0x9:
2414                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2415                                        strlen_m(r->in.name)))
2416                 {
2417                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2418                                 r->in.name));
2419                         return WERR_INVALID_NAME;
2420                 }
2421                 break;
2422
2423         default:
2424                 return WERR_UNKNOWN_LEVEL;
2425         }
2426
2427         return WERR_OK;
2428 }
2429
2430 /*******************************************************************
2431 ********************************************************************/
2432
2433 static void enum_file_close_fn( const struct share_mode_entry *e,
2434                           const char *sharepath, const char *fname,
2435                           void *private_data )
2436 {
2437         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2438         struct srvsvc_NetFileClose *r =
2439                 (struct srvsvc_NetFileClose *)private_data;
2440         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2441
2442         if (fid != r->in.fid) {
2443                 return; /* Not this file. */
2444         }
2445
2446         if (!process_exists(e->pid) ) {
2447                 return;
2448         }
2449
2450         /* Ok - send the close message. */
2451         DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2452                 sharepath,
2453                 share_mode_str(talloc_tos(), 0, e) ));
2454
2455         share_mode_entry_to_message(msg, e);
2456
2457         r->out.result = ntstatus_to_werror(
2458                         messaging_send_buf(smbd_messaging_context(),
2459                                 e->pid, MSG_SMB_CLOSE_FILE,
2460                                 (uint8 *)msg,
2461                                 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2462 }
2463
2464 /********************************************************************
2465  Close a file given a 32-bit file id.
2466 ********************************************************************/
2467
2468 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2469 {
2470         SE_PRIV se_diskop = SE_DISK_OPERATOR;
2471         bool is_disk_op;
2472
2473         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2474
2475         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2476
2477         if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2478                 return WERR_ACCESS_DENIED;
2479         }
2480
2481         /* enum_file_close_fn sends the close message to
2482          * the relevent smbd process. */
2483
2484         r->out.result = WERR_BADFILE;
2485         share_mode_forall( enum_file_close_fn, (void *)r);
2486         return r->out.result;
2487 }
2488
2489 /********************************************************************
2490 ********************************************************************/
2491
2492 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2493 {
2494         p->rng_fault_state = True;
2495         return WERR_NOT_SUPPORTED;
2496 }
2497
2498 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2499 {
2500         p->rng_fault_state = True;
2501         return WERR_NOT_SUPPORTED;
2502 }
2503
2504 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2505 {
2506         p->rng_fault_state = True;
2507         return WERR_NOT_SUPPORTED;
2508 }
2509
2510 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2511 {
2512         p->rng_fault_state = True;
2513         return WERR_NOT_SUPPORTED;
2514 }
2515
2516 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2517 {
2518         p->rng_fault_state = True;
2519         return WERR_NOT_SUPPORTED;
2520 }
2521
2522 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2523 {
2524         p->rng_fault_state = True;
2525         return WERR_NOT_SUPPORTED;
2526 }
2527
2528 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2529 {
2530         p->rng_fault_state = True;
2531         return WERR_NOT_SUPPORTED;
2532 }
2533
2534 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2535 {
2536         p->rng_fault_state = True;
2537         return WERR_NOT_SUPPORTED;
2538 }
2539
2540 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2541 {
2542         p->rng_fault_state = True;
2543         return WERR_NOT_SUPPORTED;
2544 }
2545
2546 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2547 {
2548         p->rng_fault_state = True;
2549         return WERR_NOT_SUPPORTED;
2550 }
2551
2552 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2553 {
2554         p->rng_fault_state = True;
2555         return WERR_NOT_SUPPORTED;
2556 }
2557
2558 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2559 {
2560         p->rng_fault_state = True;
2561         return WERR_NOT_SUPPORTED;
2562 }
2563
2564 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2565 {
2566         p->rng_fault_state = True;
2567         return WERR_NOT_SUPPORTED;
2568 }
2569
2570 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2571 {
2572         p->rng_fault_state = True;
2573         return WERR_NOT_SUPPORTED;
2574 }
2575
2576 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2577 {
2578         p->rng_fault_state = True;
2579         return WERR_NOT_SUPPORTED;
2580 }
2581
2582 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2583 {
2584         p->rng_fault_state = True;
2585         return WERR_NOT_SUPPORTED;
2586 }
2587
2588 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2589 {
2590         p->rng_fault_state = True;
2591         return WERR_NOT_SUPPORTED;
2592 }
2593
2594 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2595 {
2596         p->rng_fault_state = True;
2597         return WERR_NOT_SUPPORTED;
2598 }
2599
2600 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2601 {
2602         p->rng_fault_state = True;
2603         return WERR_NOT_SUPPORTED;
2604 }
2605
2606 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2607 {
2608         p->rng_fault_state = True;
2609         return WERR_NOT_SUPPORTED;
2610 }
2611
2612 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2613 {
2614         p->rng_fault_state = True;
2615         return WERR_NOT_SUPPORTED;
2616 }
2617
2618 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2619 {
2620         p->rng_fault_state = True;
2621         return WERR_NOT_SUPPORTED;
2622 }
2623
2624 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2625 {
2626         p->rng_fault_state = True;
2627         return WERR_NOT_SUPPORTED;
2628 }
2629
2630 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2631 {
2632         p->rng_fault_state = True;
2633         return WERR_NOT_SUPPORTED;
2634 }
2635
2636 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2637 {
2638         p->rng_fault_state = True;
2639         return WERR_NOT_SUPPORTED;
2640 }
2641
2642 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2643 {
2644         p->rng_fault_state = True;
2645         return WERR_NOT_SUPPORTED;
2646 }
2647
2648 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2649 {
2650         p->rng_fault_state = True;
2651         return WERR_NOT_SUPPORTED;
2652 }
2653
2654 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2655 {
2656         p->rng_fault_state = True;
2657         return WERR_NOT_SUPPORTED;
2658 }
2659
2660 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2661 {
2662         p->rng_fault_state = True;
2663         return WERR_NOT_SUPPORTED;
2664 }
2665
2666 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2667 {
2668         p->rng_fault_state = True;
2669         return WERR_NOT_SUPPORTED;
2670 }
2671
2672 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2673 {
2674         p->rng_fault_state = True;
2675         return WERR_NOT_SUPPORTED;
2676 }
2677
2678 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2679 {
2680         p->rng_fault_state = True;
2681         return WERR_NOT_SUPPORTED;
2682 }
2683
2684 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2685 {
2686         p->rng_fault_state = True;
2687         return WERR_NOT_SUPPORTED;
2688 }
2689
2690 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2691 {
2692         p->rng_fault_state = True;
2693         return WERR_NOT_SUPPORTED;
2694 }
2695
2696 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2697 {
2698         p->rng_fault_state = True;
2699         return WERR_NOT_SUPPORTED;
2700 }
2701