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