s3: rpc_server/srvsvc: count share connections in NetConnEnum
[Samba.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob8a7fc2f03f56f114ed903ab1da625776e14adeef
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.
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.
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.
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/>.
24 /* This is the implementation of the srvsvc pipe. */
26 #include "includes.h"
27 #include "system/passwd.h"
28 #include "ntdomain.h"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
34 #include "session.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
38 #include "auth.h"
39 #include "messages.h"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping;
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count {
52 TALLOC_CTX *ctx;
53 const char *username;
54 struct srvsvc_NetFileCtr3 *ctr3;
57 struct sess_file_info {
58 struct srvsvc_NetSessCtr1 *ctr;
59 struct sessionid *session_list;
60 uint32_t resume_handle;
61 uint32_t num_entries;
64 struct share_file_stat {
65 struct srvsvc_NetConnInfo1 *netconn_arr;
66 struct server_id *svrid_arr;
67 const char *in_sharepath;
68 uint32_t resp_entries;
69 uint32_t total_entries;
72 struct share_conn_stat {
73 TALLOC_CTX *ctx;
74 const char *sharename;
75 struct server_id *svrid_arr;
76 int count;
79 /*******************************************************************
80 ********************************************************************/
82 static void enum_file_fn( const struct share_mode_entry *e,
83 const char *sharepath, const char *fname,
84 void *private_data )
86 struct file_enum_count *fenum =
87 (struct file_enum_count *)private_data;
89 struct srvsvc_NetFileInfo3 *f;
90 int i = fenum->ctr3->count;
91 files_struct fsp;
92 struct byte_range_lock *brl;
93 int num_locks = 0;
94 char *fullpath = NULL;
95 uint32 permissions;
96 const char *username;
98 /* If the pid was not found delete the entry from connections.tdb */
100 if ( !process_exists(e->pid) ) {
101 return;
104 username = uidtoname(e->uid);
106 if ((fenum->username != NULL)
107 && !strequal(username, fenum->username)) {
108 return;
111 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
112 struct srvsvc_NetFileInfo3, i+1);
113 if ( !f ) {
114 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
115 return;
117 fenum->ctr3->array = f;
119 /* need to count the number of locks on a file */
121 ZERO_STRUCT( fsp );
122 fsp.file_id = e->id;
124 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
125 num_locks = brl_num_locks(brl);
126 TALLOC_FREE(brl);
129 if ( strcmp( fname, "." ) == 0 ) {
130 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
131 } else {
132 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
133 sharepath, fname );
135 if (!fullpath) {
136 return;
138 string_replace( fullpath, '/', '\\' );
140 /* mask out create (what ever that is) */
141 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
143 /* now fill in the srvsvc_NetFileInfo3 struct */
145 fenum->ctr3->array[i].fid =
146 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
147 fenum->ctr3->array[i].permissions = permissions;
148 fenum->ctr3->array[i].num_locks = num_locks;
149 fenum->ctr3->array[i].path = fullpath;
150 fenum->ctr3->array[i].user = username;
152 fenum->ctr3->count++;
155 /*******************************************************************
156 ********************************************************************/
158 static WERROR net_enum_files(TALLOC_CTX *ctx,
159 const char *username,
160 struct srvsvc_NetFileCtr3 **ctr3,
161 uint32_t resume)
163 struct file_enum_count f_enum_cnt;
165 f_enum_cnt.ctx = ctx;
166 f_enum_cnt.username = username;
167 f_enum_cnt.ctr3 = *ctr3;
169 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
171 *ctr3 = f_enum_cnt.ctr3;
173 return WERR_OK;
176 /*******************************************************************
177 Utility function to get the 'type' of a share from an snum.
178 ********************************************************************/
179 static enum srvsvc_ShareType get_share_type(int snum)
181 /* work out the share type */
182 enum srvsvc_ShareType type = STYPE_DISKTREE;
184 if (lp_printable(snum)) {
185 type = lp_administrative_share(snum)
186 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
188 if (strequal(lp_fstype(snum), "IPC")) {
189 type = lp_administrative_share(snum)
190 ? STYPE_IPC_HIDDEN : STYPE_IPC;
192 return type;
195 /*******************************************************************
196 Fill in a share info level 0 structure.
197 ********************************************************************/
199 static void init_srv_share_info_0(struct pipes_struct *p,
200 struct srvsvc_NetShareInfo0 *r, int snum)
202 r->name = lp_servicename(talloc_tos(), snum);
205 /*******************************************************************
206 Fill in a share info level 1 structure.
207 ********************************************************************/
209 static void init_srv_share_info_1(struct pipes_struct *p,
210 struct srvsvc_NetShareInfo1 *r,
211 int snum)
213 char *net_name = lp_servicename(talloc_tos(), snum);
214 char *remark = lp_comment(p->mem_ctx, snum);
216 if (remark) {
217 remark = talloc_sub_advanced(
218 p->mem_ctx, lp_servicename(talloc_tos(), snum),
219 get_current_username(), lp_path(talloc_tos(), snum),
220 p->session_info->unix_token->uid, get_current_username(),
221 "", remark);
224 r->name = net_name;
225 r->type = get_share_type(snum);
226 r->comment = remark ? remark : "";
229 /*******************************************************************
230 Fill in a share info level 2 structure.
231 ********************************************************************/
233 static void init_srv_share_info_2(struct pipes_struct *p,
234 struct srvsvc_NetShareInfo2 *r,
235 int snum)
237 char *remark = NULL;
238 char *path = NULL;
239 int max_connections = lp_max_connections(snum);
240 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
241 char *net_name = lp_servicename(talloc_tos(), snum);
243 remark = lp_comment(p->mem_ctx, snum);
244 if (remark) {
245 remark = talloc_sub_advanced(
246 p->mem_ctx, lp_servicename(talloc_tos(), snum),
247 get_current_username(), lp_path(talloc_tos(), snum),
248 p->session_info->unix_token->uid, get_current_username(),
249 "", remark);
251 path = talloc_asprintf(p->mem_ctx,
252 "C:%s", lp_path(talloc_tos(), snum));
254 if (path) {
256 * Change / to \\ so that win2k will see it as a valid path.
257 * This was added to enable use of browsing in win2k add
258 * share dialog.
261 string_replace(path, '/', '\\');
264 r->name = net_name;
265 r->type = get_share_type(snum);
266 r->comment = remark ? remark : "";
267 r->permissions = 0;
268 r->max_users = max_uses;
269 r->current_users = 0; /* computed later */
270 r->path = path ? path : "";
271 r->password = "";
274 /*******************************************************************
275 Map any generic bits to file specific bits.
276 ********************************************************************/
278 static void map_generic_share_sd_bits(struct security_descriptor *psd)
280 int i;
281 struct security_acl *ps_dacl = NULL;
283 if (!psd)
284 return;
286 ps_dacl = psd->dacl;
287 if (!ps_dacl)
288 return;
290 for (i = 0; i < ps_dacl->num_aces; i++) {
291 struct security_ace *psa = &ps_dacl->aces[i];
292 uint32 orig_mask = psa->access_mask;
294 se_map_generic(&psa->access_mask, &file_generic_mapping);
295 psa->access_mask |= orig_mask;
299 /*******************************************************************
300 Fill in a share info level 501 structure.
301 ********************************************************************/
303 static void init_srv_share_info_501(struct pipes_struct *p,
304 struct srvsvc_NetShareInfo501 *r, int snum)
306 const char *net_name = lp_servicename(talloc_tos(), snum);
307 char *remark = lp_comment(p->mem_ctx, snum);
309 if (remark) {
310 remark = talloc_sub_advanced(
311 p->mem_ctx, lp_servicename(talloc_tos(), snum),
312 get_current_username(), lp_path(talloc_tos(), snum),
313 p->session_info->unix_token->uid, get_current_username(),
314 "", remark);
317 r->name = net_name;
318 r->type = get_share_type(snum);
319 r->comment = remark ? remark : "";
322 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
323 * level 1005.
325 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
328 /*******************************************************************
329 Fill in a share info level 502 structure.
330 ********************************************************************/
332 static void init_srv_share_info_502(struct pipes_struct *p,
333 struct srvsvc_NetShareInfo502 *r, int snum)
335 const char *net_name = lp_servicename(talloc_tos(), snum);
336 char *path = NULL;
337 struct security_descriptor *sd = NULL;
338 struct sec_desc_buf *sd_buf = NULL;
339 size_t sd_size = 0;
340 TALLOC_CTX *ctx = p->mem_ctx;
341 char *remark = lp_comment(ctx, snum);
343 if (remark) {
344 remark = talloc_sub_advanced(
345 p->mem_ctx, lp_servicename(talloc_tos(), snum),
346 get_current_username(), lp_path(talloc_tos(), snum),
347 p->session_info->unix_token->uid, get_current_username(),
348 "", remark);
350 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
351 if (path) {
353 * Change / to \\ so that win2k will see it as a valid path. This was added to
354 * enable use of browsing in win2k add share dialog.
356 string_replace(path, '/', '\\');
359 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
361 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
363 r->name = net_name;
364 r->type = get_share_type(snum);
365 r->comment = remark ? remark : "";
366 r->permissions = 0;
367 r->max_users = (uint32_t)-1;
368 r->current_users = 1; /* ??? */
369 r->path = path ? path : "";
370 r->password = "";
371 r->sd_buf = *sd_buf;
374 /***************************************************************************
375 Fill in a share info level 1004 structure.
376 ***************************************************************************/
378 static void init_srv_share_info_1004(struct pipes_struct *p,
379 struct srvsvc_NetShareInfo1004 *r,
380 int snum)
382 char *remark = lp_comment(p->mem_ctx, snum);
384 if (remark) {
385 remark = talloc_sub_advanced(
386 p->mem_ctx, lp_servicename(talloc_tos(), snum),
387 get_current_username(), lp_path(talloc_tos(), snum),
388 p->session_info->unix_token->uid, get_current_username(),
389 "", remark);
392 r->comment = remark ? remark : "";
395 /***************************************************************************
396 Fill in a share info level 1005 structure.
397 ***************************************************************************/
399 static void init_srv_share_info_1005(struct pipes_struct *p,
400 struct srvsvc_NetShareInfo1005 *r,
401 int snum)
403 uint32_t dfs_flags = 0;
405 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
406 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
409 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
411 r->dfs_flags = dfs_flags;
414 /***************************************************************************
415 Fill in a share info level 1006 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1006(struct pipes_struct *p,
419 struct srvsvc_NetShareInfo1006 *r,
420 int snum)
422 r->max_users = (uint32_t)-1;
425 /***************************************************************************
426 Fill in a share info level 1007 structure.
427 ***************************************************************************/
429 static void init_srv_share_info_1007(struct pipes_struct *p,
430 struct srvsvc_NetShareInfo1007 *r,
431 int snum)
433 r->flags = 0;
434 r->alternate_directory_name = "";
437 /*******************************************************************
438 Fill in a share info level 1501 structure.
439 ********************************************************************/
441 static void init_srv_share_info_1501(struct pipes_struct *p,
442 struct sec_desc_buf **r,
443 int snum)
445 struct security_descriptor *sd;
446 struct sec_desc_buf *sd_buf = NULL;
447 size_t sd_size;
448 TALLOC_CTX *ctx = p->mem_ctx;
450 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
451 if (sd) {
452 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
455 *r = sd_buf;
458 /*******************************************************************
459 True if it ends in '$'.
460 ********************************************************************/
462 static bool is_hidden_share(int snum)
464 const char *net_name = lp_servicename(talloc_tos(), snum);
466 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
469 /*******************************************************************
470 Verify user is allowed to view share, access based enumeration
471 ********************************************************************/
472 static bool is_enumeration_allowed(struct pipes_struct *p,
473 int snum)
475 if (!lp_access_based_share_enum(snum))
476 return true;
478 return share_access_check(p->session_info->security_token,
479 lp_servicename(talloc_tos(), snum),
480 FILE_READ_DATA, NULL);
483 /****************************************************************************
484 Count an entry against the respective service.
485 ****************************************************************************/
487 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
489 union srvsvc_NetShareCtr *ctr = NULL;
490 struct srvsvc_NetShareInfo2 *info2 = NULL;
491 int share_entries = 0;
492 int i = 0;
494 ctr = (union srvsvc_NetShareCtr *) udp;
496 /* for level 2 */
497 share_entries = ctr->ctr2->count;
498 info2 = &ctr->ctr2->array[0];
500 for (i = 0; i < share_entries; i++, info2++) {
501 if (strequal(tcon->share_name, info2->name)) {
502 info2->current_users++;
503 break;
507 return 0;
510 /****************************************************************************
511 Count the entries belonging to all services in the connection db.
512 ****************************************************************************/
514 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
516 NTSTATUS status;
517 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
519 if (!NT_STATUS_IS_OK(status)) {
520 DEBUG(0,("count_connections_for_all_shares: traverse of "
521 "smbXsrv_tcon_global.tdb failed - %s\n",
522 nt_errstr(status)));
526 /*******************************************************************
527 Fill in a share info structure.
528 ********************************************************************/
530 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
531 struct srvsvc_NetShareInfoCtr *info_ctr,
532 uint32_t *resume_handle_p,
533 uint32_t *total_entries,
534 bool all_shares)
536 int num_entries = 0;
537 int alloc_entries = 0;
538 int num_services = 0;
539 int snum;
540 TALLOC_CTX *ctx = p->mem_ctx;
541 int i = 0;
542 int valid_share_count = 0;
543 bool *allowed = 0;
544 union srvsvc_NetShareCtr ctr;
545 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
547 DEBUG(5,("init_srv_share_info_ctr\n"));
549 /* Ensure all the usershares are loaded. */
550 become_root();
551 load_usershare_shares(NULL, connections_snum_used);
552 load_registry_shares();
553 num_services = lp_numservices();
554 unbecome_root();
556 allowed = talloc_zero_array(ctx, bool, num_services);
557 W_ERROR_HAVE_NO_MEMORY(allowed);
559 /* Count the number of entries. */
560 for (snum = 0; snum < num_services; snum++) {
561 if (lp_browseable(snum) && lp_snum_ok(snum) &&
562 is_enumeration_allowed(p, snum) &&
563 (all_shares || !is_hidden_share(snum)) ) {
564 DEBUG(10, ("counting service %s\n",
565 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
566 allowed[snum] = true;
567 num_entries++;
568 } else {
569 DEBUG(10, ("NOT counting service %s\n",
570 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
574 if (!num_entries || (resume_handle >= num_entries)) {
575 return WERR_OK;
578 /* Calculate alloc entries. */
579 alloc_entries = num_entries - resume_handle;
580 switch (info_ctr->level) {
581 case 0:
582 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
583 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
585 ctr.ctr0->count = alloc_entries;
586 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
587 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
589 for (snum = 0; snum < num_services; snum++) {
590 if (allowed[snum] &&
591 (resume_handle <= (i + valid_share_count++)) ) {
592 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
596 break;
598 case 1:
599 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
600 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
602 ctr.ctr1->count = alloc_entries;
603 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
604 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
606 for (snum = 0; snum < num_services; snum++) {
607 if (allowed[snum] &&
608 (resume_handle <= (i + valid_share_count++)) ) {
609 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
613 break;
615 case 2:
616 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
617 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
619 ctr.ctr2->count = alloc_entries;
620 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
621 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
623 for (snum = 0; snum < num_services; snum++) {
624 if (allowed[snum] &&
625 (resume_handle <= (i + valid_share_count++)) ) {
626 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
630 count_connections_for_all_shares(&ctr);
631 break;
633 case 501:
634 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
635 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
637 ctr.ctr501->count = alloc_entries;
638 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
639 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
641 for (snum = 0; snum < num_services; snum++) {
642 if (allowed[snum] &&
643 (resume_handle <= (i + valid_share_count++)) ) {
644 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
648 break;
650 case 502:
651 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
652 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
654 ctr.ctr502->count = alloc_entries;
655 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
656 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
658 for (snum = 0; snum < num_services; snum++) {
659 if (allowed[snum] &&
660 (resume_handle <= (i + valid_share_count++)) ) {
661 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
665 break;
667 case 1004:
668 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
669 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
671 ctr.ctr1004->count = alloc_entries;
672 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
673 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
675 for (snum = 0; snum < num_services; snum++) {
676 if (allowed[snum] &&
677 (resume_handle <= (i + valid_share_count++)) ) {
678 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
682 break;
684 case 1005:
685 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
686 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
688 ctr.ctr1005->count = alloc_entries;
689 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
690 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
692 for (snum = 0; snum < num_services; snum++) {
693 if (allowed[snum] &&
694 (resume_handle <= (i + valid_share_count++)) ) {
695 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
699 break;
701 case 1006:
702 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
703 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
705 ctr.ctr1006->count = alloc_entries;
706 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
707 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
709 for (snum = 0; snum < num_services; snum++) {
710 if (allowed[snum] &&
711 (resume_handle <= (i + valid_share_count++)) ) {
712 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
716 break;
718 case 1007:
719 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
720 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
722 ctr.ctr1007->count = alloc_entries;
723 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
724 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
726 for (snum = 0; snum < num_services; snum++) {
727 if (allowed[snum] &&
728 (resume_handle <= (i + valid_share_count++)) ) {
729 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
733 break;
735 case 1501:
736 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
737 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
739 ctr.ctr1501->count = alloc_entries;
740 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
741 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
743 for (snum = 0; snum < num_services; snum++) {
744 if (allowed[snum] &&
745 (resume_handle <= (i + valid_share_count++)) ) {
746 struct sec_desc_buf *sd_buf = NULL;
747 init_srv_share_info_1501(p, &sd_buf, snum);
748 ctr.ctr1501->array[i++] = *sd_buf;
752 break;
754 default:
755 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
756 info_ctr->level));
757 return WERR_UNKNOWN_LEVEL;
760 *total_entries = alloc_entries;
761 if (resume_handle_p) {
762 if (all_shares) {
763 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
764 } else {
765 *resume_handle_p = num_entries;
769 info_ctr->ctr = ctr;
771 return WERR_OK;
774 /*******************************************************************
775 fill in a sess info level 0 structure.
776 ********************************************************************/
778 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
779 struct srvsvc_NetSessCtr0 *ctr0,
780 uint32_t *resume_handle_p,
781 uint32_t *total_entries)
783 struct sessionid *session_list;
784 uint32_t num_entries = 0;
785 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
786 *total_entries = list_sessions(p->mem_ctx, &session_list);
788 DEBUG(5,("init_srv_sess_info_0\n"));
790 if (ctr0 == NULL) {
791 if (resume_handle_p) {
792 *resume_handle_p = 0;
794 return WERR_OK;
797 for (; resume_handle < *total_entries; resume_handle++) {
799 ctr0->array = talloc_realloc(p->mem_ctx,
800 ctr0->array,
801 struct srvsvc_NetSessInfo0,
802 num_entries+1);
803 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
805 ctr0->array[num_entries].client =
806 session_list[resume_handle].remote_machine;
808 num_entries++;
811 ctr0->count = num_entries;
813 if (resume_handle_p) {
814 if (*resume_handle_p >= *total_entries) {
815 *resume_handle_p = 0;
816 } else {
817 *resume_handle_p = resume_handle;
821 return WERR_OK;
824 /***********************************************************************
825 * find out the session on which this file is open and bump up its count
826 **********************************************************************/
828 static void count_sess_files_fn(const struct share_mode_entry *e,
829 const char *sharepath, const char *fname,
830 void *data)
832 struct sess_file_info *info = data;
833 uint32_t rh = info->resume_handle;
834 int i;
836 for (i=0; i < info->num_entries; i++) {
837 /* rh+info->num_entries is safe, as we've
838 ensured that:
839 *total_entries > resume_handle &&
840 info->num_entries = *total_entries - resume_handle;
841 inside init_srv_sess_info_1() below.
843 struct sessionid *sess = &info->session_list[rh + i];
844 if ((e->uid == sess->uid) &&
845 serverid_equal(&e->pid, &sess->pid)) {
847 info->ctr->array[i].num_open++;
848 return;
853 /*******************************************************************
854 * count the num of open files on all sessions
855 *******************************************************************/
857 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
858 struct sessionid *session_list,
859 uint32_t resume_handle,
860 uint32_t num_entries)
862 struct sess_file_info s_file_info;
864 s_file_info.ctr = ctr1;
865 s_file_info.session_list = session_list;
866 s_file_info.resume_handle = resume_handle;
867 s_file_info.num_entries = num_entries;
869 share_mode_forall(count_sess_files_fn, &s_file_info);
872 /*******************************************************************
873 fill in a sess info level 1 structure.
874 ********************************************************************/
876 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
877 struct srvsvc_NetSessCtr1 *ctr1,
878 uint32_t *resume_handle_p,
879 uint32_t *total_entries)
881 struct sessionid *session_list;
882 uint32_t num_entries = 0;
883 time_t now = time(NULL);
884 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
886 ZERO_STRUCTP(ctr1);
888 if (ctr1 == NULL) {
889 if (resume_handle_p) {
890 *resume_handle_p = 0;
892 return WERR_OK;
895 *total_entries = list_sessions(p->mem_ctx, &session_list);
897 if (resume_handle >= *total_entries) {
898 if (resume_handle_p) {
899 *resume_handle_p = 0;
901 return WERR_OK;
904 /* We know num_entries must be positive, due to
905 the check resume_handle >= *total_entries above. */
907 num_entries = *total_entries - resume_handle;
909 ctr1->array = talloc_zero_array(p->mem_ctx,
910 struct srvsvc_NetSessInfo1,
911 num_entries);
913 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
915 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
916 uint32 connect_time;
917 bool guest;
919 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
920 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
922 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
923 ctr1->array[num_entries].user = session_list[resume_handle].username;
924 ctr1->array[num_entries].num_open = 0;/* computed later */
925 ctr1->array[num_entries].time = connect_time;
926 ctr1->array[num_entries].idle_time = 0;
927 ctr1->array[num_entries].user_flags = guest;
930 ctr1->count = num_entries;
932 /* count open files on all sessions in single tdb traversal */
933 net_count_files_for_all_sess(ctr1, session_list,
934 resume_handle_p ? *resume_handle_p : 0,
935 num_entries);
937 if (resume_handle_p) {
938 if (*resume_handle_p >= *total_entries) {
939 *resume_handle_p = 0;
940 } else {
941 *resume_handle_p = resume_handle;
945 return WERR_OK;
948 /*******************************************************************
949 find the share connection on which this open exists.
950 ********************************************************************/
952 static void share_file_fn(const struct share_mode_entry *e,
953 const char *sharepath, const char *fname,
954 void *data)
956 struct share_file_stat *sfs = data;
957 uint32_t i;
958 uint32_t offset = sfs->total_entries - sfs->resp_entries;
960 if (strequal(sharepath, sfs->in_sharepath)) {
961 for (i=0; i < sfs->resp_entries; i++) {
962 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
963 sfs->netconn_arr[i].num_open ++;
964 return;
970 /*******************************************************************
971 count number of open files on given share connections.
972 ********************************************************************/
974 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
975 struct server_id *svrid_arr, char *sharepath,
976 uint32_t resp_entries, uint32_t total_entries)
978 struct share_file_stat sfs;
980 sfs.netconn_arr = arr;
981 sfs.svrid_arr = svrid_arr;
982 sfs.in_sharepath = sharepath;
983 sfs.resp_entries = resp_entries;
984 sfs.total_entries = total_entries;
986 share_mode_forall(share_file_fn, &sfs);
989 /****************************************************************************
990 process an entry from the connection db.
991 ****************************************************************************/
993 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
994 void *data)
996 struct share_conn_stat *scs = data;
998 if (!process_exists(tcon->server_id)) {
999 return 0;
1002 if (strequal(tcon->share_name, scs->sharename)) {
1003 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1004 struct server_id,
1005 scs->count + 1);
1006 if (!scs->svrid_arr) {
1007 return 0;
1010 scs->svrid_arr[scs->count] = tcon->server_id;
1011 scs->count++;
1014 return 0;
1017 /****************************************************************************
1018 Count the connections to a share. Build an array of serverid's owning these
1019 connections.
1020 ****************************************************************************/
1022 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1023 struct server_id **arr)
1025 struct share_conn_stat scs;
1026 NTSTATUS status;
1028 scs.ctx = ctx;
1029 scs.sharename = sharename;
1030 scs.svrid_arr = NULL;
1031 scs.count = 0;
1033 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 DEBUG(0,("count_share_conns: traverse of "
1037 "smbXsrv_tcon_global.tdb failed - %s\n",
1038 nt_errstr(status)));
1039 return 0;
1042 *arr = scs.svrid_arr;
1043 return scs.count;
1046 /*******************************************************************
1047 fill in a conn info level 0 structure.
1048 ********************************************************************/
1050 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1051 uint32_t *resume_handle_p,
1052 uint32_t *total_entries)
1054 uint32_t num_entries = 0;
1055 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1057 DEBUG(5,("init_srv_conn_info_0\n"));
1059 if (ctr0 == NULL) {
1060 if (resume_handle_p) {
1061 *resume_handle_p = 0;
1063 return WERR_OK;
1066 *total_entries = 1;
1068 ZERO_STRUCTP(ctr0);
1070 for (; resume_handle < *total_entries; resume_handle++) {
1072 ctr0->array = talloc_realloc(talloc_tos(),
1073 ctr0->array,
1074 struct srvsvc_NetConnInfo0,
1075 num_entries+1);
1076 if (!ctr0->array) {
1077 return WERR_NOMEM;
1080 ctr0->array[num_entries].conn_id = *total_entries;
1082 /* move on to creating next connection */
1083 num_entries++;
1086 ctr0->count = num_entries;
1087 *total_entries = num_entries;
1089 if (resume_handle_p) {
1090 if (*resume_handle_p >= *total_entries) {
1091 *resume_handle_p = 0;
1092 } else {
1093 *resume_handle_p = resume_handle;
1097 return WERR_OK;
1100 /*******************************************************************
1101 fill in a conn info level 1 structure.
1102 ********************************************************************/
1104 static WERROR init_srv_conn_info_1(const char *name,
1105 struct srvsvc_NetConnCtr1 *ctr1,
1106 uint32_t *resume_handle_p,
1107 uint32_t *total_entries)
1109 uint32_t num_entries = 0, snum = 0;
1110 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1111 char *share_name = NULL;
1112 struct server_id *svrid_arr = NULL;
1114 DEBUG(5,("init_srv_conn_info_1\n"));
1116 if (ctr1 == NULL) {
1117 if (resume_handle_p) {
1118 *resume_handle_p = 0;
1120 return WERR_OK;
1123 /* check if this is a server name or a share name */
1124 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1125 (name[1] == '\\')) {
1127 /* 'name' is a server name - this part is unimplemented */
1128 *total_entries = 1;
1129 } else {
1130 /* 'name' is a share name */
1131 snum = find_service(talloc_tos(), name, &share_name);
1133 if (!share_name) {
1134 return WERR_NOMEM;
1137 if (snum < 0) {
1138 return WERR_INVALID_NAME;
1142 * count the num of connections to this share. Also,
1143 * build a list of serverid's that own these
1144 * connections. The serverid list is used later to
1145 * identify the share connection on which an open exists.
1148 *total_entries = count_share_conns(talloc_tos(),
1149 share_name,
1150 &svrid_arr);
1153 if (resume_handle >= *total_entries) {
1154 if (resume_handle_p) {
1155 *resume_handle_p = 0;
1157 return WERR_OK;
1161 ZERO_STRUCTP(ctr1);
1163 for (; resume_handle < *total_entries; resume_handle++) {
1165 ctr1->array = talloc_realloc(talloc_tos(),
1166 ctr1->array,
1167 struct srvsvc_NetConnInfo1,
1168 num_entries+1);
1169 if (!ctr1->array) {
1170 return WERR_NOMEM;
1173 ctr1->array[num_entries].conn_id = *total_entries;
1174 ctr1->array[num_entries].conn_type = 0x3;
1175 ctr1->array[num_entries].num_open = 1;
1176 ctr1->array[num_entries].num_users = 1;
1177 ctr1->array[num_entries].conn_time = 3;
1178 ctr1->array[num_entries].user = "dummy_user";
1179 ctr1->array[num_entries].share = "IPC$";
1181 /* move on to creating next connection */
1182 num_entries++;
1185 ctr1->count = num_entries;
1186 *total_entries = num_entries;
1188 if (resume_handle_p) {
1189 *resume_handle_p = resume_handle;
1192 return WERR_OK;
1195 /*******************************************************************
1196 _srvsvc_NetFileEnum
1197 *******************************************************************/
1199 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1200 struct srvsvc_NetFileEnum *r)
1202 TALLOC_CTX *ctx = NULL;
1203 struct srvsvc_NetFileCtr3 *ctr3;
1204 uint32_t resume_hnd = 0;
1205 WERROR werr;
1207 switch (r->in.info_ctr->level) {
1208 case 3:
1209 break;
1210 default:
1211 return WERR_UNKNOWN_LEVEL;
1214 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1215 p->session_info->security_token)) {
1216 DEBUG(1, ("Enumerating files only allowed for "
1217 "administrators\n"));
1218 return WERR_ACCESS_DENIED;
1221 ctx = talloc_tos();
1222 ctr3 = r->in.info_ctr->ctr.ctr3;
1223 if (!ctr3) {
1224 werr = WERR_INVALID_PARAM;
1225 goto done;
1228 /* TODO -- Windows enumerates
1229 (b) active pipes
1230 (c) open directories and files */
1232 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1233 if (!W_ERROR_IS_OK(werr)) {
1234 goto done;
1237 *r->out.totalentries = ctr3->count;
1238 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1239 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1241 werr = WERR_OK;
1243 done:
1244 return werr;
1247 /*******************************************************************
1248 _srvsvc_NetSrvGetInfo
1249 ********************************************************************/
1251 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1252 struct srvsvc_NetSrvGetInfo *r)
1254 WERROR status = WERR_OK;
1256 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1258 if (!pipe_access_check(p)) {
1259 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1260 return WERR_ACCESS_DENIED;
1263 switch (r->in.level) {
1265 /* Technically level 102 should only be available to
1266 Administrators but there isn't anything super-secret
1267 here, as most of it is made up. */
1269 case 102: {
1270 struct srvsvc_NetSrvInfo102 *info102;
1272 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1273 if (!info102) {
1274 return WERR_NOMEM;
1277 info102->platform_id = PLATFORM_ID_NT;
1278 info102->server_name = lp_netbios_name();
1279 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1280 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1281 info102->server_type = lp_default_server_announce();
1282 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1283 MAX_SERVER_STRING_LENGTH);
1284 info102->users = 0xffffffff;
1285 info102->disc = 0xf;
1286 info102->hidden = 0;
1287 info102->announce = 240;
1288 info102->anndelta = 3000;
1289 info102->licenses = 100000;
1290 info102->userpath = "C:\\";
1292 r->out.info->info102 = info102;
1293 break;
1295 case 101: {
1296 struct srvsvc_NetSrvInfo101 *info101;
1298 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1299 if (!info101) {
1300 return WERR_NOMEM;
1303 info101->platform_id = PLATFORM_ID_NT;
1304 info101->server_name = lp_netbios_name();
1305 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1306 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1307 info101->server_type = lp_default_server_announce();
1308 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1309 MAX_SERVER_STRING_LENGTH);
1311 r->out.info->info101 = info101;
1312 break;
1314 case 100: {
1315 struct srvsvc_NetSrvInfo100 *info100;
1317 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1318 if (!info100) {
1319 return WERR_NOMEM;
1322 info100->platform_id = PLATFORM_ID_NT;
1323 info100->server_name = lp_netbios_name();
1325 r->out.info->info100 = info100;
1327 break;
1329 default:
1330 status = WERR_UNKNOWN_LEVEL;
1331 break;
1334 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1336 return status;
1339 /*******************************************************************
1340 _srvsvc_NetSrvSetInfo
1341 ********************************************************************/
1343 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1344 struct srvsvc_NetSrvSetInfo *r)
1346 WERROR status = WERR_OK;
1348 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1350 /* Set up the net server set info structure. */
1352 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1354 return status;
1357 /*******************************************************************
1358 _srvsvc_NetConnEnum
1359 ********************************************************************/
1361 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1362 struct srvsvc_NetConnEnum *r)
1364 WERROR werr;
1366 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1368 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1369 p->session_info->security_token)) {
1370 DEBUG(1, ("Enumerating connections only allowed for "
1371 "administrators\n"));
1372 return WERR_ACCESS_DENIED;
1375 switch (r->in.info_ctr->level) {
1376 case 0:
1377 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1378 r->in.resume_handle,
1379 r->out.totalentries);
1380 break;
1381 case 1:
1382 werr = init_srv_conn_info_1(r->in.path,
1383 r->in.info_ctr->ctr.ctr1,
1384 r->in.resume_handle,
1385 r->out.totalentries);
1386 break;
1387 default:
1388 return WERR_UNKNOWN_LEVEL;
1391 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1393 return werr;
1396 /*******************************************************************
1397 _srvsvc_NetSessEnum
1398 ********************************************************************/
1400 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1401 struct srvsvc_NetSessEnum *r)
1403 WERROR werr;
1405 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1407 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1408 p->session_info->security_token)) {
1409 DEBUG(1, ("Enumerating sessions only allowed for "
1410 "administrators\n"));
1411 return WERR_ACCESS_DENIED;
1414 switch (r->in.info_ctr->level) {
1415 case 0:
1416 werr = init_srv_sess_info_0(p,
1417 r->in.info_ctr->ctr.ctr0,
1418 r->in.resume_handle,
1419 r->out.totalentries);
1420 break;
1421 case 1:
1422 werr = init_srv_sess_info_1(p,
1423 r->in.info_ctr->ctr.ctr1,
1424 r->in.resume_handle,
1425 r->out.totalentries);
1426 break;
1427 default:
1428 return WERR_UNKNOWN_LEVEL;
1431 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1433 return werr;
1436 /*******************************************************************
1437 _srvsvc_NetSessDel
1438 ********************************************************************/
1440 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1441 struct srvsvc_NetSessDel *r)
1443 struct sessionid *session_list;
1444 int num_sessions, snum;
1445 const char *username;
1446 const char *machine;
1447 bool not_root = False;
1448 WERROR werr;
1450 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1452 werr = WERR_ACCESS_DENIED;
1454 /* fail out now if you are not root or not a domain admin */
1456 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1457 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1458 DOMAIN_RID_ADMINS))) {
1460 goto done;
1463 username = r->in.user;
1464 machine = r->in.client;
1466 /* strip leading backslashes if any */
1467 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1468 machine += 2;
1471 num_sessions = find_sessions(p->mem_ctx, username, machine,
1472 &session_list);
1474 for (snum = 0; snum < num_sessions; snum++) {
1476 NTSTATUS ntstat;
1478 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1479 not_root = True;
1480 become_root();
1483 ntstat = messaging_send(p->msg_ctx,
1484 session_list[snum].pid,
1485 MSG_SHUTDOWN, &data_blob_null);
1487 if (NT_STATUS_IS_OK(ntstat))
1488 werr = WERR_OK;
1490 if (not_root)
1491 unbecome_root();
1494 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1496 done:
1498 return werr;
1501 /*******************************************************************
1502 _srvsvc_NetShareEnumAll
1503 ********************************************************************/
1505 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1506 struct srvsvc_NetShareEnumAll *r)
1508 WERROR werr;
1510 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1512 if (!pipe_access_check(p)) {
1513 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1514 return WERR_ACCESS_DENIED;
1517 /* Create the list of shares for the response. */
1518 werr = init_srv_share_info_ctr(p,
1519 r->in.info_ctr,
1520 r->in.resume_handle,
1521 r->out.totalentries,
1522 true);
1524 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1526 return werr;
1529 /*******************************************************************
1530 _srvsvc_NetShareEnum
1531 ********************************************************************/
1533 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1534 struct srvsvc_NetShareEnum *r)
1536 WERROR werr;
1538 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1540 if (!pipe_access_check(p)) {
1541 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1542 return WERR_ACCESS_DENIED;
1545 /* Create the list of shares for the response. */
1546 werr = init_srv_share_info_ctr(p,
1547 r->in.info_ctr,
1548 r->in.resume_handle,
1549 r->out.totalentries,
1550 false);
1552 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1554 return werr;
1557 /*******************************************************************
1558 _srvsvc_NetShareGetInfo
1559 ********************************************************************/
1561 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1562 struct srvsvc_NetShareGetInfo *r)
1564 WERROR status = WERR_OK;
1565 char *share_name = NULL;
1566 int snum;
1567 union srvsvc_NetShareInfo *info = r->out.info;
1569 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1571 if (!r->in.share_name) {
1572 return WERR_INVALID_NAME;
1575 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1576 if (!share_name) {
1577 return WERR_NOMEM;
1579 if (snum < 0) {
1580 return WERR_INVALID_NAME;
1583 switch (r->in.level) {
1584 case 0:
1585 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1586 W_ERROR_HAVE_NO_MEMORY(info->info0);
1587 init_srv_share_info_0(p, info->info0, snum);
1588 break;
1589 case 1:
1590 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1591 W_ERROR_HAVE_NO_MEMORY(info->info1);
1592 init_srv_share_info_1(p, info->info1, snum);
1593 break;
1594 case 2:
1595 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1596 W_ERROR_HAVE_NO_MEMORY(info->info2);
1597 init_srv_share_info_2(p, info->info2, snum);
1598 info->info2->current_users =
1599 count_current_connections(info->info2->name, false);
1600 break;
1601 case 501:
1602 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1603 W_ERROR_HAVE_NO_MEMORY(info->info501);
1604 init_srv_share_info_501(p, info->info501, snum);
1605 break;
1606 case 502:
1607 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1608 W_ERROR_HAVE_NO_MEMORY(info->info502);
1609 init_srv_share_info_502(p, info->info502, snum);
1610 break;
1611 case 1004:
1612 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1613 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1614 init_srv_share_info_1004(p, info->info1004, snum);
1615 break;
1616 case 1005:
1617 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1618 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1619 init_srv_share_info_1005(p, info->info1005, snum);
1620 break;
1621 case 1006:
1622 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1623 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1624 init_srv_share_info_1006(p, info->info1006, snum);
1625 break;
1626 case 1007:
1627 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1628 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1629 init_srv_share_info_1007(p, info->info1007, snum);
1630 break;
1631 case 1501:
1632 init_srv_share_info_1501(p, &info->info1501, snum);
1633 break;
1634 default:
1635 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1636 r->in.level));
1637 status = WERR_UNKNOWN_LEVEL;
1638 break;
1641 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1643 return status;
1646 /*******************************************************************
1647 _srvsvc_NetShareSetInfo. Modify share details.
1648 ********************************************************************/
1650 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1651 struct srvsvc_NetShareSetInfo *r)
1653 char *command = NULL;
1654 char *share_name = NULL;
1655 char *comment = NULL;
1656 const char *pathname = NULL;
1657 int type;
1658 int snum;
1659 int ret;
1660 char *path = NULL;
1661 struct security_descriptor *psd = NULL;
1662 bool is_disk_op = False;
1663 const char *csc_policy = NULL;
1664 bool csc_policy_changed = false;
1665 const char *csc_policies[] = {"manual", "documents", "programs",
1666 "disable"};
1667 uint32_t client_csc_policy;
1668 int max_connections = 0;
1669 TALLOC_CTX *ctx = p->mem_ctx;
1670 union srvsvc_NetShareInfo *info = r->in.info;
1672 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1674 if (!r->in.share_name) {
1675 return WERR_INVALID_NAME;
1678 if (r->out.parm_error) {
1679 *r->out.parm_error = 0;
1682 if ( strequal(r->in.share_name,"IPC$")
1683 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1684 || strequal(r->in.share_name,"global") )
1686 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1687 "modified by a remote user.\n",
1688 r->in.share_name ));
1689 return WERR_ACCESS_DENIED;
1692 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1693 if (!share_name) {
1694 return WERR_NOMEM;
1697 /* Does this share exist ? */
1698 if (snum < 0)
1699 return WERR_NET_NAME_NOT_FOUND;
1701 /* No change to printer shares. */
1702 if (lp_printable(snum))
1703 return WERR_ACCESS_DENIED;
1705 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1707 /* fail out now if you are not root and not a disk op */
1709 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1710 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1711 "SeDiskOperatorPrivilege privilege needed to modify "
1712 "share %s\n",
1713 (unsigned int)p->session_info->unix_token->uid,
1714 share_name ));
1715 return WERR_ACCESS_DENIED;
1718 max_connections = lp_max_connections(snum);
1719 csc_policy = csc_policies[lp_csc_policy(snum)];
1721 switch (r->in.level) {
1722 case 1:
1723 pathname = lp_path(ctx, snum);
1724 comment = talloc_strdup(ctx, info->info1->comment);
1725 type = info->info1->type;
1726 psd = NULL;
1727 break;
1728 case 2:
1729 comment = talloc_strdup(ctx, info->info2->comment);
1730 pathname = info->info2->path;
1731 type = info->info2->type;
1732 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1733 0 : info->info2->max_users;
1734 psd = NULL;
1735 break;
1736 #if 0
1737 /* not supported on set but here for completeness */
1738 case 501:
1739 comment = talloc_strdup(ctx, info->info501->comment);
1740 type = info->info501->type;
1741 psd = NULL;
1742 break;
1743 #endif
1744 case 502:
1745 comment = talloc_strdup(ctx, info->info502->comment);
1746 pathname = info->info502->path;
1747 type = info->info502->type;
1748 psd = info->info502->sd_buf.sd;
1749 map_generic_share_sd_bits(psd);
1750 break;
1751 case 1004:
1752 pathname = lp_path(ctx, snum);
1753 comment = talloc_strdup(ctx, info->info1004->comment);
1754 type = STYPE_DISKTREE;
1755 break;
1756 case 1005:
1757 /* XP re-sets the csc policy even if it wasn't changed by the
1758 user, so we must compare it to see if it's what is set in
1759 smb.conf, so that we can contine other ops like setting
1760 ACLs on a share */
1761 client_csc_policy = (info->info1005->dfs_flags &
1762 SHARE_1005_CSC_POLICY_MASK) >>
1763 SHARE_1005_CSC_POLICY_SHIFT;
1765 if (client_csc_policy == lp_csc_policy(snum))
1766 return WERR_OK;
1767 else {
1768 csc_policy = csc_policies[client_csc_policy];
1769 csc_policy_changed = true;
1772 pathname = lp_path(ctx, snum);
1773 comment = lp_comment(ctx, snum);
1774 type = STYPE_DISKTREE;
1775 break;
1776 case 1006:
1777 case 1007:
1778 return WERR_ACCESS_DENIED;
1779 case 1501:
1780 pathname = lp_path(ctx, snum);
1781 comment = lp_comment(ctx, snum);
1782 psd = info->info1501->sd;
1783 map_generic_share_sd_bits(psd);
1784 type = STYPE_DISKTREE;
1785 break;
1786 default:
1787 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1788 r->in.level));
1789 return WERR_UNKNOWN_LEVEL;
1792 /* We can only modify disk shares. */
1793 if (type != STYPE_DISKTREE) {
1794 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1795 "disk share\n",
1796 share_name ));
1797 return WERR_ACCESS_DENIED;
1800 if (comment == NULL) {
1801 return WERR_NOMEM;
1804 /* Check if the pathname is valid. */
1805 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1806 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1807 pathname ));
1808 return WERR_OBJECT_PATH_INVALID;
1811 /* Ensure share name, pathname and comment don't contain '"' characters. */
1812 string_replace(share_name, '"', ' ');
1813 string_replace(path, '"', ' ');
1814 string_replace(comment, '"', ' ');
1816 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1817 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1819 /* Only call modify function if something changed. */
1821 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1822 || (lp_max_connections(snum) != max_connections)
1823 || csc_policy_changed) {
1825 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1826 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1827 return WERR_ACCESS_DENIED;
1830 command = talloc_asprintf(p->mem_ctx,
1831 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1832 lp_change_share_command(talloc_tos()),
1833 get_dyn_CONFIGFILE(),
1834 share_name,
1835 path,
1836 comment ? comment : "",
1837 max_connections,
1838 csc_policy);
1839 if (!command) {
1840 return WERR_NOMEM;
1843 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1845 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1847 if (is_disk_op)
1848 become_root();
1850 if ( (ret = smbrun(command, NULL)) == 0 ) {
1851 /* Tell everyone we updated smb.conf. */
1852 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1853 NULL, 0, NULL);
1856 if ( is_disk_op )
1857 unbecome_root();
1859 /********* END SeDiskOperatorPrivilege BLOCK *********/
1861 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1862 command, ret ));
1864 TALLOC_FREE(command);
1866 if ( ret != 0 )
1867 return WERR_ACCESS_DENIED;
1868 } else {
1869 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1870 share_name ));
1873 /* Replace SD if changed. */
1874 if (psd) {
1875 struct security_descriptor *old_sd;
1876 size_t sd_size;
1878 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1880 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1881 if (!set_share_security(share_name, psd))
1882 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1883 share_name ));
1887 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1889 return WERR_OK;
1892 /*******************************************************************
1893 _srvsvc_NetShareAdd.
1894 Call 'add_share_command "sharename" "pathname"
1895 "comment" "max connections = "
1896 ********************************************************************/
1898 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1899 struct srvsvc_NetShareAdd *r)
1901 char *command = NULL;
1902 char *share_name_in = NULL;
1903 char *share_name = NULL;
1904 char *comment = NULL;
1905 char *pathname = NULL;
1906 int type;
1907 int snum;
1908 int ret;
1909 char *path;
1910 struct security_descriptor *psd = NULL;
1911 bool is_disk_op;
1912 int max_connections = 0;
1913 TALLOC_CTX *ctx = p->mem_ctx;
1915 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1917 if (r->out.parm_error) {
1918 *r->out.parm_error = 0;
1921 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1923 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1924 return WERR_ACCESS_DENIED;
1926 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1927 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1928 return WERR_ACCESS_DENIED;
1931 switch (r->in.level) {
1932 case 0:
1933 /* No path. Not enough info in a level 0 to do anything. */
1934 return WERR_ACCESS_DENIED;
1935 case 1:
1936 /* Not enough info in a level 1 to do anything. */
1937 return WERR_ACCESS_DENIED;
1938 case 2:
1939 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1940 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1941 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1942 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1943 0 : r->in.info->info2->max_users;
1944 type = r->in.info->info2->type;
1945 break;
1946 case 501:
1947 /* No path. Not enough info in a level 501 to do anything. */
1948 return WERR_ACCESS_DENIED;
1949 case 502:
1950 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1951 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1952 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1953 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1954 0 : r->in.info->info502->max_users;
1955 type = r->in.info->info502->type;
1956 psd = r->in.info->info502->sd_buf.sd;
1957 map_generic_share_sd_bits(psd);
1958 break;
1960 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1962 case 1004:
1963 case 1005:
1964 case 1006:
1965 case 1007:
1966 return WERR_ACCESS_DENIED;
1967 case 1501:
1968 /* DFS only level. */
1969 return WERR_ACCESS_DENIED;
1970 default:
1971 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1972 r->in.level));
1973 return WERR_UNKNOWN_LEVEL;
1976 /* check for invalid share names */
1978 if (!share_name_in || !validate_net_name(share_name_in,
1979 INVALID_SHARENAME_CHARS,
1980 strlen(share_name_in))) {
1981 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1982 share_name_in ? share_name_in : ""));
1983 return WERR_INVALID_NAME;
1986 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1987 || (lp_enable_asu_support() &&
1988 strequal(share_name_in,"ADMIN$"))) {
1989 return WERR_ACCESS_DENIED;
1992 snum = find_service(ctx, share_name_in, &share_name);
1993 if (!share_name) {
1994 return WERR_NOMEM;
1997 /* Share already exists. */
1998 if (snum >= 0) {
1999 return WERR_FILE_EXISTS;
2002 /* We can only add disk shares. */
2003 if (type != STYPE_DISKTREE) {
2004 return WERR_ACCESS_DENIED;
2007 /* Check if the pathname is valid. */
2008 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2009 return WERR_OBJECT_PATH_INVALID;
2012 /* Ensure share name, pathname and comment don't contain '"' characters. */
2013 string_replace(share_name_in, '"', ' ');
2014 string_replace(share_name, '"', ' ');
2015 string_replace(path, '"', ' ');
2016 if (comment) {
2017 string_replace(comment, '"', ' ');
2020 command = talloc_asprintf(ctx,
2021 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2022 lp_add_share_command(talloc_tos()),
2023 get_dyn_CONFIGFILE(),
2024 share_name_in,
2025 path,
2026 comment ? comment : "",
2027 max_connections);
2028 if (!command) {
2029 return WERR_NOMEM;
2032 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2034 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2036 if ( is_disk_op )
2037 become_root();
2039 /* FIXME: use libnetconf here - gd */
2041 if ( (ret = smbrun(command, NULL)) == 0 ) {
2042 /* Tell everyone we updated smb.conf. */
2043 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2044 NULL);
2047 if ( is_disk_op )
2048 unbecome_root();
2050 /********* END SeDiskOperatorPrivilege BLOCK *********/
2052 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2053 command, ret ));
2055 TALLOC_FREE(command);
2057 if ( ret != 0 )
2058 return WERR_ACCESS_DENIED;
2060 if (psd) {
2061 /* Note we use share_name here, not share_name_in as
2062 we need a canonicalized name for setting security. */
2063 if (!set_share_security(share_name, psd)) {
2064 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2065 share_name ));
2070 * We don't call reload_services() here, the message will
2071 * cause this to be done before the next packet is read
2072 * from the client. JRA.
2075 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2077 return WERR_OK;
2080 /*******************************************************************
2081 _srvsvc_NetShareDel
2082 Call "delete share command" with the share name as
2083 a parameter.
2084 ********************************************************************/
2086 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2087 struct srvsvc_NetShareDel *r)
2089 char *command = NULL;
2090 char *share_name = NULL;
2091 int ret;
2092 int snum;
2093 bool is_disk_op;
2094 struct share_params *params;
2095 TALLOC_CTX *ctx = p->mem_ctx;
2097 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2099 if (!r->in.share_name) {
2100 return WERR_NET_NAME_NOT_FOUND;
2103 if ( strequal(r->in.share_name,"IPC$")
2104 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2105 || strequal(r->in.share_name,"global") )
2107 return WERR_ACCESS_DENIED;
2110 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2111 if (!share_name) {
2112 return WERR_NOMEM;
2115 if (snum < 0) {
2116 return WERR_NO_SUCH_SHARE;
2119 if (!(params = get_share_params(p->mem_ctx, share_name))) {
2120 return WERR_NO_SUCH_SHARE;
2123 /* No change to printer shares. */
2124 if (lp_printable(snum))
2125 return WERR_ACCESS_DENIED;
2127 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2129 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2130 return WERR_ACCESS_DENIED;
2132 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2133 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2134 return WERR_ACCESS_DENIED;
2137 command = talloc_asprintf(ctx,
2138 "%s \"%s\" \"%s\"",
2139 lp_delete_share_command(talloc_tos()),
2140 get_dyn_CONFIGFILE(),
2141 lp_servicename(talloc_tos(), snum));
2142 if (!command) {
2143 return WERR_NOMEM;
2146 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2148 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2150 if ( is_disk_op )
2151 become_root();
2153 if ( (ret = smbrun(command, NULL)) == 0 ) {
2154 /* Tell everyone we updated smb.conf. */
2155 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2156 NULL);
2159 if ( is_disk_op )
2160 unbecome_root();
2162 /********* END SeDiskOperatorPrivilege BLOCK *********/
2164 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2166 if ( ret != 0 )
2167 return WERR_ACCESS_DENIED;
2169 /* Delete the SD in the database. */
2170 delete_share_security(lp_servicename(talloc_tos(), params->service));
2172 lp_killservice(params->service);
2174 return WERR_OK;
2177 /*******************************************************************
2178 _srvsvc_NetShareDelSticky
2179 ********************************************************************/
2181 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2182 struct srvsvc_NetShareDelSticky *r)
2184 struct srvsvc_NetShareDel q;
2186 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2188 q.in.server_unc = r->in.server_unc;
2189 q.in.share_name = r->in.share_name;
2190 q.in.reserved = r->in.reserved;
2192 return _srvsvc_NetShareDel(p, &q);
2195 /*******************************************************************
2196 _srvsvc_NetRemoteTOD
2197 ********************************************************************/
2199 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2200 struct srvsvc_NetRemoteTOD *r)
2202 struct srvsvc_NetRemoteTODInfo *tod;
2203 struct tm *t;
2204 time_t unixdate = time(NULL);
2206 /* We do this call first as if we do it *after* the gmtime call
2207 it overwrites the pointed-to values. JRA */
2209 uint32 zone = get_time_zone(unixdate)/60;
2211 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2213 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2214 return WERR_NOMEM;
2216 *r->out.info = tod;
2218 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2220 t = gmtime(&unixdate);
2222 /* set up the */
2223 tod->elapsed = unixdate;
2224 tod->msecs = 0;
2225 tod->hours = t->tm_hour;
2226 tod->mins = t->tm_min;
2227 tod->secs = t->tm_sec;
2228 tod->hunds = 0;
2229 tod->timezone = zone;
2230 tod->tinterval = 10000;
2231 tod->day = t->tm_mday;
2232 tod->month = t->tm_mon + 1;
2233 tod->year = 1900+t->tm_year;
2234 tod->weekday = t->tm_wday;
2236 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2238 return WERR_OK;
2241 /***********************************************************************************
2242 _srvsvc_NetGetFileSecurity
2243 Win9x NT tools get security descriptor.
2244 ***********************************************************************************/
2246 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2247 struct srvsvc_NetGetFileSecurity *r)
2249 struct smb_filename *smb_fname = NULL;
2250 size_t sd_size;
2251 char *servicename = NULL;
2252 SMB_STRUCT_STAT st;
2253 NTSTATUS nt_status;
2254 WERROR werr;
2255 connection_struct *conn = NULL;
2256 struct sec_desc_buf *sd_buf = NULL;
2257 files_struct *fsp = NULL;
2258 int snum;
2259 char *oldcwd = NULL;
2261 ZERO_STRUCT(st);
2263 if (!r->in.share) {
2264 werr = WERR_NET_NAME_NOT_FOUND;
2265 goto error_exit;
2267 snum = find_service(talloc_tos(), r->in.share, &servicename);
2268 if (!servicename) {
2269 werr = WERR_NOMEM;
2270 goto error_exit;
2272 if (snum == -1) {
2273 DEBUG(10, ("Could not find service %s\n", servicename));
2274 werr = WERR_NET_NAME_NOT_FOUND;
2275 goto error_exit;
2278 nt_status = create_conn_struct_cwd(talloc_tos(),
2279 server_event_context(),
2280 server_messaging_context(),
2281 &conn,
2282 snum, lp_path(talloc_tos(), snum),
2283 p->session_info, &oldcwd);
2284 if (!NT_STATUS_IS_OK(nt_status)) {
2285 DEBUG(10, ("create_conn_struct failed: %s\n",
2286 nt_errstr(nt_status)));
2287 werr = ntstatus_to_werror(nt_status);
2288 goto error_exit;
2291 nt_status = filename_convert(talloc_tos(),
2292 conn,
2293 false,
2294 r->in.file,
2296 NULL,
2297 &smb_fname);
2298 if (!NT_STATUS_IS_OK(nt_status)) {
2299 werr = ntstatus_to_werror(nt_status);
2300 goto error_exit;
2303 nt_status = SMB_VFS_CREATE_FILE(
2304 conn, /* conn */
2305 NULL, /* req */
2306 0, /* root_dir_fid */
2307 smb_fname, /* fname */
2308 FILE_READ_ATTRIBUTES, /* access_mask */
2309 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2310 FILE_OPEN, /* create_disposition*/
2311 0, /* create_options */
2312 0, /* file_attributes */
2313 INTERNAL_OPEN_ONLY, /* oplock_request */
2314 0, /* allocation_size */
2315 0, /* private_flags */
2316 NULL, /* sd */
2317 NULL, /* ea_list */
2318 &fsp, /* result */
2319 NULL); /* pinfo */
2321 if (!NT_STATUS_IS_OK(nt_status)) {
2322 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2323 smb_fname_str_dbg(smb_fname)));
2324 werr = ntstatus_to_werror(nt_status);
2325 goto error_exit;
2328 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2329 if (!sd_buf) {
2330 werr = WERR_NOMEM;
2331 goto error_exit;
2334 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2335 (SECINFO_OWNER
2336 |SECINFO_GROUP
2337 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2339 if (!NT_STATUS_IS_OK(nt_status)) {
2340 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2341 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2342 werr = ntstatus_to_werror(nt_status);
2343 TALLOC_FREE(sd_buf);
2344 goto error_exit;
2347 if (sd_buf->sd->dacl) {
2348 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2351 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2353 sd_buf->sd_size = sd_size;
2355 *r->out.sd_buf = sd_buf;
2357 close_file(NULL, fsp, NORMAL_CLOSE);
2358 vfs_ChDir(conn, oldcwd);
2359 SMB_VFS_DISCONNECT(conn);
2360 conn_free(conn);
2361 werr = WERR_OK;
2362 goto done;
2364 error_exit:
2366 if (fsp) {
2367 close_file(NULL, fsp, NORMAL_CLOSE);
2370 if (oldcwd) {
2371 vfs_ChDir(conn, oldcwd);
2374 if (conn) {
2375 SMB_VFS_DISCONNECT(conn);
2376 conn_free(conn);
2379 done:
2381 TALLOC_FREE(smb_fname);
2383 return werr;
2386 /***********************************************************************************
2387 _srvsvc_NetSetFileSecurity
2388 Win9x NT tools set security descriptor.
2389 ***********************************************************************************/
2391 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2392 struct srvsvc_NetSetFileSecurity *r)
2394 struct smb_filename *smb_fname = NULL;
2395 char *servicename = NULL;
2396 files_struct *fsp = NULL;
2397 SMB_STRUCT_STAT st;
2398 NTSTATUS nt_status;
2399 WERROR werr;
2400 connection_struct *conn = NULL;
2401 int snum;
2402 char *oldcwd = NULL;
2403 struct security_descriptor *psd = NULL;
2404 uint32_t security_info_sent = 0;
2406 ZERO_STRUCT(st);
2408 if (!r->in.share) {
2409 werr = WERR_NET_NAME_NOT_FOUND;
2410 goto error_exit;
2413 snum = find_service(talloc_tos(), r->in.share, &servicename);
2414 if (!servicename) {
2415 werr = WERR_NOMEM;
2416 goto error_exit;
2419 if (snum == -1) {
2420 DEBUG(10, ("Could not find service %s\n", servicename));
2421 werr = WERR_NET_NAME_NOT_FOUND;
2422 goto error_exit;
2425 nt_status = create_conn_struct_cwd(talloc_tos(),
2426 server_event_context(),
2427 server_messaging_context(),
2428 &conn,
2429 snum, lp_path(talloc_tos(), snum),
2430 p->session_info, &oldcwd);
2431 if (!NT_STATUS_IS_OK(nt_status)) {
2432 DEBUG(10, ("create_conn_struct failed: %s\n",
2433 nt_errstr(nt_status)));
2434 werr = ntstatus_to_werror(nt_status);
2435 goto error_exit;
2438 nt_status = filename_convert(talloc_tos(),
2439 conn,
2440 false,
2441 r->in.file,
2443 NULL,
2444 &smb_fname);
2445 if (!NT_STATUS_IS_OK(nt_status)) {
2446 werr = ntstatus_to_werror(nt_status);
2447 goto error_exit;
2450 nt_status = SMB_VFS_CREATE_FILE(
2451 conn, /* conn */
2452 NULL, /* req */
2453 0, /* root_dir_fid */
2454 smb_fname, /* fname */
2455 FILE_WRITE_ATTRIBUTES, /* access_mask */
2456 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2457 FILE_OPEN, /* create_disposition*/
2458 0, /* create_options */
2459 0, /* file_attributes */
2460 INTERNAL_OPEN_ONLY, /* oplock_request */
2461 0, /* allocation_size */
2462 0, /* private_flags */
2463 NULL, /* sd */
2464 NULL, /* ea_list */
2465 &fsp, /* result */
2466 NULL); /* pinfo */
2468 if (!NT_STATUS_IS_OK(nt_status)) {
2469 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2470 smb_fname_str_dbg(smb_fname)));
2471 werr = ntstatus_to_werror(nt_status);
2472 goto error_exit;
2475 psd = r->in.sd_buf->sd;
2476 security_info_sent = r->in.securityinformation;
2478 nt_status = set_sd(fsp, psd, security_info_sent);
2480 if (!NT_STATUS_IS_OK(nt_status) ) {
2481 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2482 "on file %s\n", r->in.share));
2483 werr = WERR_ACCESS_DENIED;
2484 goto error_exit;
2487 close_file(NULL, fsp, NORMAL_CLOSE);
2488 vfs_ChDir(conn, oldcwd);
2489 SMB_VFS_DISCONNECT(conn);
2490 conn_free(conn);
2491 werr = WERR_OK;
2492 goto done;
2494 error_exit:
2496 if (fsp) {
2497 close_file(NULL, fsp, NORMAL_CLOSE);
2500 if (oldcwd) {
2501 vfs_ChDir(conn, oldcwd);
2504 if (conn) {
2505 SMB_VFS_DISCONNECT(conn);
2506 conn_free(conn);
2509 done:
2510 TALLOC_FREE(smb_fname);
2512 return werr;
2515 /***********************************************************************************
2516 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2517 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2518 These disks would the disks listed by this function.
2519 Users could then create shares relative to these disks. Watch out for moving these disks around.
2520 "Nigel Williams" <nigel@veritas.com>.
2521 ***********************************************************************************/
2523 static const char *server_disks[] = {"C:"};
2525 static uint32 get_server_disk_count(void)
2527 return sizeof(server_disks)/sizeof(server_disks[0]);
2530 static uint32 init_server_disk_enum(uint32 *resume)
2532 uint32 server_disk_count = get_server_disk_count();
2534 /*resume can be an offset into the list for now*/
2536 if(*resume & 0x80000000)
2537 *resume = 0;
2539 if(*resume > server_disk_count)
2540 *resume = server_disk_count;
2542 return server_disk_count - *resume;
2545 static const char *next_server_disk_enum(uint32 *resume)
2547 const char *disk;
2549 if(init_server_disk_enum(resume) == 0)
2550 return NULL;
2552 disk = server_disks[*resume];
2554 (*resume)++;
2556 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2558 return disk;
2561 /********************************************************************
2562 _srvsvc_NetDiskEnum
2563 ********************************************************************/
2565 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2566 struct srvsvc_NetDiskEnum *r)
2568 uint32 i;
2569 const char *disk_name;
2570 TALLOC_CTX *ctx = p->mem_ctx;
2571 WERROR werr;
2572 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2574 werr = WERR_OK;
2576 *r->out.totalentries = init_server_disk_enum(&resume);
2578 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2579 MAX_SERVER_DISK_ENTRIES);
2580 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2582 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2584 r->out.info->count = 0;
2586 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2588 r->out.info->count++;
2590 /*copy disk name into a unicode string*/
2592 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2593 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2596 /* add a terminating null string. Is this there if there is more data to come? */
2598 r->out.info->count++;
2600 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2601 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2603 if (r->out.resume_handle) {
2604 *r->out.resume_handle = resume;
2607 return werr;
2610 /********************************************************************
2611 _srvsvc_NetNameValidate
2612 ********************************************************************/
2614 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2615 struct srvsvc_NetNameValidate *r)
2617 switch (r->in.name_type) {
2618 case 0x9:
2619 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2620 strlen_m(r->in.name)))
2622 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2623 r->in.name));
2624 return WERR_INVALID_NAME;
2626 break;
2628 default:
2629 return WERR_UNKNOWN_LEVEL;
2632 return WERR_OK;
2635 /*******************************************************************
2636 ********************************************************************/
2638 struct enum_file_close_state {
2639 struct srvsvc_NetFileClose *r;
2640 struct messaging_context *msg_ctx;
2643 static void enum_file_close_fn( const struct share_mode_entry *e,
2644 const char *sharepath, const char *fname,
2645 void *private_data )
2647 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2648 struct enum_file_close_state *state =
2649 (struct enum_file_close_state *)private_data;
2650 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2652 if (fid != state->r->in.fid) {
2653 return; /* Not this file. */
2656 if (!process_exists(e->pid) ) {
2657 return;
2660 /* Ok - send the close message. */
2661 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2662 sharepath,
2663 share_mode_str(talloc_tos(), 0, e) ));
2665 share_mode_entry_to_message(msg, e);
2667 state->r->out.result = ntstatus_to_werror(
2668 messaging_send_buf(state->msg_ctx,
2669 e->pid, MSG_SMB_CLOSE_FILE,
2670 (uint8 *)msg, sizeof(msg)));
2673 /********************************************************************
2674 Close a file given a 32-bit file id.
2675 ********************************************************************/
2677 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2678 struct srvsvc_NetFileClose *r)
2680 struct enum_file_close_state state;
2681 bool is_disk_op;
2683 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2685 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2687 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2688 return WERR_ACCESS_DENIED;
2691 /* enum_file_close_fn sends the close message to
2692 * the relevant smbd process. */
2694 r->out.result = WERR_BADFILE;
2695 state.r = r;
2696 state.msg_ctx = p->msg_ctx;
2697 share_mode_forall(enum_file_close_fn, &state);
2698 return r->out.result;
2701 /********************************************************************
2702 ********************************************************************/
2704 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2705 struct srvsvc_NetCharDevEnum *r)
2707 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2708 return WERR_NOT_SUPPORTED;
2711 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2712 struct srvsvc_NetCharDevGetInfo *r)
2714 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2715 return WERR_NOT_SUPPORTED;
2718 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2719 struct srvsvc_NetCharDevControl *r)
2721 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2722 return WERR_NOT_SUPPORTED;
2725 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2726 struct srvsvc_NetCharDevQEnum *r)
2728 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2729 return WERR_NOT_SUPPORTED;
2732 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2733 struct srvsvc_NetCharDevQGetInfo *r)
2735 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2736 return WERR_NOT_SUPPORTED;
2739 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2740 struct srvsvc_NetCharDevQSetInfo *r)
2742 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2743 return WERR_NOT_SUPPORTED;
2746 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2747 struct srvsvc_NetCharDevQPurge *r)
2749 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2750 return WERR_NOT_SUPPORTED;
2753 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2754 struct srvsvc_NetCharDevQPurgeSelf *r)
2756 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2757 return WERR_NOT_SUPPORTED;
2760 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2761 struct srvsvc_NetFileGetInfo *r)
2763 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2764 return WERR_NOT_SUPPORTED;
2767 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2768 struct srvsvc_NetShareCheck *r)
2770 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2771 return WERR_NOT_SUPPORTED;
2774 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2775 struct srvsvc_NetServerStatisticsGet *r)
2777 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2778 return WERR_NOT_SUPPORTED;
2781 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2782 struct srvsvc_NetTransportAdd *r)
2784 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2785 return WERR_NOT_SUPPORTED;
2788 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2789 struct srvsvc_NetTransportEnum *r)
2791 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2792 return WERR_NOT_SUPPORTED;
2795 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2796 struct srvsvc_NetTransportDel *r)
2798 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2799 return WERR_NOT_SUPPORTED;
2802 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2803 struct srvsvc_NetSetServiceBits *r)
2805 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2806 return WERR_NOT_SUPPORTED;
2809 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2810 struct srvsvc_NetPathType *r)
2812 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2813 return WERR_NOT_SUPPORTED;
2816 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2817 struct srvsvc_NetPathCanonicalize *r)
2819 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2820 return WERR_NOT_SUPPORTED;
2823 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2824 struct srvsvc_NetPathCompare *r)
2826 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2827 return WERR_NOT_SUPPORTED;
2830 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2831 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2833 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2834 return WERR_NOT_SUPPORTED;
2837 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2838 struct srvsvc_NetPRNameCompare *r)
2840 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2841 return WERR_NOT_SUPPORTED;
2844 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2845 struct srvsvc_NetShareDelStart *r)
2847 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2848 return WERR_NOT_SUPPORTED;
2851 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2852 struct srvsvc_NetShareDelCommit *r)
2854 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2855 return WERR_NOT_SUPPORTED;
2858 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2859 struct srvsvc_NetServerTransportAddEx *r)
2861 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2862 return WERR_NOT_SUPPORTED;
2865 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2866 struct srvsvc_NetServerSetServiceBitsEx *r)
2868 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2869 return WERR_NOT_SUPPORTED;
2872 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2873 struct srvsvc_NETRDFSGETVERSION *r)
2875 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2876 return WERR_NOT_SUPPORTED;
2879 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2880 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2882 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2883 return WERR_NOT_SUPPORTED;
2886 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2887 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2889 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2890 return WERR_NOT_SUPPORTED;
2893 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2894 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2896 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2897 return WERR_NOT_SUPPORTED;
2900 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2901 struct srvsvc_NETRDFSSETSERVERINFO *r)
2903 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2904 return WERR_NOT_SUPPORTED;
2907 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2908 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2910 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2911 return WERR_NOT_SUPPORTED;
2914 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2915 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2917 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2918 return WERR_NOT_SUPPORTED;
2921 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2922 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2924 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2925 return WERR_NOT_SUPPORTED;
2928 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2929 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2931 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2932 return WERR_NOT_SUPPORTED;
2935 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2936 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2938 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2939 return WERR_NOT_SUPPORTED;
2942 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2943 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2945 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2946 return WERR_NOT_SUPPORTED;