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