s3: rpc_server/srvsvc: count open files in NetConnEnum
[Samba.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob39d5e05bfec937a3f7caaea9634cda530fe22391
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 * We know num_entries must be positive, due to
1162 * the check resume_handle >= *total_entries above.
1165 num_entries = *total_entries - resume_handle;
1167 ZERO_STRUCTP(ctr1);
1169 ctr1->array = talloc_zero_array(talloc_tos(),
1170 struct srvsvc_NetConnInfo1,
1171 num_entries);
1173 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1175 for (num_entries = 0; resume_handle < *total_entries;
1176 num_entries++, resume_handle++) {
1178 ctr1->array[num_entries].conn_id = *total_entries;
1179 ctr1->array[num_entries].conn_type = 0x3;
1182 * if these are connections to a share, we are going to
1183 * compute the opens on them later. If it's for the server,
1184 * it's unimplemented.
1187 if (!share_name) {
1188 ctr1->array[num_entries].num_open = 1;
1191 ctr1->array[num_entries].num_users = 1;
1192 ctr1->array[num_entries].conn_time = 3;
1193 ctr1->array[num_entries].user = "dummy_user";
1194 ctr1->array[num_entries].share = "IPC$";
1197 /* now compute open files on the share connections */
1199 if (share_name) {
1202 * the locking tdb, which has the open files information,
1203 * does not store share name or share (service) number, but
1204 * just the share path. So, we can compute open files only
1205 * on the share path. If more than one shares are defined
1206 * on a share path, open files on all of them are included
1207 * in the count.
1209 * To have the correct behavior in case multiple shares
1210 * are defined on the same path, changes to tdb records
1211 * would be required. That would be lot more effort, so
1212 * this seems a good stopgap fix.
1215 count_share_opens(ctr1->array, svrid_arr,
1216 lp_path(talloc_tos(), snum),
1217 num_entries, *total_entries);
1221 ctr1->count = num_entries;
1222 *total_entries = num_entries;
1224 if (resume_handle_p) {
1225 *resume_handle_p = resume_handle;
1228 return WERR_OK;
1231 /*******************************************************************
1232 _srvsvc_NetFileEnum
1233 *******************************************************************/
1235 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1236 struct srvsvc_NetFileEnum *r)
1238 TALLOC_CTX *ctx = NULL;
1239 struct srvsvc_NetFileCtr3 *ctr3;
1240 uint32_t resume_hnd = 0;
1241 WERROR werr;
1243 switch (r->in.info_ctr->level) {
1244 case 3:
1245 break;
1246 default:
1247 return WERR_UNKNOWN_LEVEL;
1250 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1251 p->session_info->security_token)) {
1252 DEBUG(1, ("Enumerating files only allowed for "
1253 "administrators\n"));
1254 return WERR_ACCESS_DENIED;
1257 ctx = talloc_tos();
1258 ctr3 = r->in.info_ctr->ctr.ctr3;
1259 if (!ctr3) {
1260 werr = WERR_INVALID_PARAM;
1261 goto done;
1264 /* TODO -- Windows enumerates
1265 (b) active pipes
1266 (c) open directories and files */
1268 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1269 if (!W_ERROR_IS_OK(werr)) {
1270 goto done;
1273 *r->out.totalentries = ctr3->count;
1274 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1275 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1277 werr = WERR_OK;
1279 done:
1280 return werr;
1283 /*******************************************************************
1284 _srvsvc_NetSrvGetInfo
1285 ********************************************************************/
1287 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1288 struct srvsvc_NetSrvGetInfo *r)
1290 WERROR status = WERR_OK;
1292 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1294 if (!pipe_access_check(p)) {
1295 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1296 return WERR_ACCESS_DENIED;
1299 switch (r->in.level) {
1301 /* Technically level 102 should only be available to
1302 Administrators but there isn't anything super-secret
1303 here, as most of it is made up. */
1305 case 102: {
1306 struct srvsvc_NetSrvInfo102 *info102;
1308 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1309 if (!info102) {
1310 return WERR_NOMEM;
1313 info102->platform_id = PLATFORM_ID_NT;
1314 info102->server_name = lp_netbios_name();
1315 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1316 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1317 info102->server_type = lp_default_server_announce();
1318 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1319 MAX_SERVER_STRING_LENGTH);
1320 info102->users = 0xffffffff;
1321 info102->disc = 0xf;
1322 info102->hidden = 0;
1323 info102->announce = 240;
1324 info102->anndelta = 3000;
1325 info102->licenses = 100000;
1326 info102->userpath = "C:\\";
1328 r->out.info->info102 = info102;
1329 break;
1331 case 101: {
1332 struct srvsvc_NetSrvInfo101 *info101;
1334 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1335 if (!info101) {
1336 return WERR_NOMEM;
1339 info101->platform_id = PLATFORM_ID_NT;
1340 info101->server_name = lp_netbios_name();
1341 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1342 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1343 info101->server_type = lp_default_server_announce();
1344 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1345 MAX_SERVER_STRING_LENGTH);
1347 r->out.info->info101 = info101;
1348 break;
1350 case 100: {
1351 struct srvsvc_NetSrvInfo100 *info100;
1353 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1354 if (!info100) {
1355 return WERR_NOMEM;
1358 info100->platform_id = PLATFORM_ID_NT;
1359 info100->server_name = lp_netbios_name();
1361 r->out.info->info100 = info100;
1363 break;
1365 default:
1366 status = WERR_UNKNOWN_LEVEL;
1367 break;
1370 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1372 return status;
1375 /*******************************************************************
1376 _srvsvc_NetSrvSetInfo
1377 ********************************************************************/
1379 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1380 struct srvsvc_NetSrvSetInfo *r)
1382 WERROR status = WERR_OK;
1384 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1386 /* Set up the net server set info structure. */
1388 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1390 return status;
1393 /*******************************************************************
1394 _srvsvc_NetConnEnum
1395 ********************************************************************/
1397 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1398 struct srvsvc_NetConnEnum *r)
1400 WERROR werr;
1402 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1404 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1405 p->session_info->security_token)) {
1406 DEBUG(1, ("Enumerating connections only allowed for "
1407 "administrators\n"));
1408 return WERR_ACCESS_DENIED;
1411 switch (r->in.info_ctr->level) {
1412 case 0:
1413 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1414 r->in.resume_handle,
1415 r->out.totalentries);
1416 break;
1417 case 1:
1418 werr = init_srv_conn_info_1(r->in.path,
1419 r->in.info_ctr->ctr.ctr1,
1420 r->in.resume_handle,
1421 r->out.totalentries);
1422 break;
1423 default:
1424 return WERR_UNKNOWN_LEVEL;
1427 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1429 return werr;
1432 /*******************************************************************
1433 _srvsvc_NetSessEnum
1434 ********************************************************************/
1436 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1437 struct srvsvc_NetSessEnum *r)
1439 WERROR werr;
1441 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1443 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1444 p->session_info->security_token)) {
1445 DEBUG(1, ("Enumerating sessions only allowed for "
1446 "administrators\n"));
1447 return WERR_ACCESS_DENIED;
1450 switch (r->in.info_ctr->level) {
1451 case 0:
1452 werr = init_srv_sess_info_0(p,
1453 r->in.info_ctr->ctr.ctr0,
1454 r->in.resume_handle,
1455 r->out.totalentries);
1456 break;
1457 case 1:
1458 werr = init_srv_sess_info_1(p,
1459 r->in.info_ctr->ctr.ctr1,
1460 r->in.resume_handle,
1461 r->out.totalentries);
1462 break;
1463 default:
1464 return WERR_UNKNOWN_LEVEL;
1467 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1469 return werr;
1472 /*******************************************************************
1473 _srvsvc_NetSessDel
1474 ********************************************************************/
1476 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1477 struct srvsvc_NetSessDel *r)
1479 struct sessionid *session_list;
1480 int num_sessions, snum;
1481 const char *username;
1482 const char *machine;
1483 bool not_root = False;
1484 WERROR werr;
1486 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1488 werr = WERR_ACCESS_DENIED;
1490 /* fail out now if you are not root or not a domain admin */
1492 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1493 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1494 DOMAIN_RID_ADMINS))) {
1496 goto done;
1499 username = r->in.user;
1500 machine = r->in.client;
1502 /* strip leading backslashes if any */
1503 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1504 machine += 2;
1507 num_sessions = find_sessions(p->mem_ctx, username, machine,
1508 &session_list);
1510 for (snum = 0; snum < num_sessions; snum++) {
1512 NTSTATUS ntstat;
1514 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1515 not_root = True;
1516 become_root();
1519 ntstat = messaging_send(p->msg_ctx,
1520 session_list[snum].pid,
1521 MSG_SHUTDOWN, &data_blob_null);
1523 if (NT_STATUS_IS_OK(ntstat))
1524 werr = WERR_OK;
1526 if (not_root)
1527 unbecome_root();
1530 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1532 done:
1534 return werr;
1537 /*******************************************************************
1538 _srvsvc_NetShareEnumAll
1539 ********************************************************************/
1541 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1542 struct srvsvc_NetShareEnumAll *r)
1544 WERROR werr;
1546 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1548 if (!pipe_access_check(p)) {
1549 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1550 return WERR_ACCESS_DENIED;
1553 /* Create the list of shares for the response. */
1554 werr = init_srv_share_info_ctr(p,
1555 r->in.info_ctr,
1556 r->in.resume_handle,
1557 r->out.totalentries,
1558 true);
1560 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1562 return werr;
1565 /*******************************************************************
1566 _srvsvc_NetShareEnum
1567 ********************************************************************/
1569 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1570 struct srvsvc_NetShareEnum *r)
1572 WERROR werr;
1574 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1576 if (!pipe_access_check(p)) {
1577 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1578 return WERR_ACCESS_DENIED;
1581 /* Create the list of shares for the response. */
1582 werr = init_srv_share_info_ctr(p,
1583 r->in.info_ctr,
1584 r->in.resume_handle,
1585 r->out.totalentries,
1586 false);
1588 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1590 return werr;
1593 /*******************************************************************
1594 _srvsvc_NetShareGetInfo
1595 ********************************************************************/
1597 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1598 struct srvsvc_NetShareGetInfo *r)
1600 WERROR status = WERR_OK;
1601 char *share_name = NULL;
1602 int snum;
1603 union srvsvc_NetShareInfo *info = r->out.info;
1605 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1607 if (!r->in.share_name) {
1608 return WERR_INVALID_NAME;
1611 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1612 if (!share_name) {
1613 return WERR_NOMEM;
1615 if (snum < 0) {
1616 return WERR_INVALID_NAME;
1619 switch (r->in.level) {
1620 case 0:
1621 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1622 W_ERROR_HAVE_NO_MEMORY(info->info0);
1623 init_srv_share_info_0(p, info->info0, snum);
1624 break;
1625 case 1:
1626 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1627 W_ERROR_HAVE_NO_MEMORY(info->info1);
1628 init_srv_share_info_1(p, info->info1, snum);
1629 break;
1630 case 2:
1631 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1632 W_ERROR_HAVE_NO_MEMORY(info->info2);
1633 init_srv_share_info_2(p, info->info2, snum);
1634 info->info2->current_users =
1635 count_current_connections(info->info2->name, false);
1636 break;
1637 case 501:
1638 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1639 W_ERROR_HAVE_NO_MEMORY(info->info501);
1640 init_srv_share_info_501(p, info->info501, snum);
1641 break;
1642 case 502:
1643 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1644 W_ERROR_HAVE_NO_MEMORY(info->info502);
1645 init_srv_share_info_502(p, info->info502, snum);
1646 break;
1647 case 1004:
1648 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1649 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1650 init_srv_share_info_1004(p, info->info1004, snum);
1651 break;
1652 case 1005:
1653 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1654 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1655 init_srv_share_info_1005(p, info->info1005, snum);
1656 break;
1657 case 1006:
1658 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1659 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1660 init_srv_share_info_1006(p, info->info1006, snum);
1661 break;
1662 case 1007:
1663 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1664 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1665 init_srv_share_info_1007(p, info->info1007, snum);
1666 break;
1667 case 1501:
1668 init_srv_share_info_1501(p, &info->info1501, snum);
1669 break;
1670 default:
1671 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1672 r->in.level));
1673 status = WERR_UNKNOWN_LEVEL;
1674 break;
1677 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1679 return status;
1682 /*******************************************************************
1683 _srvsvc_NetShareSetInfo. Modify share details.
1684 ********************************************************************/
1686 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1687 struct srvsvc_NetShareSetInfo *r)
1689 char *command = NULL;
1690 char *share_name = NULL;
1691 char *comment = NULL;
1692 const char *pathname = NULL;
1693 int type;
1694 int snum;
1695 int ret;
1696 char *path = NULL;
1697 struct security_descriptor *psd = NULL;
1698 bool is_disk_op = False;
1699 const char *csc_policy = NULL;
1700 bool csc_policy_changed = false;
1701 const char *csc_policies[] = {"manual", "documents", "programs",
1702 "disable"};
1703 uint32_t client_csc_policy;
1704 int max_connections = 0;
1705 TALLOC_CTX *ctx = p->mem_ctx;
1706 union srvsvc_NetShareInfo *info = r->in.info;
1708 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1710 if (!r->in.share_name) {
1711 return WERR_INVALID_NAME;
1714 if (r->out.parm_error) {
1715 *r->out.parm_error = 0;
1718 if ( strequal(r->in.share_name,"IPC$")
1719 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1720 || strequal(r->in.share_name,"global") )
1722 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1723 "modified by a remote user.\n",
1724 r->in.share_name ));
1725 return WERR_ACCESS_DENIED;
1728 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1729 if (!share_name) {
1730 return WERR_NOMEM;
1733 /* Does this share exist ? */
1734 if (snum < 0)
1735 return WERR_NET_NAME_NOT_FOUND;
1737 /* No change to printer shares. */
1738 if (lp_printable(snum))
1739 return WERR_ACCESS_DENIED;
1741 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1743 /* fail out now if you are not root and not a disk op */
1745 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1746 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1747 "SeDiskOperatorPrivilege privilege needed to modify "
1748 "share %s\n",
1749 (unsigned int)p->session_info->unix_token->uid,
1750 share_name ));
1751 return WERR_ACCESS_DENIED;
1754 max_connections = lp_max_connections(snum);
1755 csc_policy = csc_policies[lp_csc_policy(snum)];
1757 switch (r->in.level) {
1758 case 1:
1759 pathname = lp_path(ctx, snum);
1760 comment = talloc_strdup(ctx, info->info1->comment);
1761 type = info->info1->type;
1762 psd = NULL;
1763 break;
1764 case 2:
1765 comment = talloc_strdup(ctx, info->info2->comment);
1766 pathname = info->info2->path;
1767 type = info->info2->type;
1768 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1769 0 : info->info2->max_users;
1770 psd = NULL;
1771 break;
1772 #if 0
1773 /* not supported on set but here for completeness */
1774 case 501:
1775 comment = talloc_strdup(ctx, info->info501->comment);
1776 type = info->info501->type;
1777 psd = NULL;
1778 break;
1779 #endif
1780 case 502:
1781 comment = talloc_strdup(ctx, info->info502->comment);
1782 pathname = info->info502->path;
1783 type = info->info502->type;
1784 psd = info->info502->sd_buf.sd;
1785 map_generic_share_sd_bits(psd);
1786 break;
1787 case 1004:
1788 pathname = lp_path(ctx, snum);
1789 comment = talloc_strdup(ctx, info->info1004->comment);
1790 type = STYPE_DISKTREE;
1791 break;
1792 case 1005:
1793 /* XP re-sets the csc policy even if it wasn't changed by the
1794 user, so we must compare it to see if it's what is set in
1795 smb.conf, so that we can contine other ops like setting
1796 ACLs on a share */
1797 client_csc_policy = (info->info1005->dfs_flags &
1798 SHARE_1005_CSC_POLICY_MASK) >>
1799 SHARE_1005_CSC_POLICY_SHIFT;
1801 if (client_csc_policy == lp_csc_policy(snum))
1802 return WERR_OK;
1803 else {
1804 csc_policy = csc_policies[client_csc_policy];
1805 csc_policy_changed = true;
1808 pathname = lp_path(ctx, snum);
1809 comment = lp_comment(ctx, snum);
1810 type = STYPE_DISKTREE;
1811 break;
1812 case 1006:
1813 case 1007:
1814 return WERR_ACCESS_DENIED;
1815 case 1501:
1816 pathname = lp_path(ctx, snum);
1817 comment = lp_comment(ctx, snum);
1818 psd = info->info1501->sd;
1819 map_generic_share_sd_bits(psd);
1820 type = STYPE_DISKTREE;
1821 break;
1822 default:
1823 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1824 r->in.level));
1825 return WERR_UNKNOWN_LEVEL;
1828 /* We can only modify disk shares. */
1829 if (type != STYPE_DISKTREE) {
1830 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1831 "disk share\n",
1832 share_name ));
1833 return WERR_ACCESS_DENIED;
1836 if (comment == NULL) {
1837 return WERR_NOMEM;
1840 /* Check if the pathname is valid. */
1841 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1842 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1843 pathname ));
1844 return WERR_OBJECT_PATH_INVALID;
1847 /* Ensure share name, pathname and comment don't contain '"' characters. */
1848 string_replace(share_name, '"', ' ');
1849 string_replace(path, '"', ' ');
1850 string_replace(comment, '"', ' ');
1852 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1853 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1855 /* Only call modify function if something changed. */
1857 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1858 || (lp_max_connections(snum) != max_connections)
1859 || csc_policy_changed) {
1861 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1862 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1863 return WERR_ACCESS_DENIED;
1866 command = talloc_asprintf(p->mem_ctx,
1867 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1868 lp_change_share_command(talloc_tos()),
1869 get_dyn_CONFIGFILE(),
1870 share_name,
1871 path,
1872 comment ? comment : "",
1873 max_connections,
1874 csc_policy);
1875 if (!command) {
1876 return WERR_NOMEM;
1879 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1881 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1883 if (is_disk_op)
1884 become_root();
1886 if ( (ret = smbrun(command, NULL)) == 0 ) {
1887 /* Tell everyone we updated smb.conf. */
1888 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1889 NULL, 0, NULL);
1892 if ( is_disk_op )
1893 unbecome_root();
1895 /********* END SeDiskOperatorPrivilege BLOCK *********/
1897 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1898 command, ret ));
1900 TALLOC_FREE(command);
1902 if ( ret != 0 )
1903 return WERR_ACCESS_DENIED;
1904 } else {
1905 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1906 share_name ));
1909 /* Replace SD if changed. */
1910 if (psd) {
1911 struct security_descriptor *old_sd;
1912 size_t sd_size;
1914 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1916 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1917 if (!set_share_security(share_name, psd))
1918 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1919 share_name ));
1923 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1925 return WERR_OK;
1928 /*******************************************************************
1929 _srvsvc_NetShareAdd.
1930 Call 'add_share_command "sharename" "pathname"
1931 "comment" "max connections = "
1932 ********************************************************************/
1934 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1935 struct srvsvc_NetShareAdd *r)
1937 char *command = NULL;
1938 char *share_name_in = NULL;
1939 char *share_name = NULL;
1940 char *comment = NULL;
1941 char *pathname = NULL;
1942 int type;
1943 int snum;
1944 int ret;
1945 char *path;
1946 struct security_descriptor *psd = NULL;
1947 bool is_disk_op;
1948 int max_connections = 0;
1949 TALLOC_CTX *ctx = p->mem_ctx;
1951 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1953 if (r->out.parm_error) {
1954 *r->out.parm_error = 0;
1957 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1959 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1960 return WERR_ACCESS_DENIED;
1962 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1963 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1964 return WERR_ACCESS_DENIED;
1967 switch (r->in.level) {
1968 case 0:
1969 /* No path. Not enough info in a level 0 to do anything. */
1970 return WERR_ACCESS_DENIED;
1971 case 1:
1972 /* Not enough info in a level 1 to do anything. */
1973 return WERR_ACCESS_DENIED;
1974 case 2:
1975 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1976 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1977 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1978 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1979 0 : r->in.info->info2->max_users;
1980 type = r->in.info->info2->type;
1981 break;
1982 case 501:
1983 /* No path. Not enough info in a level 501 to do anything. */
1984 return WERR_ACCESS_DENIED;
1985 case 502:
1986 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1987 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1988 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1989 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1990 0 : r->in.info->info502->max_users;
1991 type = r->in.info->info502->type;
1992 psd = r->in.info->info502->sd_buf.sd;
1993 map_generic_share_sd_bits(psd);
1994 break;
1996 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1998 case 1004:
1999 case 1005:
2000 case 1006:
2001 case 1007:
2002 return WERR_ACCESS_DENIED;
2003 case 1501:
2004 /* DFS only level. */
2005 return WERR_ACCESS_DENIED;
2006 default:
2007 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2008 r->in.level));
2009 return WERR_UNKNOWN_LEVEL;
2012 /* check for invalid share names */
2014 if (!share_name_in || !validate_net_name(share_name_in,
2015 INVALID_SHARENAME_CHARS,
2016 strlen(share_name_in))) {
2017 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2018 share_name_in ? share_name_in : ""));
2019 return WERR_INVALID_NAME;
2022 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2023 || (lp_enable_asu_support() &&
2024 strequal(share_name_in,"ADMIN$"))) {
2025 return WERR_ACCESS_DENIED;
2028 snum = find_service(ctx, share_name_in, &share_name);
2029 if (!share_name) {
2030 return WERR_NOMEM;
2033 /* Share already exists. */
2034 if (snum >= 0) {
2035 return WERR_FILE_EXISTS;
2038 /* We can only add disk shares. */
2039 if (type != STYPE_DISKTREE) {
2040 return WERR_ACCESS_DENIED;
2043 /* Check if the pathname is valid. */
2044 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2045 return WERR_OBJECT_PATH_INVALID;
2048 /* Ensure share name, pathname and comment don't contain '"' characters. */
2049 string_replace(share_name_in, '"', ' ');
2050 string_replace(share_name, '"', ' ');
2051 string_replace(path, '"', ' ');
2052 if (comment) {
2053 string_replace(comment, '"', ' ');
2056 command = talloc_asprintf(ctx,
2057 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2058 lp_add_share_command(talloc_tos()),
2059 get_dyn_CONFIGFILE(),
2060 share_name_in,
2061 path,
2062 comment ? comment : "",
2063 max_connections);
2064 if (!command) {
2065 return WERR_NOMEM;
2068 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2070 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2072 if ( is_disk_op )
2073 become_root();
2075 /* FIXME: use libnetconf here - gd */
2077 if ( (ret = smbrun(command, NULL)) == 0 ) {
2078 /* Tell everyone we updated smb.conf. */
2079 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2080 NULL);
2083 if ( is_disk_op )
2084 unbecome_root();
2086 /********* END SeDiskOperatorPrivilege BLOCK *********/
2088 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2089 command, ret ));
2091 TALLOC_FREE(command);
2093 if ( ret != 0 )
2094 return WERR_ACCESS_DENIED;
2096 if (psd) {
2097 /* Note we use share_name here, not share_name_in as
2098 we need a canonicalized name for setting security. */
2099 if (!set_share_security(share_name, psd)) {
2100 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2101 share_name ));
2106 * We don't call reload_services() here, the message will
2107 * cause this to be done before the next packet is read
2108 * from the client. JRA.
2111 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2113 return WERR_OK;
2116 /*******************************************************************
2117 _srvsvc_NetShareDel
2118 Call "delete share command" with the share name as
2119 a parameter.
2120 ********************************************************************/
2122 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2123 struct srvsvc_NetShareDel *r)
2125 char *command = NULL;
2126 char *share_name = NULL;
2127 int ret;
2128 int snum;
2129 bool is_disk_op;
2130 struct share_params *params;
2131 TALLOC_CTX *ctx = p->mem_ctx;
2133 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2135 if (!r->in.share_name) {
2136 return WERR_NET_NAME_NOT_FOUND;
2139 if ( strequal(r->in.share_name,"IPC$")
2140 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2141 || strequal(r->in.share_name,"global") )
2143 return WERR_ACCESS_DENIED;
2146 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2147 if (!share_name) {
2148 return WERR_NOMEM;
2151 if (snum < 0) {
2152 return WERR_NO_SUCH_SHARE;
2155 if (!(params = get_share_params(p->mem_ctx, share_name))) {
2156 return WERR_NO_SUCH_SHARE;
2159 /* No change to printer shares. */
2160 if (lp_printable(snum))
2161 return WERR_ACCESS_DENIED;
2163 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2165 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2166 return WERR_ACCESS_DENIED;
2168 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2169 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2170 return WERR_ACCESS_DENIED;
2173 command = talloc_asprintf(ctx,
2174 "%s \"%s\" \"%s\"",
2175 lp_delete_share_command(talloc_tos()),
2176 get_dyn_CONFIGFILE(),
2177 lp_servicename(talloc_tos(), snum));
2178 if (!command) {
2179 return WERR_NOMEM;
2182 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2184 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2186 if ( is_disk_op )
2187 become_root();
2189 if ( (ret = smbrun(command, NULL)) == 0 ) {
2190 /* Tell everyone we updated smb.conf. */
2191 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2192 NULL);
2195 if ( is_disk_op )
2196 unbecome_root();
2198 /********* END SeDiskOperatorPrivilege BLOCK *********/
2200 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2202 if ( ret != 0 )
2203 return WERR_ACCESS_DENIED;
2205 /* Delete the SD in the database. */
2206 delete_share_security(lp_servicename(talloc_tos(), params->service));
2208 lp_killservice(params->service);
2210 return WERR_OK;
2213 /*******************************************************************
2214 _srvsvc_NetShareDelSticky
2215 ********************************************************************/
2217 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2218 struct srvsvc_NetShareDelSticky *r)
2220 struct srvsvc_NetShareDel q;
2222 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2224 q.in.server_unc = r->in.server_unc;
2225 q.in.share_name = r->in.share_name;
2226 q.in.reserved = r->in.reserved;
2228 return _srvsvc_NetShareDel(p, &q);
2231 /*******************************************************************
2232 _srvsvc_NetRemoteTOD
2233 ********************************************************************/
2235 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2236 struct srvsvc_NetRemoteTOD *r)
2238 struct srvsvc_NetRemoteTODInfo *tod;
2239 struct tm *t;
2240 time_t unixdate = time(NULL);
2242 /* We do this call first as if we do it *after* the gmtime call
2243 it overwrites the pointed-to values. JRA */
2245 uint32 zone = get_time_zone(unixdate)/60;
2247 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2249 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2250 return WERR_NOMEM;
2252 *r->out.info = tod;
2254 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2256 t = gmtime(&unixdate);
2258 /* set up the */
2259 tod->elapsed = unixdate;
2260 tod->msecs = 0;
2261 tod->hours = t->tm_hour;
2262 tod->mins = t->tm_min;
2263 tod->secs = t->tm_sec;
2264 tod->hunds = 0;
2265 tod->timezone = zone;
2266 tod->tinterval = 10000;
2267 tod->day = t->tm_mday;
2268 tod->month = t->tm_mon + 1;
2269 tod->year = 1900+t->tm_year;
2270 tod->weekday = t->tm_wday;
2272 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2274 return WERR_OK;
2277 /***********************************************************************************
2278 _srvsvc_NetGetFileSecurity
2279 Win9x NT tools get security descriptor.
2280 ***********************************************************************************/
2282 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2283 struct srvsvc_NetGetFileSecurity *r)
2285 struct smb_filename *smb_fname = NULL;
2286 size_t sd_size;
2287 char *servicename = NULL;
2288 SMB_STRUCT_STAT st;
2289 NTSTATUS nt_status;
2290 WERROR werr;
2291 connection_struct *conn = NULL;
2292 struct sec_desc_buf *sd_buf = NULL;
2293 files_struct *fsp = NULL;
2294 int snum;
2295 char *oldcwd = NULL;
2297 ZERO_STRUCT(st);
2299 if (!r->in.share) {
2300 werr = WERR_NET_NAME_NOT_FOUND;
2301 goto error_exit;
2303 snum = find_service(talloc_tos(), r->in.share, &servicename);
2304 if (!servicename) {
2305 werr = WERR_NOMEM;
2306 goto error_exit;
2308 if (snum == -1) {
2309 DEBUG(10, ("Could not find service %s\n", servicename));
2310 werr = WERR_NET_NAME_NOT_FOUND;
2311 goto error_exit;
2314 nt_status = create_conn_struct_cwd(talloc_tos(),
2315 server_event_context(),
2316 server_messaging_context(),
2317 &conn,
2318 snum, lp_path(talloc_tos(), snum),
2319 p->session_info, &oldcwd);
2320 if (!NT_STATUS_IS_OK(nt_status)) {
2321 DEBUG(10, ("create_conn_struct failed: %s\n",
2322 nt_errstr(nt_status)));
2323 werr = ntstatus_to_werror(nt_status);
2324 goto error_exit;
2327 nt_status = filename_convert(talloc_tos(),
2328 conn,
2329 false,
2330 r->in.file,
2332 NULL,
2333 &smb_fname);
2334 if (!NT_STATUS_IS_OK(nt_status)) {
2335 werr = ntstatus_to_werror(nt_status);
2336 goto error_exit;
2339 nt_status = SMB_VFS_CREATE_FILE(
2340 conn, /* conn */
2341 NULL, /* req */
2342 0, /* root_dir_fid */
2343 smb_fname, /* fname */
2344 FILE_READ_ATTRIBUTES, /* access_mask */
2345 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2346 FILE_OPEN, /* create_disposition*/
2347 0, /* create_options */
2348 0, /* file_attributes */
2349 INTERNAL_OPEN_ONLY, /* oplock_request */
2350 0, /* allocation_size */
2351 0, /* private_flags */
2352 NULL, /* sd */
2353 NULL, /* ea_list */
2354 &fsp, /* result */
2355 NULL); /* pinfo */
2357 if (!NT_STATUS_IS_OK(nt_status)) {
2358 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2359 smb_fname_str_dbg(smb_fname)));
2360 werr = ntstatus_to_werror(nt_status);
2361 goto error_exit;
2364 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2365 if (!sd_buf) {
2366 werr = WERR_NOMEM;
2367 goto error_exit;
2370 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2371 (SECINFO_OWNER
2372 |SECINFO_GROUP
2373 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2375 if (!NT_STATUS_IS_OK(nt_status)) {
2376 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2377 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2378 werr = ntstatus_to_werror(nt_status);
2379 TALLOC_FREE(sd_buf);
2380 goto error_exit;
2383 if (sd_buf->sd->dacl) {
2384 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2387 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2389 sd_buf->sd_size = sd_size;
2391 *r->out.sd_buf = sd_buf;
2393 close_file(NULL, fsp, NORMAL_CLOSE);
2394 vfs_ChDir(conn, oldcwd);
2395 SMB_VFS_DISCONNECT(conn);
2396 conn_free(conn);
2397 werr = WERR_OK;
2398 goto done;
2400 error_exit:
2402 if (fsp) {
2403 close_file(NULL, fsp, NORMAL_CLOSE);
2406 if (oldcwd) {
2407 vfs_ChDir(conn, oldcwd);
2410 if (conn) {
2411 SMB_VFS_DISCONNECT(conn);
2412 conn_free(conn);
2415 done:
2417 TALLOC_FREE(smb_fname);
2419 return werr;
2422 /***********************************************************************************
2423 _srvsvc_NetSetFileSecurity
2424 Win9x NT tools set security descriptor.
2425 ***********************************************************************************/
2427 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2428 struct srvsvc_NetSetFileSecurity *r)
2430 struct smb_filename *smb_fname = NULL;
2431 char *servicename = NULL;
2432 files_struct *fsp = NULL;
2433 SMB_STRUCT_STAT st;
2434 NTSTATUS nt_status;
2435 WERROR werr;
2436 connection_struct *conn = NULL;
2437 int snum;
2438 char *oldcwd = NULL;
2439 struct security_descriptor *psd = NULL;
2440 uint32_t security_info_sent = 0;
2442 ZERO_STRUCT(st);
2444 if (!r->in.share) {
2445 werr = WERR_NET_NAME_NOT_FOUND;
2446 goto error_exit;
2449 snum = find_service(talloc_tos(), r->in.share, &servicename);
2450 if (!servicename) {
2451 werr = WERR_NOMEM;
2452 goto error_exit;
2455 if (snum == -1) {
2456 DEBUG(10, ("Could not find service %s\n", servicename));
2457 werr = WERR_NET_NAME_NOT_FOUND;
2458 goto error_exit;
2461 nt_status = create_conn_struct_cwd(talloc_tos(),
2462 server_event_context(),
2463 server_messaging_context(),
2464 &conn,
2465 snum, lp_path(talloc_tos(), snum),
2466 p->session_info, &oldcwd);
2467 if (!NT_STATUS_IS_OK(nt_status)) {
2468 DEBUG(10, ("create_conn_struct failed: %s\n",
2469 nt_errstr(nt_status)));
2470 werr = ntstatus_to_werror(nt_status);
2471 goto error_exit;
2474 nt_status = filename_convert(talloc_tos(),
2475 conn,
2476 false,
2477 r->in.file,
2479 NULL,
2480 &smb_fname);
2481 if (!NT_STATUS_IS_OK(nt_status)) {
2482 werr = ntstatus_to_werror(nt_status);
2483 goto error_exit;
2486 nt_status = SMB_VFS_CREATE_FILE(
2487 conn, /* conn */
2488 NULL, /* req */
2489 0, /* root_dir_fid */
2490 smb_fname, /* fname */
2491 FILE_WRITE_ATTRIBUTES, /* access_mask */
2492 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2493 FILE_OPEN, /* create_disposition*/
2494 0, /* create_options */
2495 0, /* file_attributes */
2496 INTERNAL_OPEN_ONLY, /* oplock_request */
2497 0, /* allocation_size */
2498 0, /* private_flags */
2499 NULL, /* sd */
2500 NULL, /* ea_list */
2501 &fsp, /* result */
2502 NULL); /* pinfo */
2504 if (!NT_STATUS_IS_OK(nt_status)) {
2505 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2506 smb_fname_str_dbg(smb_fname)));
2507 werr = ntstatus_to_werror(nt_status);
2508 goto error_exit;
2511 psd = r->in.sd_buf->sd;
2512 security_info_sent = r->in.securityinformation;
2514 nt_status = set_sd(fsp, psd, security_info_sent);
2516 if (!NT_STATUS_IS_OK(nt_status) ) {
2517 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2518 "on file %s\n", r->in.share));
2519 werr = WERR_ACCESS_DENIED;
2520 goto error_exit;
2523 close_file(NULL, fsp, NORMAL_CLOSE);
2524 vfs_ChDir(conn, oldcwd);
2525 SMB_VFS_DISCONNECT(conn);
2526 conn_free(conn);
2527 werr = WERR_OK;
2528 goto done;
2530 error_exit:
2532 if (fsp) {
2533 close_file(NULL, fsp, NORMAL_CLOSE);
2536 if (oldcwd) {
2537 vfs_ChDir(conn, oldcwd);
2540 if (conn) {
2541 SMB_VFS_DISCONNECT(conn);
2542 conn_free(conn);
2545 done:
2546 TALLOC_FREE(smb_fname);
2548 return werr;
2551 /***********************************************************************************
2552 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2553 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2554 These disks would the disks listed by this function.
2555 Users could then create shares relative to these disks. Watch out for moving these disks around.
2556 "Nigel Williams" <nigel@veritas.com>.
2557 ***********************************************************************************/
2559 static const char *server_disks[] = {"C:"};
2561 static uint32 get_server_disk_count(void)
2563 return sizeof(server_disks)/sizeof(server_disks[0]);
2566 static uint32 init_server_disk_enum(uint32 *resume)
2568 uint32 server_disk_count = get_server_disk_count();
2570 /*resume can be an offset into the list for now*/
2572 if(*resume & 0x80000000)
2573 *resume = 0;
2575 if(*resume > server_disk_count)
2576 *resume = server_disk_count;
2578 return server_disk_count - *resume;
2581 static const char *next_server_disk_enum(uint32 *resume)
2583 const char *disk;
2585 if(init_server_disk_enum(resume) == 0)
2586 return NULL;
2588 disk = server_disks[*resume];
2590 (*resume)++;
2592 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2594 return disk;
2597 /********************************************************************
2598 _srvsvc_NetDiskEnum
2599 ********************************************************************/
2601 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2602 struct srvsvc_NetDiskEnum *r)
2604 uint32 i;
2605 const char *disk_name;
2606 TALLOC_CTX *ctx = p->mem_ctx;
2607 WERROR werr;
2608 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2610 werr = WERR_OK;
2612 *r->out.totalentries = init_server_disk_enum(&resume);
2614 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2615 MAX_SERVER_DISK_ENTRIES);
2616 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2618 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2620 r->out.info->count = 0;
2622 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2624 r->out.info->count++;
2626 /*copy disk name into a unicode string*/
2628 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2629 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2632 /* add a terminating null string. Is this there if there is more data to come? */
2634 r->out.info->count++;
2636 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2637 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2639 if (r->out.resume_handle) {
2640 *r->out.resume_handle = resume;
2643 return werr;
2646 /********************************************************************
2647 _srvsvc_NetNameValidate
2648 ********************************************************************/
2650 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2651 struct srvsvc_NetNameValidate *r)
2653 switch (r->in.name_type) {
2654 case 0x9:
2655 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2656 strlen_m(r->in.name)))
2658 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2659 r->in.name));
2660 return WERR_INVALID_NAME;
2662 break;
2664 default:
2665 return WERR_UNKNOWN_LEVEL;
2668 return WERR_OK;
2671 /*******************************************************************
2672 ********************************************************************/
2674 struct enum_file_close_state {
2675 struct srvsvc_NetFileClose *r;
2676 struct messaging_context *msg_ctx;
2679 static void enum_file_close_fn( const struct share_mode_entry *e,
2680 const char *sharepath, const char *fname,
2681 void *private_data )
2683 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2684 struct enum_file_close_state *state =
2685 (struct enum_file_close_state *)private_data;
2686 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2688 if (fid != state->r->in.fid) {
2689 return; /* Not this file. */
2692 if (!process_exists(e->pid) ) {
2693 return;
2696 /* Ok - send the close message. */
2697 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2698 sharepath,
2699 share_mode_str(talloc_tos(), 0, e) ));
2701 share_mode_entry_to_message(msg, e);
2703 state->r->out.result = ntstatus_to_werror(
2704 messaging_send_buf(state->msg_ctx,
2705 e->pid, MSG_SMB_CLOSE_FILE,
2706 (uint8 *)msg, sizeof(msg)));
2709 /********************************************************************
2710 Close a file given a 32-bit file id.
2711 ********************************************************************/
2713 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2714 struct srvsvc_NetFileClose *r)
2716 struct enum_file_close_state state;
2717 bool is_disk_op;
2719 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2721 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2723 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2724 return WERR_ACCESS_DENIED;
2727 /* enum_file_close_fn sends the close message to
2728 * the relevant smbd process. */
2730 r->out.result = WERR_BADFILE;
2731 state.r = r;
2732 state.msg_ctx = p->msg_ctx;
2733 share_mode_forall(enum_file_close_fn, &state);
2734 return r->out.result;
2737 /********************************************************************
2738 ********************************************************************/
2740 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2741 struct srvsvc_NetCharDevEnum *r)
2743 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2744 return WERR_NOT_SUPPORTED;
2747 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2748 struct srvsvc_NetCharDevGetInfo *r)
2750 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2751 return WERR_NOT_SUPPORTED;
2754 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2755 struct srvsvc_NetCharDevControl *r)
2757 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2758 return WERR_NOT_SUPPORTED;
2761 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2762 struct srvsvc_NetCharDevQEnum *r)
2764 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2765 return WERR_NOT_SUPPORTED;
2768 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2769 struct srvsvc_NetCharDevQGetInfo *r)
2771 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2772 return WERR_NOT_SUPPORTED;
2775 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2776 struct srvsvc_NetCharDevQSetInfo *r)
2778 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2779 return WERR_NOT_SUPPORTED;
2782 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2783 struct srvsvc_NetCharDevQPurge *r)
2785 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2786 return WERR_NOT_SUPPORTED;
2789 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2790 struct srvsvc_NetCharDevQPurgeSelf *r)
2792 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2793 return WERR_NOT_SUPPORTED;
2796 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2797 struct srvsvc_NetFileGetInfo *r)
2799 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2800 return WERR_NOT_SUPPORTED;
2803 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2804 struct srvsvc_NetShareCheck *r)
2806 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2807 return WERR_NOT_SUPPORTED;
2810 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2811 struct srvsvc_NetServerStatisticsGet *r)
2813 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2814 return WERR_NOT_SUPPORTED;
2817 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2818 struct srvsvc_NetTransportAdd *r)
2820 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2821 return WERR_NOT_SUPPORTED;
2824 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2825 struct srvsvc_NetTransportEnum *r)
2827 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2828 return WERR_NOT_SUPPORTED;
2831 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2832 struct srvsvc_NetTransportDel *r)
2834 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2835 return WERR_NOT_SUPPORTED;
2838 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2839 struct srvsvc_NetSetServiceBits *r)
2841 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2842 return WERR_NOT_SUPPORTED;
2845 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2846 struct srvsvc_NetPathType *r)
2848 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2849 return WERR_NOT_SUPPORTED;
2852 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2853 struct srvsvc_NetPathCanonicalize *r)
2855 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2856 return WERR_NOT_SUPPORTED;
2859 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2860 struct srvsvc_NetPathCompare *r)
2862 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2863 return WERR_NOT_SUPPORTED;
2866 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2867 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2869 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2870 return WERR_NOT_SUPPORTED;
2873 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2874 struct srvsvc_NetPRNameCompare *r)
2876 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2877 return WERR_NOT_SUPPORTED;
2880 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2881 struct srvsvc_NetShareDelStart *r)
2883 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2884 return WERR_NOT_SUPPORTED;
2887 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2888 struct srvsvc_NetShareDelCommit *r)
2890 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2891 return WERR_NOT_SUPPORTED;
2894 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2895 struct srvsvc_NetServerTransportAddEx *r)
2897 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2898 return WERR_NOT_SUPPORTED;
2901 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2902 struct srvsvc_NetServerSetServiceBitsEx *r)
2904 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2905 return WERR_NOT_SUPPORTED;
2908 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2909 struct srvsvc_NETRDFSGETVERSION *r)
2911 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2912 return WERR_NOT_SUPPORTED;
2915 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2916 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2918 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2919 return WERR_NOT_SUPPORTED;
2922 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2923 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2925 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2926 return WERR_NOT_SUPPORTED;
2929 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2930 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2932 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2933 return WERR_NOT_SUPPORTED;
2936 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2937 struct srvsvc_NETRDFSSETSERVERINFO *r)
2939 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2940 return WERR_NOT_SUPPORTED;
2943 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2944 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2946 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2947 return WERR_NOT_SUPPORTED;
2950 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2951 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2953 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2954 return WERR_NOT_SUPPORTED;
2957 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2958 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2960 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2961 return WERR_NOT_SUPPORTED;
2964 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2965 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2967 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2968 return WERR_NOT_SUPPORTED;
2971 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2972 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2974 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2975 return WERR_NOT_SUPPORTED;
2978 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2979 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2981 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2982 return WERR_NOT_SUPPORTED;