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