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