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