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. */
27 #include "system/passwd.h"
28 #include "lib/util/server_id.h"
30 #include "librpc/rpc/dcesrv_core.h"
31 #include "librpc/gen_ndr/ndr_srvsvc.h"
32 #include "librpc/gen_ndr/ndr_srvsvc_scompat.h"
33 #include "librpc/gen_ndr/ndr_open_files.h"
34 #include "../libcli/security/security.h"
35 #include "../librpc/gen_ndr/ndr_security.h"
36 #include "../librpc/gen_ndr/open_files.h"
37 #include "dbwrap/dbwrap.h"
39 #include "../lib/util/util_pw.h"
40 #include "locking/share_mode_lock.h"
41 #include "smbd/smbd.h"
42 #include "smbd/globals.h"
46 #include "lib/global_contexts.h"
47 #include "source3/lib/substitute.h"
48 #include "lib/tsocket/tsocket.h"
49 #include "librpc/rpc/dcesrv_core.h"
51 extern const struct generic_mapping file_generic_mapping
;
54 #define DBGC_CLASS DBGC_RPC_SRV
56 #define MAX_SERVER_DISK_ENTRIES 15
58 /* Use for enumerating connections, pipes, & files */
60 struct file_enum_count
{
63 struct srvsvc_NetFileCtr3
*ctr3
;
67 struct sess_file_info
{
68 struct srvsvc_NetSessCtr1
*ctr
;
69 struct sessionid
*session_list
;
70 uint32_t resume_handle
;
74 struct share_file_stat
{
75 struct srvsvc_NetConnInfo1
*netconn_arr
;
76 struct server_id
*svrid_arr
;
77 const char *in_sharepath
;
78 uint32_t resp_entries
;
79 uint32_t total_entries
;
82 struct share_conn_stat
{
84 const char *sharename
;
85 struct server_id
*svrid_arr
;
89 /*******************************************************************
90 ********************************************************************/
92 static int enum_file_fn(struct file_id id
,
93 const struct share_mode_data
*d
,
94 const struct share_mode_entry
*e
,
97 struct file_enum_count
*fenum
=
98 (struct file_enum_count
*)private_data
;
99 struct srvsvc_NetFileCtr3
*ctr3
= fenum
->ctr3
;
100 struct srvsvc_NetFileInfo3
*f
;
101 struct file_id
*fids
= NULL
;
102 char *fullpath
= NULL
;
103 uint32_t permissions
;
104 const char *username
;
106 /* If the pid was not found delete the entry from connections.tdb */
108 if ( !process_exists(e
->pid
) ) {
112 username
= uidtoname(e
->uid
);
114 if ((fenum
->username
!= NULL
)
115 && !strequal(username
, fenum
->username
)) {
122 struct srvsvc_NetFileInfo3
,
125 DBG_ERR("realloc failed for %"PRIu32
" items\n", ctr3
->count
+1);
130 fids
= talloc_realloc(
131 fenum
->ctx
, fenum
->fids
, struct file_id
, ctr3
->count
+1);
133 DBG_ERR("realloc failed for %"PRIu32
" items\n", ctr3
->count
+1);
136 fids
[ctr3
->count
] = id
;
139 if ( strcmp(d
->base_name
, "." ) == 0 ) {
140 fullpath
= talloc_asprintf(
145 fullpath
= talloc_asprintf(
150 (d
->stream_name
!= NULL
) ? d
->stream_name
: "");
155 string_replace( fullpath
, '/', '\\' );
157 /* mask out create (what ever that is) */
158 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
160 /* now fill in the srvsvc_NetFileInfo3 struct */
162 ctr3
->array
[ctr3
->count
] = (struct srvsvc_NetFileInfo3
) {
163 .fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) |
165 .permissions
= permissions
,
175 /*******************************************************************
176 ********************************************************************/
178 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
179 const char *username
,
180 struct srvsvc_NetFileCtr3
**ctr3
,
183 struct file_enum_count f_enum_cnt
= {
184 .ctx
= ctx
, .username
= username
, .ctr3
= *ctr3
,
188 share_entry_forall(enum_file_fn
, (void *)&f_enum_cnt
);
190 *ctr3
= f_enum_cnt
.ctr3
;
192 /* need to count the number of locks on a file */
194 for (i
=0; i
<(*ctr3
)->count
; i
++) {
195 struct files_struct fsp
= { .file_id
= f_enum_cnt
.fids
[i
], };
196 struct byte_range_lock
*brl
= NULL
;
198 brl
= brl_get_locks(ctx
, &fsp
);
203 (*ctr3
)->array
[i
].num_locks
= brl_num_locks(brl
);
211 /*******************************************************************
212 Utility function to get the 'type' of a share from an snum.
213 ********************************************************************/
214 static enum srvsvc_ShareType
get_share_type(int snum
)
216 /* work out the share type */
217 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
219 if (lp_printable(snum
)) {
220 type
= lp_administrative_share(snum
)
221 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
223 if (strequal(lp_fstype(snum
), "IPC")) {
224 type
= lp_administrative_share(snum
)
225 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
230 /*******************************************************************
231 Fill in a share info level 0 structure.
232 ********************************************************************/
234 static void init_srv_share_info_0(struct pipes_struct
*p
,
235 struct srvsvc_NetShareInfo0
*r
, int snum
)
237 const struct loadparm_substitution
*lp_sub
=
238 loadparm_s3_global_substitution();
240 r
->name
= lp_servicename(talloc_tos(), lp_sub
, snum
);
243 /*******************************************************************
244 Fill in a share info level 1 structure.
245 ********************************************************************/
247 static void init_srv_share_info_1(struct pipes_struct
*p
,
248 struct srvsvc_NetShareInfo1
*r
,
251 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
252 struct auth_session_info
*session_info
=
253 dcesrv_call_session_info(dce_call
);
254 const struct loadparm_substitution
*lp_sub
=
255 loadparm_s3_global_substitution();
256 char *net_name
= lp_servicename(talloc_tos(), lp_sub
, snum
);
257 char *remark
= lp_comment(p
->mem_ctx
, lp_sub
, snum
);
260 remark
= talloc_sub_full(
261 p
->mem_ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
),
262 get_current_username(), lp_path(talloc_tos(), lp_sub
, snum
),
263 session_info
->unix_token
->uid
, get_current_username(),
268 r
->type
= get_share_type(snum
);
269 r
->comment
= remark
? remark
: "";
272 /*******************************************************************
273 Fill in a share info level 2 structure.
274 ********************************************************************/
276 static void init_srv_share_info_2(struct pipes_struct
*p
,
277 struct srvsvc_NetShareInfo2
*r
,
280 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
281 struct auth_session_info
*session_info
=
282 dcesrv_call_session_info(dce_call
);
283 const struct loadparm_substitution
*lp_sub
=
284 loadparm_s3_global_substitution();
287 int max_connections
= lp_max_connections(snum
);
288 uint32_t max_uses
= UINT32_MAX
;
289 char *net_name
= lp_servicename(talloc_tos(), lp_sub
, snum
);
291 if (max_connections
> 0) {
292 max_uses
= MIN(max_connections
, UINT32_MAX
);
295 remark
= lp_comment(p
->mem_ctx
, lp_sub
, snum
);
297 remark
= talloc_sub_full(
298 p
->mem_ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
),
299 get_current_username(), lp_path(talloc_tos(), lp_sub
, snum
),
300 session_info
->unix_token
->uid
, get_current_username(),
303 path
= talloc_asprintf(p
->mem_ctx
,
304 "C:%s", lp_path(talloc_tos(), lp_sub
, snum
));
308 * Change / to \\ so that win2k will see it as a valid path.
309 * This was added to enable use of browsing in win2k add
313 string_replace(path
, '/', '\\');
317 r
->type
= get_share_type(snum
);
318 r
->comment
= remark
? remark
: "";
320 r
->max_users
= max_uses
;
321 r
->current_users
= 0; /* computed later */
322 r
->path
= path
? path
: "";
326 /*******************************************************************
327 Map any generic bits to file specific bits.
328 ********************************************************************/
330 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
333 struct security_acl
*ps_dacl
= NULL
;
342 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
343 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
344 uint32_t orig_mask
= psa
->access_mask
;
346 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
347 psa
->access_mask
|= orig_mask
;
351 /*******************************************************************
352 Fill in a share info level 501 structure.
353 ********************************************************************/
355 static void init_srv_share_info_501(struct pipes_struct
*p
,
356 struct srvsvc_NetShareInfo501
*r
, int snum
)
358 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
359 struct auth_session_info
*session_info
=
360 dcesrv_call_session_info(dce_call
);
361 const struct loadparm_substitution
*lp_sub
=
362 loadparm_s3_global_substitution();
363 const char *net_name
= lp_servicename(talloc_tos(), lp_sub
, snum
);
364 char *remark
= lp_comment(p
->mem_ctx
, lp_sub
, snum
);
367 remark
= talloc_sub_full(
368 p
->mem_ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
),
369 get_current_username(), lp_path(talloc_tos(), lp_sub
, snum
),
370 session_info
->unix_token
->uid
, get_current_username(),
375 r
->type
= get_share_type(snum
);
376 r
->comment
= remark
? remark
: "";
379 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
382 r
->csc_policy
= (lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
);
385 /*******************************************************************
386 Fill in a share info level 502 structure.
387 ********************************************************************/
389 static void init_srv_share_info_502(struct pipes_struct
*p
,
390 struct srvsvc_NetShareInfo502
*r
, int snum
)
392 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
393 struct auth_session_info
*session_info
=
394 dcesrv_call_session_info(dce_call
);
395 const struct loadparm_substitution
*lp_sub
=
396 loadparm_s3_global_substitution();
397 const char *net_name
= lp_servicename(talloc_tos(), lp_sub
, snum
);
399 struct security_descriptor
*sd
= NULL
;
400 struct sec_desc_buf
*sd_buf
= NULL
;
402 TALLOC_CTX
*ctx
= p
->mem_ctx
;
403 char *remark
= lp_comment(ctx
, lp_sub
, snum
);
406 remark
= talloc_sub_full(
407 p
->mem_ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
),
408 get_current_username(), lp_path(talloc_tos(), lp_sub
, snum
),
409 session_info
->unix_token
->uid
, get_current_username(),
412 path
= talloc_asprintf(ctx
, "C:%s", lp_path(talloc_tos(), lp_sub
, snum
));
415 * Change / to \\ so that win2k will see it as a valid path. This was added to
416 * enable use of browsing in win2k add share dialog.
418 string_replace(path
, '/', '\\');
421 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
), &sd_size
);
423 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
426 r
->type
= get_share_type(snum
);
427 r
->comment
= remark
? remark
: "";
429 r
->max_users
= (uint32_t)-1;
430 r
->current_users
= 1; /* ??? */
431 r
->path
= path
? path
: "";
436 /***************************************************************************
437 Fill in a share info level 1004 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1004(struct pipes_struct
*p
,
441 struct srvsvc_NetShareInfo1004
*r
,
444 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
445 struct auth_session_info
*session_info
=
446 dcesrv_call_session_info(dce_call
);
447 const struct loadparm_substitution
*lp_sub
=
448 loadparm_s3_global_substitution();
449 char *remark
= lp_comment(p
->mem_ctx
, lp_sub
, snum
);
452 remark
= talloc_sub_full(
453 p
->mem_ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
),
454 get_current_username(), lp_path(talloc_tos(), lp_sub
, snum
),
455 session_info
->unix_token
->uid
, get_current_username(),
459 r
->comment
= remark
? remark
: "";
462 /***************************************************************************
463 Fill in a share info level 1005 structure.
464 ***************************************************************************/
466 static void init_srv_share_info_1005(struct pipes_struct
*p
,
467 struct srvsvc_NetShareInfo1005
*r
,
470 uint32_t dfs_flags
= 0;
472 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
473 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
476 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
478 r
->dfs_flags
= dfs_flags
;
481 /***************************************************************************
482 Fill in a share info level 1006 structure.
483 ***************************************************************************/
485 static void init_srv_share_info_1006(struct pipes_struct
*p
,
486 struct srvsvc_NetShareInfo1006
*r
,
489 r
->max_users
= (uint32_t)-1;
492 /***************************************************************************
493 Fill in a share info level 1007 structure.
494 ***************************************************************************/
496 static void init_srv_share_info_1007(struct pipes_struct
*p
,
497 struct srvsvc_NetShareInfo1007
*r
,
501 r
->alternate_directory_name
= "";
504 /*******************************************************************
505 Fill in a share info level 1501 structure.
506 ********************************************************************/
508 static void init_srv_share_info_1501(struct pipes_struct
*p
,
509 struct sec_desc_buf
**r
,
512 const struct loadparm_substitution
*lp_sub
=
513 loadparm_s3_global_substitution();
514 struct security_descriptor
*sd
;
515 struct sec_desc_buf
*sd_buf
= NULL
;
517 TALLOC_CTX
*ctx
= p
->mem_ctx
;
519 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
), &sd_size
);
521 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
527 /*******************************************************************
528 True if it ends in '$'.
529 ********************************************************************/
531 static bool is_hidden_share(int snum
)
533 const struct loadparm_substitution
*lp_sub
=
534 loadparm_s3_global_substitution();
535 const char *net_name
= lp_servicename(talloc_tos(), lp_sub
, snum
);
537 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
540 /*******************************************************************
541 Verify user is allowed to view share, access based enumeration
542 ********************************************************************/
543 static bool is_enumeration_allowed(struct pipes_struct
*p
,
546 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
547 struct auth_session_info
*session_info
=
548 dcesrv_call_session_info(dce_call
);
549 const struct loadparm_substitution
*lp_sub
=
550 loadparm_s3_global_substitution();
552 if (!lp_access_based_share_enum(snum
)) {
556 if (!user_ok_token(session_info
->unix_info
->unix_name
,
557 session_info
->info
->domain_name
,
558 session_info
->security_token
, snum
)) {
562 return share_access_check(session_info
->security_token
,
563 lp_servicename(talloc_tos(), lp_sub
, snum
),
564 FILE_READ_DATA
, NULL
);
567 /****************************************************************************
568 Count an entry against the respective service.
569 ****************************************************************************/
571 static int count_for_all_fn(struct smbXsrv_tcon_global0
*tcon
, void *udp
)
573 union srvsvc_NetShareCtr
*ctr
= udp
;
575 /* Only called for level2 */
576 struct srvsvc_NetShareCtr2
*ctr2
= ctr
->ctr2
;
578 uint32_t share_entries
= ctr2
->count
;
579 struct srvsvc_NetShareInfo2
*info2
= ctr2
->array
;
582 for (i
= 0; i
< share_entries
; i
++, info2
++) {
583 if (strequal(tcon
->share_name
, info2
->name
)) {
584 info2
->current_users
++;
592 /****************************************************************************
593 Count the entries belonging to all services in the connection db.
594 ****************************************************************************/
596 static void count_connections_for_all_shares(union srvsvc_NetShareCtr
*ctr
)
599 status
= smbXsrv_tcon_global_traverse(count_for_all_fn
, ctr
);
601 if (!NT_STATUS_IS_OK(status
)) {
602 DEBUG(0,("count_connections_for_all_shares: traverse of "
603 "smbXsrv_tcon_global.tdb failed - %s\n",
608 /*******************************************************************
609 Fill in a share info structure.
610 ********************************************************************/
612 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
613 struct srvsvc_NetShareInfoCtr
*info_ctr
,
614 uint32_t *resume_handle_p
,
615 uint32_t *total_entries
,
618 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
619 struct auth_session_info
*session_info
=
620 dcesrv_call_session_info(dce_call
);
621 struct dcesrv_connection
*dcesrv_conn
= dce_call
->conn
;
622 const struct tsocket_address
*local_address
=
623 dcesrv_connection_get_local_address(dcesrv_conn
);
624 const struct loadparm_substitution
*lp_sub
=
625 loadparm_s3_global_substitution();
626 uint32_t num_entries
= 0;
627 uint32_t alloc_entries
= 0;
628 int num_services
= 0;
630 TALLOC_CTX
*ctx
= p
->mem_ctx
;
632 uint32_t valid_share_count
= 0;
634 union srvsvc_NetShareCtr ctr
;
635 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
636 const char *unix_name
= session_info
->unix_info
->unix_name
;
637 int existing_home
= -1;
639 WERROR ret
= WERR_OK
;
641 DEBUG(5,("init_srv_share_info_ctr\n"));
644 * We need to make sure to reload the services for the connecting user.
645 * It is possible that we have includes with substitutions.
647 * include = /etc/samba/%U.conf
649 * We also need all printers and usershares.
651 * We need to be root in order to have access to registry shares
652 * and root only smb.conf files.
655 lp_kill_all_services();
656 lp_load_with_shares(get_dyn_CONFIGFILE());
657 delete_and_reload_printers();
658 load_usershare_shares(NULL
, connections_snum_used
);
659 load_registry_shares();
660 existing_home
= lp_servicenumber(unix_name
);
661 if (existing_home
== -1) {
662 added_home
= register_homes_share(unix_name
);
666 num_services
= lp_numservices();
668 allowed
= talloc_zero_array(ctx
, bool, num_services
);
669 if (allowed
== NULL
) {
673 /* Count the number of entries. */
674 for (snum
= 0; snum
< num_services
; snum
++) {
675 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
676 lp_allow_local_address(snum
, local_address
) &&
677 is_enumeration_allowed(p
, snum
) &&
678 (all_shares
|| !is_hidden_share(snum
))) {
679 DEBUG(10, ("counting service %s\n",
680 lp_servicename(talloc_tos(), lp_sub
, snum
) ? lp_servicename(talloc_tos(), lp_sub
, snum
) : "(null)"));
681 allowed
[snum
] = true;
684 DEBUG(10, ("NOT counting service %s\n",
685 lp_servicename(talloc_tos(), lp_sub
, snum
) ? lp_servicename(talloc_tos(), lp_sub
, snum
) : "(null)"));
689 if (!num_entries
|| (resume_handle
>= num_entries
)) {
693 /* Calculate alloc entries. */
694 alloc_entries
= num_entries
- resume_handle
;
695 switch (info_ctr
->level
) {
697 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
698 if (ctr
.ctr0
== NULL
) {
702 ctr
.ctr0
->count
= alloc_entries
;
703 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
704 if (ctr
.ctr0
->array
== NULL
) {
708 for (snum
= 0; snum
< num_services
; snum
++) {
710 (resume_handle
<= (i
+ valid_share_count
++)) ) {
711 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
718 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
719 if (ctr
.ctr1
== NULL
) {
723 ctr
.ctr1
->count
= alloc_entries
;
724 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
725 if (ctr
.ctr1
->array
== NULL
) {
729 for (snum
= 0; snum
< num_services
; snum
++) {
731 (resume_handle
<= (i
+ valid_share_count
++)) ) {
732 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
739 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
740 if (ctr
.ctr2
== NULL
) {
744 ctr
.ctr2
->count
= alloc_entries
;
745 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
746 if (ctr
.ctr2
->array
== NULL
) {
750 for (snum
= 0; snum
< num_services
; snum
++) {
752 (resume_handle
<= (i
+ valid_share_count
++)) ) {
753 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
757 count_connections_for_all_shares(&ctr
);
761 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
762 if (ctr
.ctr501
== NULL
) {
766 ctr
.ctr501
->count
= alloc_entries
;
767 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
768 if (ctr
.ctr501
->array
== NULL
) {
772 for (snum
= 0; snum
< num_services
; snum
++) {
774 (resume_handle
<= (i
+ valid_share_count
++)) ) {
775 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
782 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
783 if (ctr
.ctr502
== NULL
) {
787 ctr
.ctr502
->count
= alloc_entries
;
788 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
789 if (ctr
.ctr502
->array
== NULL
) {
793 for (snum
= 0; snum
< num_services
; snum
++) {
795 (resume_handle
<= (i
+ valid_share_count
++)) ) {
796 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
803 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
804 if (ctr
.ctr1004
== NULL
) {
808 ctr
.ctr1004
->count
= alloc_entries
;
809 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
810 if (ctr
.ctr1004
->array
== NULL
) {
814 for (snum
= 0; snum
< num_services
; snum
++) {
816 (resume_handle
<= (i
+ valid_share_count
++)) ) {
817 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
824 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
825 if (ctr
.ctr1005
== NULL
) {
829 ctr
.ctr1005
->count
= alloc_entries
;
830 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
831 if (ctr
.ctr1005
->array
== NULL
) {
835 for (snum
= 0; snum
< num_services
; snum
++) {
837 (resume_handle
<= (i
+ valid_share_count
++)) ) {
838 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
845 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
846 if (ctr
.ctr1006
== NULL
) {
850 ctr
.ctr1006
->count
= alloc_entries
;
851 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
852 if (ctr
.ctr1006
->array
== NULL
) {
856 for (snum
= 0; snum
< num_services
; snum
++) {
858 (resume_handle
<= (i
+ valid_share_count
++)) ) {
859 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
866 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
867 if (ctr
.ctr1007
== NULL
) {
871 ctr
.ctr1007
->count
= alloc_entries
;
872 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
873 if (ctr
.ctr1007
->array
== NULL
) {
877 for (snum
= 0; snum
< num_services
; snum
++) {
879 (resume_handle
<= (i
+ valid_share_count
++)) ) {
880 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
887 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
888 if (ctr
.ctr1501
== NULL
) {
892 ctr
.ctr1501
->count
= alloc_entries
;
893 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
894 if (ctr
.ctr1501
->array
== NULL
) {
898 for (snum
= 0; snum
< num_services
; snum
++) {
900 (resume_handle
<= (i
+ valid_share_count
++)) ) {
901 struct sec_desc_buf
*sd_buf
= NULL
;
902 init_srv_share_info_1501(p
, &sd_buf
, snum
);
903 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
910 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
912 ret
= WERR_INVALID_LEVEL
;
916 *total_entries
= alloc_entries
;
917 if (resume_handle_p
) {
919 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
921 *resume_handle_p
= num_entries
;
929 ret
= WERR_NOT_ENOUGH_MEMORY
;
931 if (added_home
!= -1) {
932 lp_killservice(added_home
);
937 /*******************************************************************
938 fill in a sess info level 0 structure.
939 ********************************************************************/
941 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
942 struct srvsvc_NetSessCtr0
*ctr0
,
943 uint32_t *resume_handle_p
,
944 uint32_t *total_entries
)
946 struct sessionid
*session_list
;
947 uint32_t num_entries
= 0;
948 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
949 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
951 DEBUG(5,("init_srv_sess_info_0\n"));
954 if (resume_handle_p
) {
955 *resume_handle_p
= 0;
960 for (; resume_handle
< *total_entries
; resume_handle
++) {
962 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
964 struct srvsvc_NetSessInfo0
,
966 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
968 ctr0
->array
[num_entries
].client
=
969 session_list
[resume_handle
].remote_machine
;
974 ctr0
->count
= num_entries
;
976 if (resume_handle_p
) {
977 if (*resume_handle_p
>= *total_entries
) {
978 *resume_handle_p
= 0;
980 *resume_handle_p
= resume_handle
;
987 /***********************************************************************
988 * find out the session on which this file is open and bump up its count
989 **********************************************************************/
991 static int count_sess_files_fn(struct file_id fid
,
992 const struct share_mode_data
*d
,
993 const struct share_mode_entry
*e
,
996 struct sess_file_info
*info
= data
;
997 uint32_t rh
= info
->resume_handle
;
1000 for (i
=0; i
< info
->num_entries
; i
++) {
1001 /* rh+info->num_entries is safe, as we've
1003 *total_entries > resume_handle &&
1004 info->num_entries = *total_entries - resume_handle;
1005 inside init_srv_sess_info_1() below.
1007 struct sessionid
*sess
= &info
->session_list
[rh
+ i
];
1008 if ((e
->uid
== sess
->uid
) &&
1009 server_id_equal(&e
->pid
, &sess
->pid
)) {
1011 info
->ctr
->array
[i
].num_open
++;
1018 /*******************************************************************
1019 * count the num of open files on all sessions
1020 *******************************************************************/
1022 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1
*ctr1
,
1023 struct sessionid
*session_list
,
1024 uint32_t resume_handle
,
1025 uint32_t num_entries
)
1027 struct sess_file_info s_file_info
;
1029 s_file_info
.ctr
= ctr1
;
1030 s_file_info
.session_list
= session_list
;
1031 s_file_info
.resume_handle
= resume_handle
;
1032 s_file_info
.num_entries
= num_entries
;
1034 share_entry_forall(count_sess_files_fn
, &s_file_info
);
1037 /*******************************************************************
1038 fill in a sess info level 1 structure.
1039 ********************************************************************/
1041 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
1042 struct srvsvc_NetSessCtr1
*ctr1
,
1043 uint32_t *resume_handle_p
,
1044 uint32_t *total_entries
)
1046 struct sessionid
*session_list
;
1047 uint32_t num_entries
= 0;
1048 time_t now
= time(NULL
);
1049 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1054 if (resume_handle_p
) {
1055 *resume_handle_p
= 0;
1060 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
1062 if (resume_handle
>= *total_entries
) {
1063 if (resume_handle_p
) {
1064 *resume_handle_p
= 0;
1069 /* We know num_entries must be positive, due to
1070 the check resume_handle >= *total_entries above. */
1072 num_entries
= *total_entries
- resume_handle
;
1074 ctr1
->array
= talloc_zero_array(p
->mem_ctx
,
1075 struct srvsvc_NetSessInfo1
,
1078 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
1080 for (num_entries
= 0; resume_handle
< *total_entries
; num_entries
++, resume_handle
++) {
1081 uint32_t connect_time
;
1084 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
1085 guest
= strequal( session_list
[resume_handle
].username
, lp_guest_account() );
1087 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
1088 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
1089 ctr1
->array
[num_entries
].num_open
= 0;/* computed later */
1090 ctr1
->array
[num_entries
].time
= connect_time
;
1091 ctr1
->array
[num_entries
].idle_time
= 0;
1092 ctr1
->array
[num_entries
].user_flags
= guest
;
1095 ctr1
->count
= num_entries
;
1097 /* count open files on all sessions in single tdb traversal */
1098 net_count_files_for_all_sess(ctr1
, session_list
,
1099 resume_handle_p
? *resume_handle_p
: 0,
1102 if (resume_handle_p
) {
1103 if (*resume_handle_p
>= *total_entries
) {
1104 *resume_handle_p
= 0;
1106 *resume_handle_p
= resume_handle
;
1113 /*******************************************************************
1114 find the share connection on which this open exists.
1115 ********************************************************************/
1117 static int share_file_fn(struct file_id fid
,
1118 const struct share_mode_data
*d
,
1119 const struct share_mode_entry
*e
,
1122 struct share_file_stat
*sfs
= data
;
1124 uint32_t offset
= sfs
->total_entries
- sfs
->resp_entries
;
1126 if (strequal(d
->servicepath
, sfs
->in_sharepath
)) {
1127 for (i
=0; i
< sfs
->resp_entries
; i
++) {
1128 if (server_id_equal(
1129 &e
->pid
, &sfs
->svrid_arr
[offset
+ i
])) {
1130 sfs
->netconn_arr
[i
].num_open
++;
1138 /*******************************************************************
1139 count number of open files on given share connections.
1140 ********************************************************************/
1142 static void count_share_opens(struct srvsvc_NetConnInfo1
*arr
,
1143 struct server_id
*svrid_arr
, char *sharepath
,
1144 uint32_t resp_entries
, uint32_t total_entries
)
1146 struct share_file_stat sfs
;
1148 sfs
.netconn_arr
= arr
;
1149 sfs
.svrid_arr
= svrid_arr
;
1150 sfs
.in_sharepath
= sharepath
;
1151 sfs
.resp_entries
= resp_entries
;
1152 sfs
.total_entries
= total_entries
;
1154 share_entry_forall(share_file_fn
, &sfs
);
1157 /****************************************************************************
1158 process an entry from the connection db.
1159 ****************************************************************************/
1161 static int share_conn_fn(struct smbXsrv_tcon_global0
*tcon
,
1164 struct share_conn_stat
*scs
= data
;
1166 if (!process_exists(tcon
->server_id
)) {
1170 if (strequal(tcon
->share_name
, scs
->sharename
)) {
1171 scs
->svrid_arr
= talloc_realloc(scs
->ctx
, scs
->svrid_arr
,
1174 if (!scs
->svrid_arr
) {
1178 scs
->svrid_arr
[scs
->count
] = tcon
->server_id
;
1185 /****************************************************************************
1186 Count the connections to a share. Build an array of serverid's owning these
1188 ****************************************************************************/
1190 static uint32_t count_share_conns(TALLOC_CTX
*ctx
, const char *sharename
,
1191 struct server_id
**arr
)
1193 struct share_conn_stat scs
;
1197 scs
.sharename
= sharename
;
1198 scs
.svrid_arr
= NULL
;
1201 status
= smbXsrv_tcon_global_traverse(share_conn_fn
, &scs
);
1203 if (!NT_STATUS_IS_OK(status
)) {
1204 DEBUG(0,("count_share_conns: traverse of "
1205 "smbXsrv_tcon_global.tdb failed - %s\n",
1206 nt_errstr(status
)));
1210 *arr
= scs
.svrid_arr
;
1214 /*******************************************************************
1215 fill in a conn info level 0 structure.
1216 ********************************************************************/
1218 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
1219 uint32_t *resume_handle_p
,
1220 uint32_t *total_entries
)
1222 uint32_t num_entries
= 0;
1223 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1225 DEBUG(5,("init_srv_conn_info_0\n"));
1228 if (resume_handle_p
) {
1229 *resume_handle_p
= 0;
1238 for (; resume_handle
< *total_entries
; resume_handle
++) {
1240 ctr0
->array
= talloc_realloc(talloc_tos(),
1242 struct srvsvc_NetConnInfo0
,
1245 return WERR_NOT_ENOUGH_MEMORY
;
1248 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
1250 /* move on to creating next connection */
1254 ctr0
->count
= num_entries
;
1255 *total_entries
= num_entries
;
1257 if (resume_handle_p
) {
1258 if (*resume_handle_p
>= *total_entries
) {
1259 *resume_handle_p
= 0;
1261 *resume_handle_p
= resume_handle
;
1268 /*******************************************************************
1269 fill in a conn info level 1 structure.
1270 ********************************************************************/
1272 static WERROR
init_srv_conn_info_1(const char *name
,
1273 struct srvsvc_NetConnCtr1
*ctr1
,
1274 uint32_t *resume_handle_p
,
1275 uint32_t *total_entries
)
1277 const struct loadparm_substitution
*lp_sub
=
1278 loadparm_s3_global_substitution();
1279 uint32_t num_entries
= 0;
1281 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1282 char *share_name
= NULL
;
1283 struct server_id
*svrid_arr
= NULL
;
1285 DEBUG(5,("init_srv_conn_info_1\n"));
1288 if (resume_handle_p
) {
1289 *resume_handle_p
= 0;
1294 /* check if this is a server name or a share name */
1295 if (name
&& (strlen(name
) > 2) && (name
[0] == '\\') &&
1296 (name
[1] == '\\')) {
1298 /* 'name' is a server name - this part is unimplemented */
1301 /* 'name' is a share name */
1302 snum
= find_service(talloc_tos(), name
, &share_name
);
1305 return WERR_NOT_ENOUGH_MEMORY
;
1309 return WERR_INVALID_NAME
;
1313 * count the num of connections to this share. Also,
1314 * build a list of serverid's that own these
1315 * connections. The serverid list is used later to
1316 * identify the share connection on which an open exists.
1319 *total_entries
= count_share_conns(talloc_tos(),
1324 if (resume_handle
>= *total_entries
) {
1325 if (resume_handle_p
) {
1326 *resume_handle_p
= 0;
1332 * We know num_entries must be positive, due to
1333 * the check resume_handle >= *total_entries above.
1336 num_entries
= *total_entries
- resume_handle
;
1340 ctr1
->array
= talloc_zero_array(talloc_tos(),
1341 struct srvsvc_NetConnInfo1
,
1344 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
1346 for (num_entries
= 0; resume_handle
< *total_entries
;
1347 num_entries
++, resume_handle
++) {
1349 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1350 ctr1
->array
[num_entries
].conn_type
= 0x3;
1353 * if these are connections to a share, we are going to
1354 * compute the opens on them later. If it's for the server,
1355 * it's unimplemented.
1359 ctr1
->array
[num_entries
].num_open
= 1;
1362 ctr1
->array
[num_entries
].num_users
= 1;
1363 ctr1
->array
[num_entries
].conn_time
= 3;
1364 ctr1
->array
[num_entries
].user
= "dummy_user";
1365 ctr1
->array
[num_entries
].share
= "IPC$";
1368 /* now compute open files on the share connections */
1373 * the locking tdb, which has the open files information,
1374 * does not store share name or share (service) number, but
1375 * just the share path. So, we can compute open files only
1376 * on the share path. If more than one shares are defined
1377 * on a share path, open files on all of them are included
1380 * To have the correct behavior in case multiple shares
1381 * are defined on the same path, changes to tdb records
1382 * would be required. That would be lot more effort, so
1383 * this seems a good stopgap fix.
1386 count_share_opens(ctr1
->array
, svrid_arr
,
1387 lp_path(talloc_tos(), lp_sub
, snum
),
1388 num_entries
, *total_entries
);
1392 ctr1
->count
= num_entries
;
1393 *total_entries
= num_entries
;
1395 if (resume_handle_p
) {
1396 *resume_handle_p
= resume_handle
;
1402 /*******************************************************************
1404 *******************************************************************/
1406 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1407 struct srvsvc_NetFileEnum
*r
)
1409 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1410 struct auth_session_info
*session_info
=
1411 dcesrv_call_session_info(dce_call
);
1412 TALLOC_CTX
*ctx
= NULL
;
1413 struct srvsvc_NetFileCtr3
*ctr3
;
1414 uint32_t resume_hnd
= 0;
1417 switch (r
->in
.info_ctr
->level
) {
1421 return WERR_INVALID_LEVEL
;
1424 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1425 session_info
->security_token
)) {
1426 DEBUG(1, ("Enumerating files only allowed for "
1427 "administrators\n"));
1428 return WERR_ACCESS_DENIED
;
1432 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1434 werr
= WERR_INVALID_PARAMETER
;
1438 /* TODO -- Windows enumerates
1440 (c) open directories and files */
1442 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1443 if (!W_ERROR_IS_OK(werr
)) {
1447 *r
->out
.totalentries
= ctr3
->count
;
1448 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1449 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1457 /*******************************************************************
1458 _srvsvc_NetSrvGetInfo
1459 ********************************************************************/
1461 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1462 struct srvsvc_NetSrvGetInfo
*r
)
1464 const struct loadparm_substitution
*lp_sub
=
1465 loadparm_s3_global_substitution();
1466 WERROR status
= WERR_OK
;
1468 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1470 if (!pipe_access_check(p
)) {
1471 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1472 return WERR_ACCESS_DENIED
;
1475 switch (r
->in
.level
) {
1477 /* Technically level 102 should only be available to
1478 Administrators but there isn't anything super-secret
1479 here, as most of it is made up. */
1482 struct srvsvc_NetSrvInfo102
*info102
;
1484 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1486 return WERR_NOT_ENOUGH_MEMORY
;
1489 info102
->platform_id
= PLATFORM_ID_NT
;
1490 info102
->server_name
= lp_netbios_name();
1491 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1492 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1493 info102
->server_type
= lp_default_server_announce();
1495 string_truncate(lp_server_string(info102
, lp_sub
),
1496 MAX_SERVER_STRING_LENGTH
);
1497 info102
->users
= 0xffffffff;
1498 info102
->disc
= 0xf;
1499 info102
->hidden
= 0;
1500 info102
->announce
= 240;
1501 info102
->anndelta
= 3000;
1502 info102
->licenses
= 100000;
1503 info102
->userpath
= "C:\\";
1505 r
->out
.info
->info102
= info102
;
1509 struct srvsvc_NetSrvInfo101
*info101
;
1511 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1513 return WERR_NOT_ENOUGH_MEMORY
;
1516 info101
->platform_id
= PLATFORM_ID_NT
;
1517 info101
->server_name
= lp_netbios_name();
1518 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1519 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1520 info101
->server_type
= lp_default_server_announce();
1522 string_truncate(lp_server_string(info101
, lp_sub
),
1523 MAX_SERVER_STRING_LENGTH
);
1525 r
->out
.info
->info101
= info101
;
1529 struct srvsvc_NetSrvInfo100
*info100
;
1531 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1533 return WERR_NOT_ENOUGH_MEMORY
;
1536 info100
->platform_id
= PLATFORM_ID_NT
;
1537 info100
->server_name
= lp_netbios_name();
1539 r
->out
.info
->info100
= info100
;
1544 status
= WERR_INVALID_LEVEL
;
1548 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1553 /*******************************************************************
1554 _srvsvc_NetSrvSetInfo
1555 ********************************************************************/
1557 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1558 struct srvsvc_NetSrvSetInfo
*r
)
1560 WERROR status
= WERR_OK
;
1562 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1564 /* Set up the net server set info structure. */
1566 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1571 /*******************************************************************
1573 ********************************************************************/
1575 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1576 struct srvsvc_NetConnEnum
*r
)
1578 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1579 struct auth_session_info
*session_info
=
1580 dcesrv_call_session_info(dce_call
);
1583 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1585 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1586 session_info
->security_token
)) {
1587 DEBUG(1, ("Enumerating connections only allowed for "
1588 "administrators\n"));
1589 return WERR_ACCESS_DENIED
;
1592 switch (r
->in
.info_ctr
->level
) {
1594 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1595 r
->in
.resume_handle
,
1596 r
->out
.totalentries
);
1599 werr
= init_srv_conn_info_1(r
->in
.path
,
1600 r
->in
.info_ctr
->ctr
.ctr1
,
1601 r
->in
.resume_handle
,
1602 r
->out
.totalentries
);
1605 return WERR_INVALID_LEVEL
;
1608 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1613 /*******************************************************************
1615 ********************************************************************/
1617 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1618 struct srvsvc_NetSessEnum
*r
)
1620 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1621 struct auth_session_info
*session_info
=
1622 dcesrv_call_session_info(dce_call
);
1625 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1627 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1628 session_info
->security_token
)) {
1629 DEBUG(1, ("Enumerating sessions only allowed for "
1630 "administrators\n"));
1631 return WERR_ACCESS_DENIED
;
1634 switch (r
->in
.info_ctr
->level
) {
1636 werr
= init_srv_sess_info_0(p
,
1637 r
->in
.info_ctr
->ctr
.ctr0
,
1638 r
->in
.resume_handle
,
1639 r
->out
.totalentries
);
1642 werr
= init_srv_sess_info_1(p
,
1643 r
->in
.info_ctr
->ctr
.ctr1
,
1644 r
->in
.resume_handle
,
1645 r
->out
.totalentries
);
1648 return WERR_INVALID_LEVEL
;
1651 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1656 /*******************************************************************
1658 ********************************************************************/
1660 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1661 struct srvsvc_NetSessDel
*r
)
1663 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1664 struct auth_session_info
*session_info
=
1665 dcesrv_call_session_info(dce_call
);
1666 struct sessionid
*session_list
;
1667 int num_sessions
, snum
;
1668 const char *username
;
1669 const char *machine
;
1670 bool not_root
= False
;
1673 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1675 werr
= WERR_ACCESS_DENIED
;
1677 /* fail out now if you are not root or not a domain admin */
1679 if ((session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1680 ( ! nt_token_check_domain_rid(session_info
->security_token
,
1681 DOMAIN_RID_ADMINS
))) {
1686 username
= r
->in
.user
;
1687 machine
= r
->in
.client
;
1689 /* strip leading backslashes if any */
1690 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1694 num_sessions
= find_sessions(p
->mem_ctx
, username
, machine
,
1697 for (snum
= 0; snum
< num_sessions
; snum
++) {
1701 if (session_info
->unix_token
->uid
!= sec_initial_uid()) {
1706 ntstat
= messaging_send(p
->msg_ctx
,
1707 session_list
[snum
].pid
,
1708 MSG_SHUTDOWN
, &data_blob_null
);
1710 if (NT_STATUS_IS_OK(ntstat
))
1717 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1724 /*******************************************************************
1725 _srvsvc_NetShareEnumAll
1726 ********************************************************************/
1728 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1729 struct srvsvc_NetShareEnumAll
*r
)
1733 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1735 if (!pipe_access_check(p
)) {
1736 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1737 return WERR_ACCESS_DENIED
;
1740 /* Create the list of shares for the response. */
1741 werr
= init_srv_share_info_ctr(p
,
1743 r
->in
.resume_handle
,
1744 r
->out
.totalentries
,
1747 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1752 /*******************************************************************
1753 _srvsvc_NetShareEnum
1754 ********************************************************************/
1756 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1757 struct srvsvc_NetShareEnum
*r
)
1761 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1763 if (!pipe_access_check(p
)) {
1764 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1765 return WERR_ACCESS_DENIED
;
1768 /* Create the list of shares for the response. */
1769 werr
= init_srv_share_info_ctr(p
,
1771 r
->in
.resume_handle
,
1772 r
->out
.totalentries
,
1775 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1780 /*******************************************************************
1781 _srvsvc_NetShareGetInfo
1782 ********************************************************************/
1784 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1785 struct srvsvc_NetShareGetInfo
*r
)
1787 WERROR status
= WERR_OK
;
1788 char *share_name
= NULL
;
1790 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1792 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1794 if (!r
->in
.share_name
) {
1795 return WERR_INVALID_NAME
;
1798 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1800 return WERR_NOT_ENOUGH_MEMORY
;
1803 return WERR_INVALID_NAME
;
1806 switch (r
->in
.level
) {
1808 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1809 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1810 init_srv_share_info_0(p
, info
->info0
, snum
);
1813 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1814 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1815 init_srv_share_info_1(p
, info
->info1
, snum
);
1818 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1819 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1820 init_srv_share_info_2(p
, info
->info2
, snum
);
1821 info
->info2
->current_users
=
1822 count_current_connections(info
->info2
->name
, false);
1825 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1826 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1827 init_srv_share_info_501(p
, info
->info501
, snum
);
1830 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1831 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1832 init_srv_share_info_502(p
, info
->info502
, snum
);
1835 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1836 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1837 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1840 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1841 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1842 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1845 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1846 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1847 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1850 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1851 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1852 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1855 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1858 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1860 status
= WERR_INVALID_LEVEL
;
1864 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1869 /*******************************************************************
1870 _srvsvc_NetShareSetInfo. Modify share details.
1871 ********************************************************************/
1873 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1874 struct srvsvc_NetShareSetInfo
*r
)
1876 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
1877 struct auth_session_info
*session_info
=
1878 dcesrv_call_session_info(dce_call
);
1879 const struct loadparm_substitution
*lp_sub
=
1880 loadparm_s3_global_substitution();
1881 char *command
= NULL
;
1882 char *share_name
= NULL
;
1883 char *comment
= NULL
;
1884 const char *pathname
= NULL
;
1889 struct security_descriptor
*psd
= NULL
;
1890 bool is_disk_op
= False
;
1891 const char *csc_policy
= NULL
;
1892 bool csc_policy_changed
= false;
1893 const char *csc_policies
[] = {"manual", "documents", "programs",
1895 uint32_t client_csc_policy
;
1896 int max_connections
= 0;
1897 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1898 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1900 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1902 if (!r
->in
.share_name
) {
1903 return WERR_INVALID_NAME
;
1906 if (r
->out
.parm_error
) {
1907 *r
->out
.parm_error
= 0;
1910 if ( strequal(r
->in
.share_name
,"IPC$")
1911 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1912 || strequal(r
->in
.share_name
,"global") )
1914 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1915 "modified by a remote user.\n",
1916 r
->in
.share_name
));
1917 return WERR_ACCESS_DENIED
;
1920 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1922 return WERR_NOT_ENOUGH_MEMORY
;
1925 /* Does this share exist ? */
1927 return WERR_NERR_NETNAMENOTFOUND
;
1929 /* No change to printer shares. */
1930 if (lp_printable(snum
))
1931 return WERR_ACCESS_DENIED
;
1933 is_disk_op
= security_token_has_privilege(
1934 session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1936 /* fail out now if you are not root and not a disk op */
1938 if (session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1939 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1940 "SeDiskOperatorPrivilege privilege needed to modify "
1942 (unsigned int)session_info
->unix_token
->uid
,
1944 return WERR_ACCESS_DENIED
;
1947 max_connections
= lp_max_connections(snum
);
1948 csc_policy
= csc_policies
[lp_csc_policy(snum
)];
1950 switch (r
->in
.level
) {
1952 pathname
= lp_path(ctx
, lp_sub
, snum
);
1953 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1954 type
= info
->info1
->type
;
1958 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1959 pathname
= info
->info2
->path
;
1960 type
= info
->info2
->type
;
1961 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1962 0 : info
->info2
->max_users
;
1966 /* not supported on set but here for completeness */
1968 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1969 type
= info
->info501
->type
;
1974 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1975 pathname
= info
->info502
->path
;
1976 type
= info
->info502
->type
;
1977 psd
= info
->info502
->sd_buf
.sd
;
1978 map_generic_share_sd_bits(psd
);
1981 pathname
= lp_path(ctx
, lp_sub
, snum
);
1982 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1983 type
= STYPE_DISKTREE
;
1986 /* XP re-sets the csc policy even if it wasn't changed by the
1987 user, so we must compare it to see if it's what is set in
1988 smb.conf, so that we can continue other ops like setting
1990 client_csc_policy
= (info
->info1005
->dfs_flags
&
1991 SHARE_1005_CSC_POLICY_MASK
) >>
1992 SHARE_1005_CSC_POLICY_SHIFT
;
1994 if (client_csc_policy
== (uint32_t)lp_csc_policy(snum
)) {
1998 csc_policy
= csc_policies
[client_csc_policy
];
1999 csc_policy_changed
= true;
2001 pathname
= lp_path(ctx
, lp_sub
, snum
);
2002 comment
= lp_comment(ctx
, lp_sub
, snum
);
2003 type
= STYPE_DISKTREE
;
2007 return WERR_ACCESS_DENIED
;
2009 pathname
= lp_path(ctx
, lp_sub
, snum
);
2010 comment
= lp_comment(ctx
, lp_sub
, snum
);
2011 psd
= info
->info1501
->sd
;
2012 map_generic_share_sd_bits(psd
);
2013 type
= STYPE_DISKTREE
;
2016 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
2018 return WERR_INVALID_LEVEL
;
2021 /* We can only modify disk shares. */
2022 if (type
!= STYPE_DISKTREE
) {
2023 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
2026 return WERR_ACCESS_DENIED
;
2029 if (comment
== NULL
) {
2030 return WERR_NOT_ENOUGH_MEMORY
;
2033 /* Check if the pathname is valid. */
2034 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
2035 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
2037 return WERR_BAD_PATHNAME
;
2040 /* Ensure share name, pathname and comment don't contain '"' characters. */
2041 string_replace(share_name
, '"', ' ');
2042 string_replace(path
, '"', ' ');
2043 string_replace(comment
, '"', ' ');
2045 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
2046 lp_change_share_command(talloc_tos(), lp_sub
) ? lp_change_share_command(talloc_tos(), lp_sub
) : "NULL" ));
2048 /* Only call modify function if something changed. */
2050 if (strcmp(path
, lp_path(talloc_tos(), lp_sub
, snum
))
2051 || strcmp(comment
, lp_comment(talloc_tos(), lp_sub
, snum
))
2052 || (lp_max_connections(snum
) != max_connections
)
2053 || csc_policy_changed
) {
2055 if (!lp_change_share_command(talloc_tos(), lp_sub
) || !*lp_change_share_command(talloc_tos(), lp_sub
)) {
2056 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
2057 return WERR_ACCESS_DENIED
;
2060 command
= talloc_asprintf(p
->mem_ctx
,
2061 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
2062 lp_change_share_command(talloc_tos(), lp_sub
),
2063 get_dyn_CONFIGFILE(),
2070 return WERR_NOT_ENOUGH_MEMORY
;
2073 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
2075 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2080 ret
= smbrun(command
, NULL
, NULL
);
2082 reload_services(NULL
, NULL
, false);
2084 /* Tell everyone we updated smb.conf. */
2085 messaging_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
2092 /********* END SeDiskOperatorPrivilege BLOCK *********/
2094 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
2097 TALLOC_FREE(command
);
2100 return WERR_ACCESS_DENIED
;
2102 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
2106 /* Replace SD if changed. */
2108 struct security_descriptor
*old_sd
;
2112 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(talloc_tos(), lp_sub
, snum
), &sd_size
);
2114 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
2115 status
= set_share_security(share_name
, psd
);
2116 if (!NT_STATUS_IS_OK(status
)) {
2117 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
2123 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
2128 /*******************************************************************
2129 _srvsvc_NetShareAdd.
2130 Call 'add_share_command "sharename" "pathname"
2131 "comment" "max connections = "
2132 ********************************************************************/
2134 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
2135 struct srvsvc_NetShareAdd
*r
)
2137 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
2138 struct auth_session_info
*session_info
=
2139 dcesrv_call_session_info(dce_call
);
2140 char *command
= NULL
;
2141 char *share_name_in
= NULL
;
2142 char *share_name
= NULL
;
2143 char *comment
= NULL
;
2144 char *pathname
= NULL
;
2149 struct security_descriptor
*psd
= NULL
;
2151 int max_connections
= 0;
2153 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2154 const struct loadparm_substitution
*lp_sub
=
2155 loadparm_s3_global_substitution();
2157 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
2159 if (r
->out
.parm_error
) {
2160 *r
->out
.parm_error
= 0;
2163 is_disk_op
= security_token_has_privilege(
2164 session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2166 if (session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2167 return WERR_ACCESS_DENIED
;
2170 if (!lp_add_share_command(talloc_tos(), lp_sub
) || !*lp_add_share_command(talloc_tos(), lp_sub
)) {
2171 DBG_WARNING("_srvsvc_NetShareAdd: No \"add share command\" parameter set in smb.conf.\n");
2172 return WERR_ACCESS_DENIED
;
2175 switch (r
->in
.level
) {
2177 /* No path. Not enough info in a level 0 to do anything. */
2178 return WERR_ACCESS_DENIED
;
2180 /* Not enough info in a level 1 to do anything. */
2181 return WERR_ACCESS_DENIED
;
2183 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
2184 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
2185 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
2186 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
2187 0 : r
->in
.info
->info2
->max_users
;
2188 type
= r
->in
.info
->info2
->type
;
2191 /* No path. Not enough info in a level 501 to do anything. */
2192 return WERR_ACCESS_DENIED
;
2194 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
2195 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
2196 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
2197 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
2198 0 : r
->in
.info
->info502
->max_users
;
2199 type
= r
->in
.info
->info502
->type
;
2200 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
2201 map_generic_share_sd_bits(psd
);
2204 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2210 return WERR_ACCESS_DENIED
;
2212 /* DFS only level. */
2213 return WERR_ACCESS_DENIED
;
2215 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2217 return WERR_INVALID_LEVEL
;
2220 /* check for invalid share names */
2222 if (!share_name_in
|| !validate_net_name(share_name_in
,
2223 INVALID_SHARENAME_CHARS
,
2224 strlen(share_name_in
))) {
2225 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2226 share_name_in
? share_name_in
: ""));
2227 return WERR_INVALID_NAME
;
2230 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
2231 || (lp_enable_asu_support() &&
2232 strequal(share_name_in
,"ADMIN$"))) {
2233 return WERR_ACCESS_DENIED
;
2236 snum
= find_service(ctx
, share_name_in
, &share_name
);
2238 return WERR_NOT_ENOUGH_MEMORY
;
2241 /* Share already exists. */
2243 return WERR_FILE_EXISTS
;
2246 /* We can only add disk shares. */
2247 if (type
!= STYPE_DISKTREE
) {
2248 return WERR_ACCESS_DENIED
;
2251 /* Check if the pathname is valid. */
2252 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
2253 return WERR_BAD_PATHNAME
;
2256 ret
= sys_lstat(path
, &st
, false);
2257 if (ret
== -1 && (errno
!= EACCES
)) {
2259 * If path has any other than permission
2260 * problem, return WERR_FILE_NOT_FOUND (as Windows
2263 return WERR_FILE_NOT_FOUND
;
2266 /* Ensure share name, pathname and comment don't contain '"' characters. */
2267 string_replace(share_name_in
, '"', ' ');
2268 string_replace(share_name
, '"', ' ');
2269 string_replace(path
, '"', ' ');
2271 string_replace(comment
, '"', ' ');
2274 command
= talloc_asprintf(ctx
,
2275 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2276 lp_add_share_command(talloc_tos(), lp_sub
),
2277 get_dyn_CONFIGFILE(),
2280 comment
? comment
: "",
2283 return WERR_NOT_ENOUGH_MEMORY
;
2286 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
2288 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2293 /* FIXME: use libnetconf here - gd */
2295 ret
= smbrun(command
, NULL
, NULL
);
2297 /* Tell everyone we updated smb.conf. */
2298 messaging_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0);
2304 /********* END SeDiskOperatorPrivilege BLOCK *********/
2306 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2309 TALLOC_FREE(command
);
2312 return WERR_ACCESS_DENIED
;
2316 /* Note we use share_name here, not share_name_in as
2317 we need a canonicalized name for setting security. */
2318 status
= set_share_security(share_name
, psd
);
2319 if (!NT_STATUS_IS_OK(status
)) {
2320 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2326 * We don't call reload_services() here, the message will
2327 * cause this to be done before the next packet is read
2328 * from the client. JRA.
2331 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
2336 /*******************************************************************
2338 Call "delete share command" with the share name as
2340 ********************************************************************/
2342 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
2343 struct srvsvc_NetShareDel
*r
)
2345 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
2346 struct auth_session_info
*session_info
=
2347 dcesrv_call_session_info(dce_call
);
2348 char *command
= NULL
;
2349 char *share_name
= NULL
;
2353 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2354 const struct loadparm_substitution
*lp_sub
=
2355 loadparm_s3_global_substitution();
2357 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
2359 if (!r
->in
.share_name
) {
2360 return WERR_NERR_NETNAMENOTFOUND
;
2363 if ( strequal(r
->in
.share_name
,"IPC$")
2364 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
2365 || strequal(r
->in
.share_name
,"global") )
2367 return WERR_ACCESS_DENIED
;
2370 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
2372 return WERR_NOT_ENOUGH_MEMORY
;
2376 return WERR_BAD_NET_NAME
;
2379 /* No change to printer shares. */
2380 if (lp_printable(snum
))
2381 return WERR_ACCESS_DENIED
;
2383 is_disk_op
= security_token_has_privilege(
2384 session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2386 if (session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2387 return WERR_ACCESS_DENIED
;
2390 if (!lp_delete_share_command(talloc_tos(), lp_sub
) || !*lp_delete_share_command(talloc_tos(), lp_sub
)) {
2391 DBG_WARNING("_srvsvc_NetShareDel: No \"delete share command\" parameter set in smb.conf.\n");
2392 return WERR_ACCESS_DENIED
;
2395 command
= talloc_asprintf(ctx
,
2397 lp_delete_share_command(talloc_tos(), lp_sub
),
2398 get_dyn_CONFIGFILE(),
2401 return WERR_NOT_ENOUGH_MEMORY
;
2404 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
2406 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2411 ret
= smbrun(command
, NULL
, NULL
);
2413 /* Tell everyone we updated smb.conf. */
2414 messaging_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0);
2420 /********* END SeDiskOperatorPrivilege BLOCK *********/
2422 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2425 return WERR_ACCESS_DENIED
;
2427 /* Delete the SD in the database. */
2428 delete_share_security(share_name
);
2430 lp_killservice(snum
);
2435 /*******************************************************************
2436 _srvsvc_NetShareDelSticky
2437 ********************************************************************/
2439 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2440 struct srvsvc_NetShareDelSticky
*r
)
2442 struct srvsvc_NetShareDel q
;
2444 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2446 q
.in
.server_unc
= r
->in
.server_unc
;
2447 q
.in
.share_name
= r
->in
.share_name
;
2448 q
.in
.reserved
= r
->in
.reserved
;
2450 return _srvsvc_NetShareDel(p
, &q
);
2453 /*******************************************************************
2454 _srvsvc_NetRemoteTOD
2455 ********************************************************************/
2457 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2458 struct srvsvc_NetRemoteTOD
*r
)
2460 struct srvsvc_NetRemoteTODInfo
*tod
;
2462 time_t unixdate
= time(NULL
);
2464 /* We do this call first as if we do it *after* the gmtime call
2465 it overwrites the pointed-to values. JRA */
2467 uint32_t zone
= get_time_zone(unixdate
)/60;
2469 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2471 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2472 return WERR_NOT_ENOUGH_MEMORY
;
2476 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2478 t
= gmtime(&unixdate
);
2481 tod
->elapsed
= unixdate
;
2483 tod
->hours
= t
->tm_hour
;
2484 tod
->mins
= t
->tm_min
;
2485 tod
->secs
= t
->tm_sec
;
2487 tod
->timezone
= zone
;
2488 tod
->tinterval
= 10000;
2489 tod
->day
= t
->tm_mday
;
2490 tod
->month
= t
->tm_mon
+ 1;
2491 tod
->year
= 1900+t
->tm_year
;
2492 tod
->weekday
= t
->tm_wday
;
2494 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2499 /***********************************************************************************
2500 _srvsvc_NetGetFileSecurity
2501 Win9x NT tools get security descriptor.
2502 ***********************************************************************************/
2504 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2505 struct srvsvc_NetGetFileSecurity
*r
)
2507 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
2508 struct auth_session_info
*session_info
=
2509 dcesrv_call_session_info(dce_call
);
2510 TALLOC_CTX
*frame
= talloc_stackframe();
2511 const struct loadparm_substitution
*lp_sub
=
2512 loadparm_s3_global_substitution();
2513 struct smb_filename
*smb_fname
= NULL
;
2515 char *servicename
= NULL
;
2519 struct conn_struct_tos
*c
= NULL
;
2520 connection_struct
*conn
= NULL
;
2521 struct sec_desc_buf
*sd_buf
= NULL
;
2522 struct files_struct
*dirfsp
= NULL
;
2523 files_struct
*fsp
= NULL
;
2525 uint32_t ucf_flags
= 0;
2531 werr
= WERR_NERR_NETNAMENOTFOUND
;
2534 snum
= find_service(frame
, r
->in
.share
, &servicename
);
2536 werr
= WERR_NOT_ENOUGH_MEMORY
;
2540 DEBUG(10, ("Could not find service %s\n", servicename
));
2541 werr
= WERR_NERR_NETNAMENOTFOUND
;
2545 nt_status
= create_conn_struct_tos_cwd(global_messaging_context(),
2547 lp_path(frame
, lp_sub
, snum
),
2550 if (!NT_STATUS_IS_OK(nt_status
)) {
2551 DEBUG(10, ("create_conn_struct failed: %s\n",
2552 nt_errstr(nt_status
)));
2553 werr
= ntstatus_to_werror(nt_status
);
2558 nt_status
= filename_convert_dirfsp(frame
,
2565 if (!NT_STATUS_IS_OK(nt_status
)) {
2566 werr
= ntstatus_to_werror(nt_status
);
2570 nt_status
= SMB_VFS_CREATE_FILE(
2573 dirfsp
, /* dirfsp */
2574 smb_fname
, /* fname */
2575 FILE_READ_ATTRIBUTES
, /* access_mask */
2576 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2577 FILE_OPEN
, /* create_disposition*/
2578 0, /* create_options */
2579 0, /* file_attributes */
2580 INTERNAL_OPEN_ONLY
, /* oplock_request */
2582 0, /* allocation_size */
2583 0, /* private_flags */
2588 NULL
, NULL
); /* create context */
2590 if (!NT_STATUS_IS_OK(nt_status
)) {
2591 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2592 smb_fname_str_dbg(smb_fname
)));
2593 werr
= ntstatus_to_werror(nt_status
);
2597 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2599 werr
= WERR_NOT_ENOUGH_MEMORY
;
2603 nt_status
= SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp
),
2606 |SECINFO_DACL
), sd_buf
, &sd_buf
->sd
);
2608 if (!NT_STATUS_IS_OK(nt_status
)) {
2609 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2610 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2611 werr
= ntstatus_to_werror(nt_status
);
2612 TALLOC_FREE(sd_buf
);
2616 if (sd_buf
->sd
->dacl
) {
2617 sd_buf
->sd
->dacl
->revision
= NT4_ACL_REVISION
;
2620 sd_size
= ndr_size_security_descriptor(sd_buf
->sd
, 0);
2622 sd_buf
->sd_size
= sd_size
;
2624 *r
->out
.sd_buf
= sd_buf
;
2631 close_file_free(NULL
, &fsp
, NORMAL_CLOSE
);
2638 /***********************************************************************************
2639 _srvsvc_NetSetFileSecurity
2640 Win9x NT tools set security descriptor.
2641 ***********************************************************************************/
2643 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2644 struct srvsvc_NetSetFileSecurity
*r
)
2646 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
2647 struct auth_session_info
*session_info
=
2648 dcesrv_call_session_info(dce_call
);
2649 TALLOC_CTX
*frame
= talloc_stackframe();
2650 const struct loadparm_substitution
*lp_sub
=
2651 loadparm_s3_global_substitution();
2652 struct smb_filename
*smb_fname
= NULL
;
2653 char *servicename
= NULL
;
2654 struct files_struct
*dirfsp
= NULL
;
2655 files_struct
*fsp
= NULL
;
2659 struct conn_struct_tos
*c
= NULL
;
2660 connection_struct
*conn
= NULL
;
2662 struct security_descriptor
*psd
= NULL
;
2663 uint32_t security_info_sent
= 0;
2664 uint32_t ucf_flags
= 0;
2670 werr
= WERR_NERR_NETNAMENOTFOUND
;
2674 snum
= find_service(frame
, r
->in
.share
, &servicename
);
2676 werr
= WERR_NOT_ENOUGH_MEMORY
;
2681 DEBUG(10, ("Could not find service %s\n", servicename
));
2682 werr
= WERR_NERR_NETNAMENOTFOUND
;
2686 nt_status
= create_conn_struct_tos_cwd(global_messaging_context(),
2688 lp_path(frame
, lp_sub
, snum
),
2691 if (!NT_STATUS_IS_OK(nt_status
)) {
2692 DEBUG(10, ("create_conn_struct failed: %s\n",
2693 nt_errstr(nt_status
)));
2694 werr
= ntstatus_to_werror(nt_status
);
2699 nt_status
= filename_convert_dirfsp(frame
,
2706 if (!NT_STATUS_IS_OK(nt_status
)) {
2707 werr
= ntstatus_to_werror(nt_status
);
2711 nt_status
= SMB_VFS_CREATE_FILE(
2714 dirfsp
, /* dirfsp */
2715 smb_fname
, /* fname */
2716 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2717 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2718 FILE_OPEN
, /* create_disposition*/
2719 0, /* create_options */
2720 0, /* file_attributes */
2721 INTERNAL_OPEN_ONLY
, /* oplock_request */
2723 0, /* allocation_size */
2724 0, /* private_flags */
2729 NULL
, NULL
); /* create context */
2731 if (!NT_STATUS_IS_OK(nt_status
)) {
2732 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2733 smb_fname_str_dbg(smb_fname
)));
2734 werr
= ntstatus_to_werror(nt_status
);
2738 psd
= r
->in
.sd_buf
->sd
;
2739 security_info_sent
= r
->in
.securityinformation
;
2741 nt_status
= set_sd(fsp
, psd
, security_info_sent
);
2743 if (!NT_STATUS_IS_OK(nt_status
) ) {
2744 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2745 "on file %s\n", r
->in
.share
));
2746 werr
= WERR_ACCESS_DENIED
;
2755 close_file_free(NULL
, &fsp
, NORMAL_CLOSE
);
2762 /***********************************************************************************
2763 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2764 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2765 These disks would the disks listed by this function.
2766 Users could then create shares relative to these disks. Watch out for moving these disks around.
2767 "Nigel Williams" <nigel@veritas.com>.
2768 ***********************************************************************************/
2770 static const char *server_disks
[] = {"C:"};
2772 static uint32_t get_server_disk_count(void)
2774 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2777 static uint32_t init_server_disk_enum(uint32_t *resume
)
2779 uint32_t server_disk_count
= get_server_disk_count();
2781 /*resume can be an offset into the list for now*/
2783 if(*resume
& 0x80000000)
2786 if(*resume
> server_disk_count
)
2787 *resume
= server_disk_count
;
2789 return server_disk_count
- *resume
;
2792 static const char *next_server_disk_enum(uint32_t *resume
)
2796 if(init_server_disk_enum(resume
) == 0)
2799 disk
= server_disks
[*resume
];
2803 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2808 /********************************************************************
2810 ********************************************************************/
2812 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2813 struct srvsvc_NetDiskEnum
*r
)
2816 const char *disk_name
;
2817 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2819 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2823 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2825 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2826 MAX_SERVER_DISK_ENTRIES
);
2827 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2829 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2831 r
->out
.info
->count
= 0;
2833 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2835 r
->out
.info
->count
++;
2837 /*copy disk name into a unicode string*/
2839 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2840 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2843 /* add a terminating null string. Is this there if there is more data to come? */
2845 r
->out
.info
->count
++;
2847 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2848 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2850 if (r
->out
.resume_handle
) {
2851 *r
->out
.resume_handle
= resume
;
2857 /********************************************************************
2858 _srvsvc_NetNameValidate
2859 ********************************************************************/
2861 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2862 struct srvsvc_NetNameValidate
*r
)
2864 switch (r
->in
.name_type
) {
2866 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2867 strlen_m(r
->in
.name
)))
2869 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2871 return WERR_INVALID_NAME
;
2876 return WERR_INVALID_LEVEL
;
2882 /*******************************************************************
2883 ********************************************************************/
2885 struct enum_file_close_state
{
2886 struct srvsvc_NetFileClose
*r
;
2887 struct messaging_context
*msg_ctx
;
2890 static int enum_file_close_fn(struct file_id id
,
2891 const struct share_mode_data
*d
,
2892 const struct share_mode_entry
*e
,
2895 struct enum_file_close_state
*state
=
2896 (struct enum_file_close_state
*)private_data
;
2897 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2898 struct oplock_break_message msg
= {
2900 .share_file_id
= e
->share_file_id
,
2902 enum ndr_err_code ndr_err
;
2904 DATA_BLOB blob
= {.data
= msgbuf
, .length
= sizeof(msgbuf
)};
2907 if (fid
!= state
->r
->in
.fid
) {
2908 return 0; /* Not this file. */
2911 if (!process_exists(e
->pid
) ) {
2915 /* Ok - send the close message. */
2916 DBG_DEBUG("request to close file %s, %s\n", d
->servicepath
,
2917 share_mode_str(talloc_tos(), 0, &id
, e
));
2919 ndr_err
= ndr_push_struct_into_fixed_blob(
2922 (ndr_push_flags_fn_t
)ndr_push_oplock_break_message
);
2923 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2924 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2925 ndr_errstr(ndr_err
));
2926 status
= ndr_map_error2ntstatus(ndr_err
);
2928 status
= messaging_send(state
->msg_ctx
,
2934 if (!NT_STATUS_IS_OK(status
)) {
2935 state
->r
->out
.result
= ntstatus_to_werror(status
);
2941 /********************************************************************
2942 Close a file given a 32-bit file id.
2943 ********************************************************************/
2945 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2946 struct srvsvc_NetFileClose
*r
)
2948 struct dcesrv_call_state
*dce_call
= p
->dce_call
;
2949 struct auth_session_info
*session_info
=
2950 dcesrv_call_session_info(dce_call
);
2951 struct enum_file_close_state state
;
2954 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2956 is_disk_op
= security_token_has_privilege(
2957 session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2959 if (session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2960 return WERR_ACCESS_DENIED
;
2963 /* enum_file_close_fn sends the close message to
2964 * the relevant smbd process. */
2966 r
->out
.result
= WERR_FILE_NOT_FOUND
;
2968 state
.msg_ctx
= p
->msg_ctx
;
2969 share_entry_forall(enum_file_close_fn
, &state
);
2970 return r
->out
.result
;
2973 /********************************************************************
2974 ********************************************************************/
2976 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2977 struct srvsvc_NetCharDevEnum
*r
)
2979 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2980 return WERR_NOT_SUPPORTED
;
2983 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2984 struct srvsvc_NetCharDevGetInfo
*r
)
2986 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2987 return WERR_NOT_SUPPORTED
;
2990 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2991 struct srvsvc_NetCharDevControl
*r
)
2993 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2994 return WERR_NOT_SUPPORTED
;
2997 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2998 struct srvsvc_NetCharDevQEnum
*r
)
3000 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3001 return WERR_NOT_SUPPORTED
;
3004 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
3005 struct srvsvc_NetCharDevQGetInfo
*r
)
3007 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3008 return WERR_NOT_SUPPORTED
;
3011 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
3012 struct srvsvc_NetCharDevQSetInfo
*r
)
3014 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3015 return WERR_NOT_SUPPORTED
;
3018 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
3019 struct srvsvc_NetCharDevQPurge
*r
)
3021 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3022 return WERR_NOT_SUPPORTED
;
3025 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
3026 struct srvsvc_NetCharDevQPurgeSelf
*r
)
3028 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3029 return WERR_NOT_SUPPORTED
;
3032 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
3033 struct srvsvc_NetFileGetInfo
*r
)
3035 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3036 return WERR_NOT_SUPPORTED
;
3039 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
3040 struct srvsvc_NetShareCheck
*r
)
3042 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3043 return WERR_NOT_SUPPORTED
;
3046 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
3047 struct srvsvc_NetServerStatisticsGet
*r
)
3049 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3050 return WERR_NOT_SUPPORTED
;
3053 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
3054 struct srvsvc_NetTransportAdd
*r
)
3056 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3057 return WERR_NOT_SUPPORTED
;
3060 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
3061 struct srvsvc_NetTransportEnum
*r
)
3063 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3064 return WERR_NOT_SUPPORTED
;
3067 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
3068 struct srvsvc_NetTransportDel
*r
)
3070 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3071 return WERR_NOT_SUPPORTED
;
3074 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
3075 struct srvsvc_NetSetServiceBits
*r
)
3077 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3078 return WERR_NOT_SUPPORTED
;
3081 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
3082 struct srvsvc_NetPathType
*r
)
3084 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3085 return WERR_NOT_SUPPORTED
;
3088 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
3089 struct srvsvc_NetPathCanonicalize
*r
)
3091 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3092 return WERR_NOT_SUPPORTED
;
3095 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
3096 struct srvsvc_NetPathCompare
*r
)
3098 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3099 return WERR_NOT_SUPPORTED
;
3102 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
3103 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
3105 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3106 return WERR_NOT_SUPPORTED
;
3109 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
3110 struct srvsvc_NetPRNameCompare
*r
)
3112 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3113 return WERR_NOT_SUPPORTED
;
3116 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
3117 struct srvsvc_NetShareDelStart
*r
)
3119 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3120 return WERR_NOT_SUPPORTED
;
3123 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
3124 struct srvsvc_NetShareDelCommit
*r
)
3126 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3127 return WERR_NOT_SUPPORTED
;
3130 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
3131 struct srvsvc_NetServerTransportAddEx
*r
)
3133 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3134 return WERR_NOT_SUPPORTED
;
3137 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
3138 struct srvsvc_NetServerSetServiceBitsEx
*r
)
3140 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3141 return WERR_NOT_SUPPORTED
;
3144 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
3145 struct srvsvc_NETRDFSGETVERSION
*r
)
3147 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3148 return WERR_NOT_SUPPORTED
;
3151 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
3152 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
3154 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3155 return WERR_NOT_SUPPORTED
;
3158 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
3159 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
3161 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3162 return WERR_NOT_SUPPORTED
;
3165 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
3166 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
3168 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3169 return WERR_NOT_SUPPORTED
;
3172 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
3173 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
3175 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3176 return WERR_NOT_SUPPORTED
;
3179 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
3180 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
3182 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3183 return WERR_NOT_SUPPORTED
;
3186 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
3187 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
3189 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3190 return WERR_NOT_SUPPORTED
;
3193 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
3194 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
3196 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3197 return WERR_NOT_SUPPORTED
;
3200 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
3201 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
3203 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3204 return WERR_NOT_SUPPORTED
;
3207 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
3208 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
3210 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3211 return WERR_NOT_SUPPORTED
;
3214 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
3215 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
3217 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3218 return WERR_NOT_SUPPORTED
;
3221 /* include the generated boilerplate */
3222 #include "librpc/gen_ndr/ndr_srvsvc_scompat.c"