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