Fix bug #7781 (Samba transforms "ShareName" to lowercase when adding new share via...
[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         if (!r->in.share_name) {
1401                 return WERR_INVALID_NAME;
1402         }
1403
1404         snum = find_service(r->in.share_name, share_name);
1405         if (snum < 0) {
1406                 return WERR_INVALID_NAME;
1407         }
1408
1409         switch (r->in.level) {
1410                 case 0:
1411                         info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1412                         W_ERROR_HAVE_NO_MEMORY(info->info0);
1413                         init_srv_share_info_0(p, info->info0, snum);
1414                         break;
1415                 case 1:
1416                         info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1417                         W_ERROR_HAVE_NO_MEMORY(info->info1);
1418                         init_srv_share_info_1(p, info->info1, snum);
1419                         break;
1420                 case 2:
1421                         info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1422                         W_ERROR_HAVE_NO_MEMORY(info->info2);
1423                         init_srv_share_info_2(p, info->info2, snum);
1424                         break;
1425                 case 501:
1426                         info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1427                         W_ERROR_HAVE_NO_MEMORY(info->info501);
1428                         init_srv_share_info_501(p, info->info501, snum);
1429                         break;
1430                 case 502:
1431                         info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1432                         W_ERROR_HAVE_NO_MEMORY(info->info502);
1433                         init_srv_share_info_502(p, info->info502, snum);
1434                         break;
1435                 case 1004:
1436                         info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1437                         W_ERROR_HAVE_NO_MEMORY(info->info1004);
1438                         init_srv_share_info_1004(p, info->info1004, snum);
1439                         break;
1440                 case 1005:
1441                         info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1442                         W_ERROR_HAVE_NO_MEMORY(info->info1005);
1443                         init_srv_share_info_1005(p, info->info1005, snum);
1444                         break;
1445                 case 1006:
1446                         info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1447                         W_ERROR_HAVE_NO_MEMORY(info->info1006);
1448                         init_srv_share_info_1006(p, info->info1006, snum);
1449                         break;
1450                 case 1007:
1451                         info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1452                         W_ERROR_HAVE_NO_MEMORY(info->info1007);
1453                         init_srv_share_info_1007(p, info->info1007, snum);
1454                         break;
1455                 case 1501:
1456                         init_srv_share_info_1501(p, info->info1501, snum);
1457                         break;
1458                 default:
1459                         DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1460                                 r->in.level));
1461                         status = WERR_UNKNOWN_LEVEL;
1462                         break;
1463         }
1464
1465         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1466
1467         return status;
1468 }
1469
1470 /*******************************************************************
1471  Check a given DOS pathname is valid for a share.
1472 ********************************************************************/
1473
1474 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1475 {
1476         char *ptr = NULL;
1477
1478         if (!dos_pathname) {
1479                 return NULL;
1480         }
1481
1482         ptr = talloc_strdup(ctx, dos_pathname);
1483         if (!ptr) {
1484                 return NULL;
1485         }
1486         /* Convert any '\' paths to '/' */
1487         unix_format(ptr);
1488         ptr = unix_clean_name(ctx, ptr);
1489         if (!ptr) {
1490                 return NULL;
1491         }
1492
1493         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1494         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1495                 ptr += 2;
1496
1497         /* Only absolute paths allowed. */
1498         if (*ptr != '/')
1499                 return NULL;
1500
1501         return ptr;
1502 }
1503
1504 /*******************************************************************
1505  _srvsvc_NetShareSetInfo. Modify share details.
1506 ********************************************************************/
1507
1508 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1509                                struct srvsvc_NetShareSetInfo *r)
1510 {
1511         char *command = NULL;
1512         fstring share_name;
1513         char *comment = NULL;
1514         const char *pathname = NULL;
1515         int type;
1516         int snum;
1517         int ret;
1518         char *path = NULL;
1519         SEC_DESC *psd = NULL;
1520         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1521         bool is_disk_op = False;
1522         int max_connections = 0;
1523         TALLOC_CTX *ctx = p->mem_ctx;
1524         union srvsvc_NetShareInfo *info = r->in.info;
1525
1526         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1527
1528         if (!r->in.share_name) {
1529                 return WERR_INVALID_NAME;
1530         }
1531
1532         if (r->out.parm_error) {
1533                 *r->out.parm_error = 0;
1534         }
1535
1536         if ( strequal(r->in.share_name,"IPC$")
1537                 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1538                 || strequal(r->in.share_name,"global") )
1539         {
1540                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1541                         "modified by a remote user.\n",
1542                         r->in.share_name ));
1543                 return WERR_ACCESS_DENIED;
1544         }
1545
1546         snum = find_service(r->in.share_name, share_name);
1547
1548         /* Does this share exist ? */
1549         if (snum < 0)
1550                 return WERR_NET_NAME_NOT_FOUND;
1551
1552         /* No change to printer shares. */
1553         if (lp_print_ok(snum))
1554                 return WERR_ACCESS_DENIED;
1555
1556         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1557
1558         /* fail out now if you are not root and not a disk op */
1559
1560         if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1561                 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1562                         "SeDiskOperatorPrivilege privilege needed to modify "
1563                         "share %s\n",
1564                         (unsigned int)p->server_info->utok.uid,
1565                         share_name ));
1566                 return WERR_ACCESS_DENIED;
1567         }
1568
1569         switch (r->in.level) {
1570         case 1:
1571                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1572                 comment = talloc_strdup(ctx, info->info1->comment);
1573                 type = info->info1->type;
1574                 psd = NULL;
1575                 break;
1576         case 2:
1577                 comment = talloc_strdup(ctx, info->info2->comment);
1578                 pathname = info->info2->path;
1579                 type = info->info2->type;
1580                 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1581                         0 : info->info2->max_users;
1582                 psd = NULL;
1583                 break;
1584 #if 0
1585                 /* not supported on set but here for completeness */
1586         case 501:
1587                 comment = talloc_strdup(ctx, info->info501->comment);
1588                 type = info->info501->type;
1589                 psd = NULL;
1590                 break;
1591 #endif
1592         case 502:
1593                 comment = talloc_strdup(ctx, info->info502->comment);
1594                 pathname = info->info502->path;
1595                 type = info->info502->type;
1596                 psd = info->info502->sd_buf.sd;
1597                 map_generic_share_sd_bits(psd);
1598                 break;
1599         case 1004:
1600                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1601                 comment = talloc_strdup(ctx, info->info1004->comment);
1602                 type = STYPE_DISKTREE;
1603                 break;
1604         case 1005:
1605                 /* XP re-sets the csc policy even if it wasn't changed by the
1606                    user, so we must compare it to see if it's what is set in
1607                    smb.conf, so that we can contine other ops like setting
1608                    ACLs on a share */
1609                 if (((info->info1005->dfs_flags &
1610                       SHARE_1005_CSC_POLICY_MASK) >>
1611                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1612                         return WERR_OK;
1613                 else {
1614                         DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1615                         return WERR_ACCESS_DENIED;
1616                 }
1617         case 1006:
1618         case 1007:
1619                 return WERR_ACCESS_DENIED;
1620         case 1501:
1621                 pathname = talloc_strdup(ctx, lp_pathname(snum));
1622                 comment = talloc_strdup(ctx, lp_comment(snum));
1623                 psd = info->info1501->sd;
1624                 map_generic_share_sd_bits(psd);
1625                 type = STYPE_DISKTREE;
1626                 break;
1627         default:
1628                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1629                         r->in.level));
1630                 return WERR_UNKNOWN_LEVEL;
1631         }
1632
1633         /* We can only modify disk shares. */
1634         if (type != STYPE_DISKTREE) {
1635                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1636                         "disk share\n",
1637                         share_name ));
1638                 return WERR_ACCESS_DENIED;
1639         }
1640
1641         if (comment == NULL) {
1642                 return WERR_NOMEM;
1643         }
1644
1645         /* Check if the pathname is valid. */
1646         if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1647                 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1648                         pathname ));
1649                 return WERR_OBJECT_PATH_INVALID;
1650         }
1651
1652         /* Ensure share name, pathname and comment don't contain '"' characters. */
1653         string_replace(share_name, '"', ' ');
1654         string_replace(path, '"', ' ');
1655         string_replace(comment, '"', ' ');
1656
1657         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1658                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1659
1660         /* Only call modify function if something changed. */
1661
1662         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1663                         || (lp_max_connections(snum) != max_connections)) {
1664                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1665                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1666                         return WERR_ACCESS_DENIED;
1667                 }
1668
1669                 command = talloc_asprintf(p->mem_ctx,
1670                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1671                                 lp_change_share_cmd(),
1672                                 get_dyn_CONFIGFILE(),
1673                                 share_name,
1674                                 path,
1675                                 comment ? comment : "",
1676                                 max_connections);
1677                 if (!command) {
1678                         return WERR_NOMEM;
1679                 }
1680
1681                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1682
1683                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1684
1685                 if (is_disk_op)
1686                         become_root();
1687
1688                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1689                         /* Tell everyone we updated smb.conf. */
1690                         message_send_all(smbd_messaging_context(),
1691                                          MSG_SMB_CONF_UPDATED, NULL, 0,
1692                                          NULL);
1693                 }
1694
1695                 if ( is_disk_op )
1696                         unbecome_root();
1697
1698                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1699
1700                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1701                         command, ret ));
1702
1703                 TALLOC_FREE(command);
1704
1705                 if ( ret != 0 )
1706                         return WERR_ACCESS_DENIED;
1707         } else {
1708                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1709                         share_name ));
1710         }
1711
1712         /* Replace SD if changed. */
1713         if (psd) {
1714                 SEC_DESC *old_sd;
1715                 size_t sd_size;
1716
1717                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1718
1719                 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1720                         if (!set_share_security(share_name, psd))
1721                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1722                                         share_name ));
1723                 }
1724         }
1725
1726         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1727
1728         return WERR_OK;
1729 }
1730
1731 /*******************************************************************
1732  _srvsvc_NetShareAdd.
1733  Call 'add_share_command "sharename" "pathname"
1734  "comment" "max connections = "
1735 ********************************************************************/
1736
1737 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1738                            struct srvsvc_NetShareAdd *r)
1739 {
1740         char *command = NULL;
1741         char *share_name_in = NULL;
1742         fstring share_name;
1743         char *comment = NULL;
1744         char *pathname = NULL;
1745         int type;
1746         int snum;
1747         int ret;
1748         char *path;
1749         SEC_DESC *psd = NULL;
1750         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1751         bool is_disk_op;
1752         int max_connections = 0;
1753         TALLOC_CTX *ctx = p->mem_ctx;
1754
1755         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1756
1757         if (r->out.parm_error) {
1758                 *r->out.parm_error = 0;
1759         }
1760
1761         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1762
1763         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1764                 return WERR_ACCESS_DENIED;
1765
1766         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1767                 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1768                 return WERR_ACCESS_DENIED;
1769         }
1770
1771         switch (r->in.level) {
1772         case 0:
1773                 /* No path. Not enough info in a level 0 to do anything. */
1774                 return WERR_ACCESS_DENIED;
1775         case 1:
1776                 /* Not enough info in a level 1 to do anything. */
1777                 return WERR_ACCESS_DENIED;
1778         case 2:
1779                 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1780                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1781                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1782                 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1783                         0 : r->in.info->info2->max_users;
1784                 type = r->in.info->info2->type;
1785                 break;
1786         case 501:
1787                 /* No path. Not enough info in a level 501 to do anything. */
1788                 return WERR_ACCESS_DENIED;
1789         case 502:
1790                 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1791                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1792                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1793                 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1794                         0 : r->in.info->info502->max_users;
1795                 type = r->in.info->info502->type;
1796                 psd = r->in.info->info502->sd_buf.sd;
1797                 map_generic_share_sd_bits(psd);
1798                 break;
1799
1800                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1801
1802         case 1004:
1803         case 1005:
1804         case 1006:
1805         case 1007:
1806                 return WERR_ACCESS_DENIED;
1807         case 1501:
1808                 /* DFS only level. */
1809                 return WERR_ACCESS_DENIED;
1810         default:
1811                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1812                         r->in.level));
1813                 return WERR_UNKNOWN_LEVEL;
1814         }
1815
1816         /* check for invalid share names */
1817
1818         if (!share_name_in || !validate_net_name(share_name_in,
1819                                 INVALID_SHARENAME_CHARS,
1820                                 strlen(share_name_in))) {
1821                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1822                                         share_name_in ? share_name_in : ""));
1823                 return WERR_INVALID_NAME;
1824         }
1825
1826         if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1827                         || (lp_enable_asu_support() &&
1828                                         strequal(share_name_in,"ADMIN$"))) {
1829                 return WERR_ACCESS_DENIED;
1830         }
1831
1832         snum = find_service(share_name_in, share_name);
1833
1834         /* Share already exists. */
1835         if (snum >= 0) {
1836                 return WERR_FILE_EXISTS;
1837         }
1838
1839         /* We can only add disk shares. */
1840         if (type != STYPE_DISKTREE) {
1841                 return WERR_ACCESS_DENIED;
1842         }
1843
1844         /* Check if the pathname is valid. */
1845         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1846                 return WERR_OBJECT_PATH_INVALID;
1847         }
1848
1849         /* Ensure share name, pathname and comment don't contain '"' characters. */
1850         string_replace(share_name_in, '"', ' ');
1851         string_replace(path, '"', ' ');
1852         if (comment) {
1853                 string_replace(comment, '"', ' ');
1854         }
1855
1856         command = talloc_asprintf(ctx,
1857                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1858                         lp_add_share_cmd(),
1859                         get_dyn_CONFIGFILE(),
1860                         share_name_in,
1861                         path,
1862                         comment ? comment : "",
1863                         max_connections);
1864         if (!command) {
1865                 return WERR_NOMEM;
1866         }
1867
1868         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1869
1870         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1871
1872         if ( is_disk_op )
1873                 become_root();
1874
1875         /* FIXME: use libnetconf here - gd */
1876
1877         if ( (ret = smbrun(command, NULL)) == 0 ) {
1878                 /* Tell everyone we updated smb.conf. */
1879                 message_send_all(smbd_messaging_context(),
1880                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1881         }
1882
1883         if ( is_disk_op )
1884                 unbecome_root();
1885
1886         /********* END SeDiskOperatorPrivilege BLOCK *********/
1887
1888         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1889                 command, ret ));
1890
1891         TALLOC_FREE(command);
1892
1893         if ( ret != 0 )
1894                 return WERR_ACCESS_DENIED;
1895
1896         if (psd) {
1897                 /* Note we use share_name here, not share_name_in as
1898                    we need a canonicalized name for setting security. */
1899                 if (!set_share_security(share_name, psd)) {
1900                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1901                                 share_name ));
1902                 }
1903         }
1904
1905         /*
1906          * We don't call reload_services() here, the message will
1907          * cause this to be done before the next packet is read
1908          * from the client. JRA.
1909          */
1910
1911         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1912
1913         return WERR_OK;
1914 }
1915
1916 /*******************************************************************
1917  _srvsvc_NetShareDel
1918  Call "delete share command" with the share name as
1919  a parameter.
1920 ********************************************************************/
1921
1922 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1923                            struct srvsvc_NetShareDel *r)
1924 {
1925         char *command = NULL;
1926         fstring share_name;
1927         int ret;
1928         int snum;
1929         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1930         bool is_disk_op;
1931         struct share_params *params;
1932         TALLOC_CTX *ctx = p->mem_ctx;
1933
1934         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1935
1936         if (!r->in.share_name) {
1937                 return WERR_NET_NAME_NOT_FOUND;
1938         }
1939         if ( strequal(r->in.share_name,"IPC$")
1940                 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1941                 || strequal(r->in.share_name,"global") )
1942         {
1943                 return WERR_ACCESS_DENIED;
1944         }
1945
1946         if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1947                 return WERR_NO_SUCH_SHARE;
1948         }
1949
1950         snum = find_service(r->in.share_name, share_name);
1951
1952         /* No change to printer shares. */
1953         if (lp_print_ok(snum))
1954                 return WERR_ACCESS_DENIED;
1955
1956         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1957
1958         if (p->server_info->utok.uid != sec_initial_uid()  && !is_disk_op )
1959                 return WERR_ACCESS_DENIED;
1960
1961         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1962                 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1963                 return WERR_ACCESS_DENIED;
1964         }
1965
1966         command = talloc_asprintf(ctx,
1967                         "%s \"%s\" \"%s\"",
1968                         lp_delete_share_cmd(),
1969                         get_dyn_CONFIGFILE(),
1970                         lp_servicename(snum));
1971         if (!command) {
1972                 return WERR_NOMEM;
1973         }
1974
1975         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1976
1977         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1978
1979         if ( is_disk_op )
1980                 become_root();
1981
1982         if ( (ret = smbrun(command, NULL)) == 0 ) {
1983                 /* Tell everyone we updated smb.conf. */
1984                 message_send_all(smbd_messaging_context(),
1985                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1986         }
1987
1988         if ( is_disk_op )
1989                 unbecome_root();
1990
1991         /********* END SeDiskOperatorPrivilege BLOCK *********/
1992
1993         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1994
1995         if ( ret != 0 )
1996                 return WERR_ACCESS_DENIED;
1997
1998         /* Delete the SD in the database. */
1999         delete_share_security(lp_servicename(params->service));
2000
2001         lp_killservice(params->service);
2002
2003         return WERR_OK;
2004 }
2005
2006 /*******************************************************************
2007  _srvsvc_NetShareDelSticky
2008 ********************************************************************/
2009
2010 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
2011                                  struct srvsvc_NetShareDelSticky *r)
2012 {
2013         struct srvsvc_NetShareDel q;
2014
2015         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2016
2017         q.in.server_unc         = r->in.server_unc;
2018         q.in.share_name         = r->in.share_name;
2019         q.in.reserved           = r->in.reserved;
2020
2021         return _srvsvc_NetShareDel(p, &q);
2022 }
2023
2024 /*******************************************************************
2025  _srvsvc_NetRemoteTOD
2026 ********************************************************************/
2027
2028 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2029                             struct srvsvc_NetRemoteTOD *r)
2030 {
2031         struct srvsvc_NetRemoteTODInfo *tod;
2032         struct tm *t;
2033         time_t unixdate = time(NULL);
2034
2035         /* We do this call first as if we do it *after* the gmtime call
2036            it overwrites the pointed-to values. JRA */
2037
2038         uint32 zone = get_time_zone(unixdate)/60;
2039
2040         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2041
2042         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2043                 return WERR_NOMEM;
2044
2045         *r->out.info = tod;
2046
2047         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2048
2049         t = gmtime(&unixdate);
2050
2051         /* set up the */
2052         tod->elapsed    = unixdate;
2053         tod->msecs      = 0;
2054         tod->hours      = t->tm_hour;
2055         tod->mins       = t->tm_min;
2056         tod->secs       = t->tm_sec;
2057         tod->hunds      = 0;
2058         tod->timezone   = zone;
2059         tod->tinterval  = 10000;
2060         tod->day        = t->tm_mday;
2061         tod->month      = t->tm_mon + 1;
2062         tod->year       = 1900+t->tm_year;
2063         tod->weekday    = t->tm_wday;
2064
2065         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2066
2067         return WERR_OK;
2068 }
2069
2070 /***********************************************************************************
2071  _srvsvc_NetGetFileSecurity
2072  Win9x NT tools get security descriptor.
2073 ***********************************************************************************/
2074
2075 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2076                                   struct srvsvc_NetGetFileSecurity *r)
2077 {
2078         struct smb_filename *smb_fname = NULL;
2079         SEC_DESC *psd = NULL;
2080         size_t sd_size;
2081         fstring servicename;
2082         SMB_STRUCT_STAT st;
2083         NTSTATUS nt_status;
2084         WERROR werr;
2085         connection_struct *conn = NULL;
2086         struct sec_desc_buf *sd_buf = NULL;
2087         files_struct *fsp = NULL;
2088         int snum;
2089         char *oldcwd = NULL;
2090
2091         ZERO_STRUCT(st);
2092
2093         if (!r->in.share) {
2094                 return WERR_INVALID_NAME;
2095         }
2096
2097         snum = find_service(r->in.share, servicename);
2098         if (snum == -1) {
2099                 DEBUG(10, ("Could not find service %s\n", servicename));
2100                 werr = WERR_NET_NAME_NOT_FOUND;
2101                 goto error_exit;
2102         }
2103
2104         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2105                                        lp_pathname(snum), p->server_info,
2106                                        &oldcwd);
2107         if (!NT_STATUS_IS_OK(nt_status)) {
2108                 DEBUG(10, ("create_conn_struct failed: %s\n",
2109                            nt_errstr(nt_status)));
2110                 werr = ntstatus_to_werror(nt_status);
2111                 goto error_exit;
2112         }
2113
2114         nt_status = filename_convert(talloc_tos(),
2115                                         conn,
2116                                         false,
2117                                         r->in.file,
2118                                         0,
2119                                         NULL,
2120                                         &smb_fname);
2121         if (!NT_STATUS_IS_OK(nt_status)) {
2122                 werr = ntstatus_to_werror(nt_status);
2123                 goto error_exit;
2124         }
2125
2126         nt_status = SMB_VFS_CREATE_FILE(
2127                 conn,                                   /* conn */
2128                 NULL,                                   /* req */
2129                 0,                                      /* root_dir_fid */
2130                 smb_fname,                              /* fname */
2131                 FILE_READ_ATTRIBUTES,                   /* access_mask */
2132                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2133                 FILE_OPEN,                              /* create_disposition*/
2134                 0,                                      /* create_options */
2135                 0,                                      /* file_attributes */
2136                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2137                 0,                                      /* allocation_size */
2138                 NULL,                                   /* sd */
2139                 NULL,                                   /* ea_list */
2140                 &fsp,                                   /* result */
2141                 NULL);                                  /* pinfo */
2142
2143         if (!NT_STATUS_IS_OK(nt_status)) {
2144                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2145                          smb_fname_str_dbg(smb_fname)));
2146                 werr = ntstatus_to_werror(nt_status);
2147                 goto error_exit;
2148         }
2149
2150         nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2151                                        (OWNER_SECURITY_INFORMATION
2152                                         |GROUP_SECURITY_INFORMATION
2153                                         |DACL_SECURITY_INFORMATION), &psd);
2154
2155         if (!NT_STATUS_IS_OK(nt_status)) {
2156                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2157                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
2158                 werr = ntstatus_to_werror(nt_status);
2159                 goto error_exit;
2160         }
2161
2162         sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2163
2164         sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2165         if (!sd_buf) {
2166                 werr = WERR_NOMEM;
2167                 goto error_exit;
2168         }
2169
2170         sd_buf->sd_size = sd_size;
2171         sd_buf->sd = psd;
2172
2173         *r->out.sd_buf = sd_buf;
2174
2175         psd->dacl->revision = NT4_ACL_REVISION;
2176
2177         close_file(NULL, fsp, NORMAL_CLOSE);
2178         vfs_ChDir(conn, oldcwd);
2179         conn_free(conn);
2180         werr = WERR_OK;
2181         goto done;
2182
2183 error_exit:
2184
2185         if (fsp) {
2186                 close_file(NULL, fsp, NORMAL_CLOSE);
2187         }
2188
2189         if (oldcwd) {
2190                 vfs_ChDir(conn, oldcwd);
2191         }
2192
2193         if (conn) {
2194                 conn_free(conn);
2195         }
2196
2197  done:
2198         TALLOC_FREE(smb_fname);
2199
2200         return werr;
2201 }
2202
2203 /***********************************************************************************
2204  _srvsvc_NetSetFileSecurity
2205  Win9x NT tools set security descriptor.
2206 ***********************************************************************************/
2207
2208 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2209                                   struct srvsvc_NetSetFileSecurity *r)
2210 {
2211         struct smb_filename *smb_fname = NULL;
2212         fstring servicename;
2213         files_struct *fsp = NULL;
2214         SMB_STRUCT_STAT st;
2215         NTSTATUS nt_status;
2216         WERROR werr;
2217         connection_struct *conn = NULL;
2218         int snum;
2219         char *oldcwd = NULL;
2220         struct security_descriptor *psd = NULL;
2221         uint32_t security_info_sent = 0;
2222
2223         ZERO_STRUCT(st);
2224
2225         if (!r->in.share) {
2226                 return WERR_INVALID_NAME;
2227         }
2228
2229         snum = find_service(r->in.share, servicename);
2230         if (snum == -1) {
2231                 DEBUG(10, ("Could not find service %s\n", servicename));
2232                 werr = WERR_NET_NAME_NOT_FOUND;
2233                 goto error_exit;
2234         }
2235
2236         nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2237                                        lp_pathname(snum), p->server_info,
2238                                        &oldcwd);
2239         if (!NT_STATUS_IS_OK(nt_status)) {
2240                 DEBUG(10, ("create_conn_struct failed: %s\n",
2241                            nt_errstr(nt_status)));
2242                 werr = ntstatus_to_werror(nt_status);
2243                 goto error_exit;
2244         }
2245
2246         nt_status = filename_convert(talloc_tos(),
2247                                         conn,
2248                                         false,
2249                                         r->in.file,
2250                                         0,
2251                                         NULL,
2252                                         &smb_fname);
2253         if (!NT_STATUS_IS_OK(nt_status)) {
2254                 werr = ntstatus_to_werror(nt_status);
2255                 goto error_exit;
2256         }
2257
2258         nt_status = SMB_VFS_CREATE_FILE(
2259                 conn,                                   /* conn */
2260                 NULL,                                   /* req */
2261                 0,                                      /* root_dir_fid */
2262                 smb_fname,                              /* fname */
2263                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
2264                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
2265                 FILE_OPEN,                              /* create_disposition*/
2266                 0,                                      /* create_options */
2267                 0,                                      /* file_attributes */
2268                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
2269                 0,                                      /* allocation_size */
2270                 NULL,                                   /* sd */
2271                 NULL,                                   /* ea_list */
2272                 &fsp,                                   /* result */
2273                 NULL);                                  /* pinfo */
2274
2275         if (!NT_STATUS_IS_OK(nt_status)) {
2276                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2277                          smb_fname_str_dbg(smb_fname)));
2278                 werr = ntstatus_to_werror(nt_status);
2279                 goto error_exit;
2280         }
2281
2282         psd = r->in.sd_buf->sd;
2283         security_info_sent = r->in.securityinformation;
2284
2285         if (psd->owner_sid==0) {
2286                 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2287         }
2288         if (psd->group_sid==0) {
2289                 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2290         }
2291         if (psd->sacl==0) {
2292                 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2293         }
2294         if (psd->dacl==0) {
2295                 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2296         }
2297
2298         /* Convert all the generic bits. */
2299         security_acl_map_generic(psd->dacl, &file_generic_mapping);
2300         security_acl_map_generic(psd->sacl, &file_generic_mapping);
2301
2302         nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2303                                         security_info_sent,
2304                                         psd);
2305
2306         if (!NT_STATUS_IS_OK(nt_status) ) {
2307                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2308                          "on file %s\n", r->in.share));
2309                 werr = WERR_ACCESS_DENIED;
2310                 goto error_exit;
2311         }
2312
2313         close_file(NULL, fsp, NORMAL_CLOSE);
2314         vfs_ChDir(conn, oldcwd);
2315         conn_free(conn);
2316         werr = WERR_OK;
2317         goto done;
2318
2319 error_exit:
2320
2321         if (fsp) {
2322                 close_file(NULL, fsp, NORMAL_CLOSE);
2323         }
2324
2325         if (oldcwd) {
2326                 vfs_ChDir(conn, oldcwd);
2327         }
2328
2329         if (conn) {
2330                 conn_free(conn);
2331         }
2332
2333  done:
2334         TALLOC_FREE(smb_fname);
2335
2336         return werr;
2337 }
2338
2339 /***********************************************************************************
2340  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2341  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2342  These disks would the disks listed by this function.
2343  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2344  "Nigel Williams" <nigel@veritas.com>.
2345 ***********************************************************************************/
2346
2347 static const char *server_disks[] = {"C:"};
2348
2349 static uint32 get_server_disk_count(void)
2350 {
2351         return sizeof(server_disks)/sizeof(server_disks[0]);
2352 }
2353
2354 static uint32 init_server_disk_enum(uint32 *resume)
2355 {
2356         uint32 server_disk_count = get_server_disk_count();
2357
2358         /*resume can be an offset into the list for now*/
2359
2360         if(*resume & 0x80000000)
2361                 *resume = 0;
2362
2363         if(*resume > server_disk_count)
2364                 *resume = server_disk_count;
2365
2366         return server_disk_count - *resume;
2367 }
2368
2369 static const char *next_server_disk_enum(uint32 *resume)
2370 {
2371         const char *disk;
2372
2373         if(init_server_disk_enum(resume) == 0)
2374                 return NULL;
2375
2376         disk = server_disks[*resume];
2377
2378         (*resume)++;
2379
2380         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2381
2382         return disk;
2383 }
2384
2385 /********************************************************************
2386  _srvsvc_NetDiskEnum
2387 ********************************************************************/
2388
2389 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2390                            struct srvsvc_NetDiskEnum *r)
2391 {
2392         uint32 i;
2393         const char *disk_name;
2394         TALLOC_CTX *ctx = p->mem_ctx;
2395         WERROR werr;
2396         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2397
2398         werr = WERR_OK;
2399
2400         *r->out.totalentries = init_server_disk_enum(&resume);
2401
2402         r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2403                                                MAX_SERVER_DISK_ENTRIES);
2404         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2405
2406         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2407
2408         r->out.info->count = 0;
2409
2410         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2411
2412                 r->out.info->count++;
2413
2414                 /*copy disk name into a unicode string*/
2415
2416                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2417                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2418         }
2419
2420         /* add a terminating null string.  Is this there if there is more data to come? */
2421
2422         r->out.info->count++;
2423
2424         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2425         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2426
2427         if (r->out.resume_handle) {
2428                 *r->out.resume_handle = resume;
2429         }
2430
2431         return werr;
2432 }
2433
2434 /********************************************************************
2435  _srvsvc_NetNameValidate
2436 ********************************************************************/
2437
2438 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2439                                struct srvsvc_NetNameValidate *r)
2440 {
2441         switch (r->in.name_type) {
2442         case 0x9:
2443                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2444                                        strlen_m(r->in.name)))
2445                 {
2446                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2447                                 r->in.name));
2448                         return WERR_INVALID_NAME;
2449                 }
2450                 break;
2451
2452         default:
2453                 return WERR_UNKNOWN_LEVEL;
2454         }
2455
2456         return WERR_OK;
2457 }
2458
2459 /*******************************************************************
2460 ********************************************************************/
2461
2462 static void enum_file_close_fn( const struct share_mode_entry *e,
2463                           const char *sharepath, const char *fname,
2464                           void *private_data )
2465 {
2466         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2467         struct srvsvc_NetFileClose *r =
2468                 (struct srvsvc_NetFileClose *)private_data;
2469         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2470
2471         if (fid != r->in.fid) {
2472                 return; /* Not this file. */
2473         }
2474
2475         if (!process_exists(e->pid) ) {
2476                 return;
2477         }
2478
2479         /* Ok - send the close message. */
2480         DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2481                 sharepath,
2482                 share_mode_str(talloc_tos(), 0, e) ));
2483
2484         share_mode_entry_to_message(msg, e);
2485
2486         r->out.result = ntstatus_to_werror(
2487                         messaging_send_buf(smbd_messaging_context(),
2488                                 e->pid, MSG_SMB_CLOSE_FILE,
2489                                 (uint8 *)msg,
2490                                 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2491 }
2492
2493 /********************************************************************
2494  Close a file given a 32-bit file id.
2495 ********************************************************************/
2496
2497 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2498 {
2499         SE_PRIV se_diskop = SE_DISK_OPERATOR;
2500         bool is_disk_op;
2501
2502         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2503
2504         is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2505
2506         if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2507                 return WERR_ACCESS_DENIED;
2508         }
2509
2510         /* enum_file_close_fn sends the close message to
2511          * the relevent smbd process. */
2512
2513         r->out.result = WERR_BADFILE;
2514         share_mode_forall( enum_file_close_fn, (void *)r);
2515         return r->out.result;
2516 }
2517
2518 /********************************************************************
2519 ********************************************************************/
2520
2521 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2522 {
2523         p->rng_fault_state = True;
2524         return WERR_NOT_SUPPORTED;
2525 }
2526
2527 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2528 {
2529         p->rng_fault_state = True;
2530         return WERR_NOT_SUPPORTED;
2531 }
2532
2533 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2534 {
2535         p->rng_fault_state = True;
2536         return WERR_NOT_SUPPORTED;
2537 }
2538
2539 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2540 {
2541         p->rng_fault_state = True;
2542         return WERR_NOT_SUPPORTED;
2543 }
2544
2545 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2546 {
2547         p->rng_fault_state = True;
2548         return WERR_NOT_SUPPORTED;
2549 }
2550
2551 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2552 {
2553         p->rng_fault_state = True;
2554         return WERR_NOT_SUPPORTED;
2555 }
2556
2557 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2558 {
2559         p->rng_fault_state = True;
2560         return WERR_NOT_SUPPORTED;
2561 }
2562
2563 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2564 {
2565         p->rng_fault_state = True;
2566         return WERR_NOT_SUPPORTED;
2567 }
2568
2569 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2570 {
2571         p->rng_fault_state = True;
2572         return WERR_NOT_SUPPORTED;
2573 }
2574
2575 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2576 {
2577         p->rng_fault_state = True;
2578         return WERR_NOT_SUPPORTED;
2579 }
2580
2581 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2582 {
2583         p->rng_fault_state = True;
2584         return WERR_NOT_SUPPORTED;
2585 }
2586
2587 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2588 {
2589         p->rng_fault_state = True;
2590         return WERR_NOT_SUPPORTED;
2591 }
2592
2593 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2594 {
2595         p->rng_fault_state = True;
2596         return WERR_NOT_SUPPORTED;
2597 }
2598
2599 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2600 {
2601         p->rng_fault_state = True;
2602         return WERR_NOT_SUPPORTED;
2603 }
2604
2605 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2606 {
2607         p->rng_fault_state = True;
2608         return WERR_NOT_SUPPORTED;
2609 }
2610
2611 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2612 {
2613         p->rng_fault_state = True;
2614         return WERR_NOT_SUPPORTED;
2615 }
2616
2617 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2618 {
2619         p->rng_fault_state = True;
2620         return WERR_NOT_SUPPORTED;
2621 }
2622
2623 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2624 {
2625         p->rng_fault_state = True;
2626         return WERR_NOT_SUPPORTED;
2627 }
2628
2629 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2630 {
2631         p->rng_fault_state = True;
2632         return WERR_NOT_SUPPORTED;
2633 }
2634
2635 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2636 {
2637         p->rng_fault_state = True;
2638         return WERR_NOT_SUPPORTED;
2639 }
2640
2641 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2642 {
2643         p->rng_fault_state = True;
2644         return WERR_NOT_SUPPORTED;
2645 }
2646
2647 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2648 {
2649         p->rng_fault_state = True;
2650         return WERR_NOT_SUPPORTED;
2651 }
2652
2653 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2654 {
2655         p->rng_fault_state = True;
2656         return WERR_NOT_SUPPORTED;
2657 }
2658
2659 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2660 {
2661         p->rng_fault_state = True;
2662         return WERR_NOT_SUPPORTED;
2663 }
2664
2665 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2666 {
2667         p->rng_fault_state = True;
2668         return WERR_NOT_SUPPORTED;
2669 }
2670
2671 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2672 {
2673         p->rng_fault_state = True;
2674         return WERR_NOT_SUPPORTED;
2675 }
2676
2677 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2678 {
2679         p->rng_fault_state = True;
2680         return WERR_NOT_SUPPORTED;
2681 }
2682
2683 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2684 {
2685         p->rng_fault_state = True;
2686         return WERR_NOT_SUPPORTED;
2687 }
2688
2689 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2690 {
2691         p->rng_fault_state = True;
2692         return WERR_NOT_SUPPORTED;
2693 }
2694
2695 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2696 {
2697         p->rng_fault_state = True;
2698         return WERR_NOT_SUPPORTED;
2699 }
2700
2701 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2702 {
2703         p->rng_fault_state = True;
2704         return WERR_NOT_SUPPORTED;
2705 }
2706
2707 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2708 {
2709         p->rng_fault_state = True;
2710         return WERR_NOT_SUPPORTED;
2711 }
2712
2713 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2714 {
2715         p->rng_fault_state = True;
2716         return WERR_NOT_SUPPORTED;
2717 }
2718
2719 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2720 {
2721         p->rng_fault_state = True;
2722         return WERR_NOT_SUPPORTED;
2723 }
2724
2725 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2726 {
2727         p->rng_fault_state = True;
2728         return WERR_NOT_SUPPORTED;
2729 }
2730