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. */
28 extern const struct generic_mapping file_generic_mapping
;
31 #define DBGC_CLASS DBGC_RPC_SRV
33 #define MAX_SERVER_DISK_ENTRIES 15
35 /* Use for enumerating connections, pipes, & files */
37 struct file_enum_count
{
40 struct srvsvc_NetFileCtr3
*ctr3
;
43 struct sess_file_count
{
49 /****************************************************************************
50 Count the entries belonging to a service in the connection db.
51 ****************************************************************************/
53 static int pipe_enum_fn( struct db_record
*rec
, void *p
)
55 struct pipe_open_rec prec
;
56 struct file_enum_count
*fenum
= (struct file_enum_count
*)p
;
57 struct srvsvc_NetFileInfo3
*f
;
58 int i
= fenum
->ctr3
->count
;
59 char *fullpath
= NULL
;
62 if (rec
->value
.dsize
!= sizeof(struct pipe_open_rec
))
65 memcpy(&prec
, rec
->value
.dptr
, sizeof(struct pipe_open_rec
));
67 if ( !process_exists(prec
.pid
) ) {
71 username
= uidtoname(prec
.uid
);
73 if ((fenum
->username
!= NULL
)
74 && !strequal(username
, fenum
->username
)) {
78 fullpath
= talloc_asprintf(fenum
->ctx
, "\\PIPE\\%s", prec
.name
);
83 f
= TALLOC_REALLOC_ARRAY(fenum
->ctx
, fenum
->ctr3
->array
,
84 struct srvsvc_NetFileInfo3
, i
+1);
86 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
89 fenum
->ctr3
->array
= f
;
91 fenum
->ctr3
->array
[i
].fid
=
92 (((uint32_t)(procid_to_pid(&prec
.pid
))<<16) | prec
.pnum
);
93 fenum
->ctr3
->array
[i
].permissions
=
94 (FILE_READ_DATA
|FILE_WRITE_DATA
);
95 fenum
->ctr3
->array
[i
].num_locks
= 0;
96 fenum
->ctr3
->array
[i
].path
= fullpath
;
97 fenum
->ctr3
->array
[i
].user
= username
;
104 /*******************************************************************
105 ********************************************************************/
107 static WERROR
net_enum_pipes(TALLOC_CTX
*ctx
,
108 const char *username
,
109 struct srvsvc_NetFileCtr3
**ctr3
,
112 struct file_enum_count fenum
;
115 fenum
.username
= username
;
118 if (connections_traverse(pipe_enum_fn
, &fenum
) == -1) {
119 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
129 /*******************************************************************
130 ********************************************************************/
132 static void enum_file_fn( const struct share_mode_entry
*e
,
133 const char *sharepath
, const char *fname
,
136 struct file_enum_count
*fenum
=
137 (struct file_enum_count
*)private_data
;
139 struct srvsvc_NetFileInfo3
*f
;
140 int i
= fenum
->ctr3
->count
;
142 struct byte_range_lock
*brl
;
144 char *fullpath
= NULL
;
146 const char *username
;
148 /* If the pid was not found delete the entry from connections.tdb */
150 if ( !process_exists(e
->pid
) ) {
154 username
= uidtoname(e
->uid
);
156 if ((fenum
->username
!= NULL
)
157 && !strequal(username
, fenum
->username
)) {
161 f
= TALLOC_REALLOC_ARRAY(fenum
->ctx
, fenum
->ctr3
->array
,
162 struct srvsvc_NetFileInfo3
, i
+1);
164 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
167 fenum
->ctr3
->array
= f
;
169 /* need to count the number of locks on a file */
174 if ( (brl
= brl_get_locks(talloc_tos(), &fsp
)) != NULL
) {
175 num_locks
= brl
->num_locks
;
179 if ( strcmp( fname
, "." ) == 0 ) {
180 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s", sharepath
);
182 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s/%s",
188 string_replace( fullpath
, '/', '\\' );
190 /* mask out create (what ever that is) */
191 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
193 /* now fill in the srvsvc_NetFileInfo3 struct */
195 fenum
->ctr3
->array
[i
].fid
=
196 (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
197 fenum
->ctr3
->array
[i
].permissions
= permissions
;
198 fenum
->ctr3
->array
[i
].num_locks
= num_locks
;
199 fenum
->ctr3
->array
[i
].path
= fullpath
;
200 fenum
->ctr3
->array
[i
].user
= username
;
202 fenum
->ctr3
->count
++;
205 /*******************************************************************
206 ********************************************************************/
208 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
209 const char *username
,
210 struct srvsvc_NetFileCtr3
**ctr3
,
213 struct file_enum_count f_enum_cnt
;
215 f_enum_cnt
.ctx
= ctx
;
216 f_enum_cnt
.username
= username
;
217 f_enum_cnt
.ctr3
= *ctr3
;
219 share_mode_forall( enum_file_fn
, (void *)&f_enum_cnt
);
221 *ctr3
= f_enum_cnt
.ctr3
;
226 /*******************************************************************
227 Utility function to get the 'type' of a share from an snum.
228 ********************************************************************/
229 static uint32
get_share_type(int snum
)
231 /* work out the share type */
232 uint32 type
= STYPE_DISKTREE
;
234 if (lp_print_ok(snum
))
236 if (strequal(lp_fstype(snum
), "IPC"))
238 if (lp_administrative_share(snum
))
239 type
|= STYPE_HIDDEN
;
244 /*******************************************************************
245 Fill in a share info level 0 structure.
246 ********************************************************************/
248 static void init_srv_share_info_0(pipes_struct
*p
, struct srvsvc_NetShareInfo0
*r
, int snum
)
250 r
->name
= lp_servicename(snum
);
253 /*******************************************************************
254 Fill in a share info level 1 structure.
255 ********************************************************************/
257 static void init_srv_share_info_1(pipes_struct
*p
, struct srvsvc_NetShareInfo1
*r
, int snum
)
259 char *net_name
= lp_servicename(snum
);
260 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
263 remark
= talloc_sub_advanced(
264 p
->mem_ctx
, lp_servicename(snum
),
265 get_current_username(), lp_pathname(snum
),
266 p
->server_info
->utok
.uid
, get_current_username(),
271 r
->type
= get_share_type(snum
);
272 r
->comment
= remark
? remark
: "";
275 /*******************************************************************
276 Fill in a share info level 2 structure.
277 ********************************************************************/
279 static void init_srv_share_info_2(pipes_struct
*p
, struct srvsvc_NetShareInfo2
*r
, int snum
)
283 int max_connections
= lp_max_connections(snum
);
284 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
285 char *net_name
= lp_servicename(snum
);
287 remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
289 remark
= talloc_sub_advanced(
290 p
->mem_ctx
, lp_servicename(snum
),
291 get_current_username(), lp_pathname(snum
),
292 p
->server_info
->utok
.uid
, get_current_username(),
295 path
= talloc_asprintf(p
->mem_ctx
,
296 "C:%s", lp_pathname(snum
));
300 * Change / to \\ so that win2k will see it as a valid path.
301 * This was added to enable use of browsing in win2k add
305 string_replace(path
, '/', '\\');
309 r
->type
= get_share_type(snum
);
310 r
->comment
= remark
? remark
: "";
312 r
->max_users
= max_uses
;
313 r
->current_users
= count_current_connections(net_name
, false);
314 r
->path
= path
? path
: "";
318 /*******************************************************************
319 Map any generic bits to file specific bits.
320 ********************************************************************/
322 static void map_generic_share_sd_bits(SEC_DESC
*psd
)
325 SEC_ACL
*ps_dacl
= NULL
;
334 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
335 SEC_ACE
*psa
= &ps_dacl
->aces
[i
];
336 uint32 orig_mask
= psa
->access_mask
;
338 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
339 psa
->access_mask
|= orig_mask
;
343 /*******************************************************************
344 Fill in a share info level 501 structure.
345 ********************************************************************/
347 static void init_srv_share_info_501(pipes_struct
*p
, struct srvsvc_NetShareInfo501
*r
, int snum
)
349 const char *net_name
= lp_servicename(snum
);
350 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
353 remark
= talloc_sub_advanced(
354 p
->mem_ctx
, lp_servicename(snum
),
355 get_current_username(), lp_pathname(snum
),
356 p
->server_info
->utok
.uid
, get_current_username(),
361 r
->type
= get_share_type(snum
);
362 r
->comment
= remark
? remark
: "";
363 r
->csc_policy
= (lp_csc_policy(snum
) << 4);
366 /*******************************************************************
367 Fill in a share info level 502 structure.
368 ********************************************************************/
370 static void init_srv_share_info_502(pipes_struct
*p
, struct srvsvc_NetShareInfo502
*r
, int snum
)
372 const char *net_name
= lp_servicename(snum
);
375 struct sec_desc_buf
*sd_buf
= NULL
;
377 TALLOC_CTX
*ctx
= p
->mem_ctx
;
378 char *remark
= talloc_strdup(ctx
, lp_comment(snum
));;
381 remark
= talloc_sub_advanced(
382 p
->mem_ctx
, lp_servicename(snum
),
383 get_current_username(), lp_pathname(snum
),
384 p
->server_info
->utok
.uid
, get_current_username(),
387 path
= talloc_asprintf(ctx
, "C:%s", lp_pathname(snum
));
390 * Change / to \\ so that win2k will see it as a valid path. This was added to
391 * enable use of browsing in win2k add share dialog.
393 string_replace(path
, '/', '\\');
396 sd
= get_share_security(ctx
, lp_servicename(snum
), &sd_size
);
398 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
401 r
->type
= get_share_type(snum
);
402 r
->comment
= remark
? remark
: "";
404 r
->max_users
= (uint32_t)-1;
405 r
->current_users
= 1; /* ??? */
406 r
->path
= path
? path
: "";
411 /***************************************************************************
412 Fill in a share info level 1004 structure.
413 ***************************************************************************/
415 static void init_srv_share_info_1004(pipes_struct
*p
, struct srvsvc_NetShareInfo1004
*r
, int snum
)
417 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
420 remark
= talloc_sub_advanced(
421 p
->mem_ctx
, lp_servicename(snum
),
422 get_current_username(), lp_pathname(snum
),
423 p
->server_info
->utok
.uid
, get_current_username(),
427 r
->comment
= remark
? remark
: "";
430 /***************************************************************************
431 Fill in a share info level 1005 structure.
432 ***************************************************************************/
434 static void init_srv_share_info_1005(pipes_struct
*p
, struct srvsvc_NetShareInfo1005
*r
, int snum
)
436 uint32_t dfs_flags
= 0;
438 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
439 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
442 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
444 r
->dfs_flags
= dfs_flags
;
447 /***************************************************************************
448 Fill in a share info level 1006 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1006(pipes_struct
*p
, struct srvsvc_NetShareInfo1006
*r
, int snum
)
453 r
->max_users
= (uint32_t)-1;
456 /***************************************************************************
457 Fill in a share info level 1007 structure.
458 ***************************************************************************/
460 static void init_srv_share_info_1007(pipes_struct
*p
, struct srvsvc_NetShareInfo1007
*r
, int snum
)
463 r
->alternate_directory_name
= "";
466 /*******************************************************************
467 Fill in a share info level 1501 structure.
468 ********************************************************************/
470 static void init_srv_share_info_1501(pipes_struct
*p
, struct sec_desc_buf
*r
, int snum
)
474 TALLOC_CTX
*ctx
= p
->mem_ctx
;
476 sd
= get_share_security(ctx
, lp_servicename(snum
), &sd_size
);
478 r
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
481 /*******************************************************************
482 True if it ends in '$'.
483 ********************************************************************/
485 static bool is_hidden_share(int snum
)
487 const char *net_name
= lp_servicename(snum
);
489 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
492 /*******************************************************************
493 Verify user is allowed to view share, access based enumeration
494 ********************************************************************/
495 static bool is_enumeration_allowed(pipes_struct
*p
,
498 if (!lp_access_based_share_enum(snum
))
501 return share_access_check(p
->server_info
->ptok
, lp_servicename(snum
),
505 /*******************************************************************
506 Fill in a share info structure.
507 ********************************************************************/
509 static WERROR
init_srv_share_info_ctr(pipes_struct
*p
,
510 struct srvsvc_NetShareInfoCtr
*info_ctr
,
511 uint32_t *resume_handle_p
,
512 uint32_t *total_entries
,
516 int alloc_entries
= 0;
517 int num_services
= 0;
519 TALLOC_CTX
*ctx
= p
->mem_ctx
;
521 int valid_share_count
= 0;
523 union srvsvc_NetShareCtr ctr
;
524 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
526 DEBUG(5,("init_srv_share_info_ctr\n"));
528 /* Ensure all the usershares are loaded. */
530 load_usershare_shares();
531 load_registry_shares();
532 num_services
= lp_numservices();
535 allowed
= TALLOC_ZERO_ARRAY(ctx
, bool, num_services
);
536 W_ERROR_HAVE_NO_MEMORY(allowed
);
538 /* Count the number of entries. */
539 for (snum
= 0; snum
< num_services
; snum
++) {
540 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
541 is_enumeration_allowed(p
, snum
) &&
542 (all_shares
|| !is_hidden_share(snum
)) ) {
543 DEBUG(10, ("counting service %s\n", lp_servicename(snum
)));
544 allowed
[snum
] = true;
547 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum
)));
551 if (!num_entries
|| (resume_handle
>= num_entries
)) {
555 /* Calculate alloc entries. */
556 alloc_entries
= num_entries
- resume_handle
;
557 switch (info_ctr
->level
) {
559 ctr
.ctr0
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr0
);
560 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
562 ctr
.ctr0
->count
= alloc_entries
;
563 ctr
.ctr0
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
564 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
566 for (snum
= 0; snum
< num_services
; snum
++) {
568 (resume_handle
<= (i
+ valid_share_count
++)) ) {
569 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
576 ctr
.ctr1
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr1
);
577 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
579 ctr
.ctr1
->count
= alloc_entries
;
580 ctr
.ctr1
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
581 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
583 for (snum
= 0; snum
< num_services
; snum
++) {
585 (resume_handle
<= (i
+ valid_share_count
++)) ) {
586 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
593 ctr
.ctr2
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr2
);
594 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
596 ctr
.ctr2
->count
= alloc_entries
;
597 ctr
.ctr2
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
598 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
600 for (snum
= 0; snum
< num_services
; snum
++) {
602 (resume_handle
<= (i
+ valid_share_count
++)) ) {
603 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
610 ctr
.ctr501
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr501
);
611 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
613 ctr
.ctr501
->count
= alloc_entries
;
614 ctr
.ctr501
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
615 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
617 for (snum
= 0; snum
< num_services
; snum
++) {
619 (resume_handle
<= (i
+ valid_share_count
++)) ) {
620 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
627 ctr
.ctr502
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr502
);
628 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
630 ctr
.ctr502
->count
= alloc_entries
;
631 ctr
.ctr502
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
632 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
634 for (snum
= 0; snum
< num_services
; snum
++) {
636 (resume_handle
<= (i
+ valid_share_count
++)) ) {
637 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
644 ctr
.ctr1004
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr1004
);
645 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
647 ctr
.ctr1004
->count
= alloc_entries
;
648 ctr
.ctr1004
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
649 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
651 for (snum
= 0; snum
< num_services
; snum
++) {
653 (resume_handle
<= (i
+ valid_share_count
++)) ) {
654 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
661 ctr
.ctr1005
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr1005
);
662 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
664 ctr
.ctr1005
->count
= alloc_entries
;
665 ctr
.ctr1005
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
666 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
668 for (snum
= 0; snum
< num_services
; snum
++) {
670 (resume_handle
<= (i
+ valid_share_count
++)) ) {
671 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
678 ctr
.ctr1006
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr1006
);
679 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
681 ctr
.ctr1006
->count
= alloc_entries
;
682 ctr
.ctr1006
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
683 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
685 for (snum
= 0; snum
< num_services
; snum
++) {
687 (resume_handle
<= (i
+ valid_share_count
++)) ) {
688 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
695 ctr
.ctr1007
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr1007
);
696 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
698 ctr
.ctr1007
->count
= alloc_entries
;
699 ctr
.ctr1007
->array
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
700 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
702 for (snum
= 0; snum
< num_services
; snum
++) {
704 (resume_handle
<= (i
+ valid_share_count
++)) ) {
705 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
712 ctr
.ctr1501
= TALLOC_ZERO_P(ctx
, struct srvsvc_NetShareCtr1501
);
713 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
715 ctr
.ctr1501
->count
= alloc_entries
;
716 ctr
.ctr1501
->array
= TALLOC_ZERO_ARRAY(ctx
, struct sec_desc_buf
, alloc_entries
);
717 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
719 for (snum
= 0; snum
< num_services
; snum
++) {
721 (resume_handle
<= (i
+ valid_share_count
++)) ) {
722 init_srv_share_info_1501(p
, &ctr
.ctr1501
->array
[i
++], snum
);
729 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
731 return WERR_UNKNOWN_LEVEL
;
734 *total_entries
= alloc_entries
;
735 if (resume_handle_p
) {
737 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
739 *resume_handle_p
= num_entries
;
748 /*******************************************************************
749 fill in a sess info level 0 structure.
750 ********************************************************************/
752 static WERROR
init_srv_sess_info_0(pipes_struct
*p
,
753 struct srvsvc_NetSessCtr0
*ctr0
,
754 uint32_t *resume_handle_p
,
755 uint32_t *total_entries
)
757 struct sessionid
*session_list
;
758 uint32_t num_entries
= 0;
759 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
760 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
762 DEBUG(5,("init_srv_sess_info_0\n"));
765 if (resume_handle_p
) {
766 *resume_handle_p
= 0;
771 for (; resume_handle
< *total_entries
; resume_handle
++) {
773 ctr0
->array
= TALLOC_REALLOC_ARRAY(p
->mem_ctx
,
775 struct srvsvc_NetSessInfo0
,
777 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
779 ctr0
->array
[num_entries
].client
=
780 session_list
[resume_handle
].remote_machine
;
785 ctr0
->count
= num_entries
;
787 if (resume_handle_p
) {
788 if (*resume_handle_p
>= *total_entries
) {
789 *resume_handle_p
= 0;
791 *resume_handle_p
= resume_handle
;
798 /*******************************************************************
799 ********************************************************************/
801 static void sess_file_fn( const struct share_mode_entry
*e
,
802 const char *sharepath
, const char *fname
,
805 struct sess_file_count
*sess
= (struct sess_file_count
*)data
;
807 if ( procid_equal(&e
->pid
, &sess
->pid
) && (sess
->uid
== e
->uid
) ) {
814 /*******************************************************************
815 ********************************************************************/
817 static int net_count_files( uid_t uid
, struct server_id pid
)
819 struct sess_file_count s_file_cnt
;
821 s_file_cnt
.count
= 0;
822 s_file_cnt
.uid
= uid
;
823 s_file_cnt
.pid
= pid
;
825 share_mode_forall( sess_file_fn
, &s_file_cnt
);
827 return s_file_cnt
.count
;
830 /*******************************************************************
831 fill in a sess info level 1 structure.
832 ********************************************************************/
834 static WERROR
init_srv_sess_info_1(pipes_struct
*p
,
835 struct srvsvc_NetSessCtr1
*ctr1
,
836 uint32_t *resume_handle_p
,
837 uint32_t *total_entries
)
839 struct sessionid
*session_list
;
840 uint32_t num_entries
= 0;
841 time_t now
= time(NULL
);
842 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
847 if (resume_handle_p
) {
848 *resume_handle_p
= 0;
853 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
855 for (; resume_handle
< *total_entries
; resume_handle
++) {
858 struct passwd
*pw
= sys_getpwnam(session_list
[resume_handle
].username
);
862 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
863 session_list
[resume_handle
].username
));
867 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
868 num_files
= net_count_files(pw
->pw_uid
, session_list
[resume_handle
].pid
);
869 guest
= strequal( session_list
[resume_handle
].username
, lp_guestaccount() );
871 ctr1
->array
= TALLOC_REALLOC_ARRAY(p
->mem_ctx
,
873 struct srvsvc_NetSessInfo1
,
875 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
877 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
878 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
879 ctr1
->array
[num_entries
].num_open
= num_files
;
880 ctr1
->array
[num_entries
].time
= connect_time
;
881 ctr1
->array
[num_entries
].idle_time
= 0;
882 ctr1
->array
[num_entries
].user_flags
= guest
;
887 ctr1
->count
= num_entries
;
889 if (resume_handle_p
) {
890 if (*resume_handle_p
>= *total_entries
) {
891 *resume_handle_p
= 0;
893 *resume_handle_p
= resume_handle
;
900 /*******************************************************************
901 fill in a conn info level 0 structure.
902 ********************************************************************/
904 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
905 uint32_t *resume_handle_p
,
906 uint32_t *total_entries
)
908 uint32_t num_entries
= 0;
909 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
911 DEBUG(5,("init_srv_conn_info_0\n"));
914 if (resume_handle_p
) {
915 *resume_handle_p
= 0;
924 for (; resume_handle
< *total_entries
; resume_handle
++) {
926 ctr0
->array
= TALLOC_REALLOC_ARRAY(talloc_tos(),
928 struct srvsvc_NetConnInfo0
,
934 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
936 /* move on to creating next connection */
940 ctr0
->count
= num_entries
;
941 *total_entries
= num_entries
;
943 if (resume_handle_p
) {
944 if (*resume_handle_p
>= *total_entries
) {
945 *resume_handle_p
= 0;
947 *resume_handle_p
= resume_handle
;
954 /*******************************************************************
955 fill in a conn info level 1 structure.
956 ********************************************************************/
958 static WERROR
init_srv_conn_info_1(struct srvsvc_NetConnCtr1
*ctr1
,
959 uint32_t *resume_handle_p
,
960 uint32_t *total_entries
)
962 uint32_t num_entries
= 0;
963 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
965 DEBUG(5,("init_srv_conn_info_1\n"));
968 if (resume_handle_p
) {
969 *resume_handle_p
= 0;
978 for (; resume_handle
< *total_entries
; resume_handle
++) {
980 ctr1
->array
= TALLOC_REALLOC_ARRAY(talloc_tos(),
982 struct srvsvc_NetConnInfo1
,
988 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
989 ctr1
->array
[num_entries
].conn_type
= 0x3;
990 ctr1
->array
[num_entries
].num_open
= 1;
991 ctr1
->array
[num_entries
].num_users
= 1;
992 ctr1
->array
[num_entries
].conn_time
= 3;
993 ctr1
->array
[num_entries
].user
= "dummy_user";
994 ctr1
->array
[num_entries
].share
= "IPC$";
996 /* move on to creating next connection */
1000 ctr1
->count
= num_entries
;
1001 *total_entries
= num_entries
;
1003 if (resume_handle_p
) {
1004 if (*resume_handle_p
>= *total_entries
) {
1005 *resume_handle_p
= 0;
1007 *resume_handle_p
= resume_handle
;
1014 /*******************************************************************
1016 *******************************************************************/
1018 WERROR
_srvsvc_NetFileEnum(pipes_struct
*p
,
1019 struct srvsvc_NetFileEnum
*r
)
1021 TALLOC_CTX
*ctx
= NULL
;
1022 struct srvsvc_NetFileCtr3
*ctr3
;
1023 uint32_t resume_hnd
= 0;
1026 switch (r
->in
.info_ctr
->level
) {
1030 return WERR_UNKNOWN_LEVEL
;
1034 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1036 werr
= WERR_INVALID_PARAM
;
1040 /* TODO -- Windows enumerates
1042 (c) open directories and files */
1044 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1045 if (!W_ERROR_IS_OK(werr
)) {
1049 werr
= net_enum_pipes(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1050 if (!W_ERROR_IS_OK(werr
)) {
1054 *r
->out
.totalentries
= ctr3
->count
;
1055 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1056 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1064 /*******************************************************************
1065 _srvsvc_NetSrvGetInfo
1066 ********************************************************************/
1068 WERROR
_srvsvc_NetSrvGetInfo(pipes_struct
*p
,
1069 struct srvsvc_NetSrvGetInfo
*r
)
1071 WERROR status
= WERR_OK
;
1073 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1075 if (!pipe_access_check(p
)) {
1076 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1077 return WERR_ACCESS_DENIED
;
1080 switch (r
->in
.level
) {
1082 /* Technically level 102 should only be available to
1083 Administrators but there isn't anything super-secret
1084 here, as most of it is made up. */
1087 struct srvsvc_NetSrvInfo102
*info102
;
1089 info102
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1094 info102
->platform_id
= PLATFORM_ID_NT
;
1095 info102
->server_name
= global_myname();
1096 info102
->version_major
= lp_major_announce_version();
1097 info102
->version_minor
= lp_minor_announce_version();
1098 info102
->server_type
= lp_default_server_announce();
1099 info102
->comment
= string_truncate(lp_serverstring(),
1100 MAX_SERVER_STRING_LENGTH
);
1101 info102
->users
= 0xffffffff;
1102 info102
->disc
= 0xf;
1103 info102
->hidden
= 0;
1104 info102
->announce
= 240;
1105 info102
->anndelta
= 3000;
1106 info102
->licenses
= 100000;
1107 info102
->userpath
= "C:\\";
1109 r
->out
.info
->info102
= info102
;
1113 struct srvsvc_NetSrvInfo101
*info101
;
1115 info101
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1120 info101
->platform_id
= PLATFORM_ID_NT
;
1121 info101
->server_name
= global_myname();
1122 info101
->version_major
= lp_major_announce_version();
1123 info101
->version_minor
= lp_minor_announce_version();
1124 info101
->server_type
= lp_default_server_announce();
1125 info101
->comment
= string_truncate(lp_serverstring(),
1126 MAX_SERVER_STRING_LENGTH
);
1128 r
->out
.info
->info101
= info101
;
1132 struct srvsvc_NetSrvInfo100
*info100
;
1134 info100
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1139 info100
->platform_id
= PLATFORM_ID_NT
;
1140 info100
->server_name
= global_myname();
1142 r
->out
.info
->info100
= info100
;
1147 status
= WERR_UNKNOWN_LEVEL
;
1151 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1156 /*******************************************************************
1157 _srvsvc_NetSrvSetInfo
1158 ********************************************************************/
1160 WERROR
_srvsvc_NetSrvSetInfo(pipes_struct
*p
,
1161 struct srvsvc_NetSrvSetInfo
*r
)
1163 WERROR status
= WERR_OK
;
1165 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1167 /* Set up the net server set info structure. */
1169 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1174 /*******************************************************************
1176 ********************************************************************/
1178 WERROR
_srvsvc_NetConnEnum(pipes_struct
*p
,
1179 struct srvsvc_NetConnEnum
*r
)
1183 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1185 switch (r
->in
.info_ctr
->level
) {
1187 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1188 r
->in
.resume_handle
,
1189 r
->out
.totalentries
);
1192 werr
= init_srv_conn_info_1(r
->in
.info_ctr
->ctr
.ctr1
,
1193 r
->in
.resume_handle
,
1194 r
->out
.totalentries
);
1197 return WERR_UNKNOWN_LEVEL
;
1200 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1205 /*******************************************************************
1207 ********************************************************************/
1209 WERROR
_srvsvc_NetSessEnum(pipes_struct
*p
,
1210 struct srvsvc_NetSessEnum
*r
)
1214 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1216 switch (r
->in
.info_ctr
->level
) {
1218 werr
= init_srv_sess_info_0(p
,
1219 r
->in
.info_ctr
->ctr
.ctr0
,
1220 r
->in
.resume_handle
,
1221 r
->out
.totalentries
);
1224 werr
= init_srv_sess_info_1(p
,
1225 r
->in
.info_ctr
->ctr
.ctr1
,
1226 r
->in
.resume_handle
,
1227 r
->out
.totalentries
);
1230 return WERR_UNKNOWN_LEVEL
;
1233 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1238 /*******************************************************************
1240 ********************************************************************/
1242 WERROR
_srvsvc_NetSessDel(pipes_struct
*p
,
1243 struct srvsvc_NetSessDel
*r
)
1245 struct sessionid
*session_list
;
1246 int num_sessions
, snum
;
1247 const char *username
;
1248 const char *machine
;
1249 bool not_root
= False
;
1252 username
= r
->in
.user
;
1253 machine
= r
->in
.client
;
1255 /* strip leading backslashes if any */
1256 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1260 num_sessions
= list_sessions(p
->mem_ctx
, &session_list
);
1262 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1264 werr
= WERR_ACCESS_DENIED
;
1266 /* fail out now if you are not root or not a domain admin */
1268 if ((p
->server_info
->utok
.uid
!= sec_initial_uid()) &&
1269 ( ! nt_token_check_domain_rid(p
->server_info
->ptok
,
1270 DOMAIN_GROUP_RID_ADMINS
))) {
1275 for (snum
= 0; snum
< num_sessions
; snum
++) {
1277 if ((strequal(session_list
[snum
].username
, username
) || username
[0] == '\0' ) &&
1278 strequal(session_list
[snum
].remote_machine
, machine
)) {
1282 if (p
->server_info
->utok
.uid
!= sec_initial_uid()) {
1287 ntstat
= messaging_send(smbd_messaging_context(),
1288 session_list
[snum
].pid
,
1289 MSG_SHUTDOWN
, &data_blob_null
);
1291 if (NT_STATUS_IS_OK(ntstat
))
1299 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1306 /*******************************************************************
1307 _srvsvc_NetShareEnumAll
1308 ********************************************************************/
1310 WERROR
_srvsvc_NetShareEnumAll(pipes_struct
*p
,
1311 struct srvsvc_NetShareEnumAll
*r
)
1315 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1317 if (!pipe_access_check(p
)) {
1318 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1319 return WERR_ACCESS_DENIED
;
1322 /* Create the list of shares for the response. */
1323 werr
= init_srv_share_info_ctr(p
,
1325 r
->in
.resume_handle
,
1326 r
->out
.totalentries
,
1329 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1334 /*******************************************************************
1335 _srvsvc_NetShareEnum
1336 ********************************************************************/
1338 WERROR
_srvsvc_NetShareEnum(pipes_struct
*p
,
1339 struct srvsvc_NetShareEnum
*r
)
1343 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1345 if (!pipe_access_check(p
)) {
1346 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1347 return WERR_ACCESS_DENIED
;
1350 /* Create the list of shares for the response. */
1351 werr
= init_srv_share_info_ctr(p
,
1353 r
->in
.resume_handle
,
1354 r
->out
.totalentries
,
1357 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1362 /*******************************************************************
1363 _srvsvc_NetShareGetInfo
1364 ********************************************************************/
1366 WERROR
_srvsvc_NetShareGetInfo(pipes_struct
*p
,
1367 struct srvsvc_NetShareGetInfo
*r
)
1369 WERROR status
= WERR_OK
;
1372 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1374 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1376 fstrcpy(share_name
, r
->in
.share_name
);
1378 snum
= find_service(share_name
);
1380 return WERR_INVALID_NAME
;
1383 switch (r
->in
.level
) {
1385 info
->info0
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1386 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1387 init_srv_share_info_0(p
, info
->info0
, snum
);
1390 info
->info1
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1391 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1392 init_srv_share_info_1(p
, info
->info1
, snum
);
1395 info
->info2
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1396 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1397 init_srv_share_info_2(p
, info
->info2
, snum
);
1400 info
->info501
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1401 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1402 init_srv_share_info_501(p
, info
->info501
, snum
);
1405 info
->info502
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1406 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1407 init_srv_share_info_502(p
, info
->info502
, snum
);
1410 info
->info1004
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1411 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1412 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1415 info
->info1005
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1416 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1417 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1420 info
->info1006
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1421 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1422 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1425 info
->info1007
= TALLOC_P(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1426 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1427 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1430 init_srv_share_info_1501(p
, info
->info1501
, snum
);
1433 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1435 status
= WERR_UNKNOWN_LEVEL
;
1439 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1444 /*******************************************************************
1445 Check a given DOS pathname is valid for a share.
1446 ********************************************************************/
1448 char *valid_share_pathname(TALLOC_CTX
*ctx
, const char *dos_pathname
)
1452 if (!dos_pathname
) {
1456 ptr
= talloc_strdup(ctx
, dos_pathname
);
1460 /* Convert any '\' paths to '/' */
1462 ptr
= unix_clean_name(ctx
, ptr
);
1467 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1468 if (strlen(ptr
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
1471 /* Only absolute paths allowed. */
1478 /*******************************************************************
1479 _srvsvc_NetShareSetInfo. Modify share details.
1480 ********************************************************************/
1482 WERROR
_srvsvc_NetShareSetInfo(pipes_struct
*p
,
1483 struct srvsvc_NetShareSetInfo
*r
)
1485 char *command
= NULL
;
1486 char *share_name
= NULL
;
1487 char *comment
= NULL
;
1488 const char *pathname
= NULL
;
1493 SEC_DESC
*psd
= NULL
;
1494 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
1495 bool is_disk_op
= False
;
1496 int max_connections
= 0;
1497 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1498 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1500 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1502 share_name
= talloc_strdup(p
->mem_ctx
, r
->in
.share_name
);
1507 if (r
->out
.parm_error
) {
1508 *r
->out
.parm_error
= 0;
1511 if ( strequal(share_name
,"IPC$")
1512 || ( lp_enable_asu_support() && strequal(share_name
,"ADMIN$") )
1513 || strequal(share_name
,"global") )
1515 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1516 "modified by a remote user.\n",
1518 return WERR_ACCESS_DENIED
;
1521 snum
= find_service(share_name
);
1523 /* Does this share exist ? */
1525 return WERR_NET_NAME_NOT_FOUND
;
1527 /* No change to printer shares. */
1528 if (lp_print_ok(snum
))
1529 return WERR_ACCESS_DENIED
;
1531 is_disk_op
= user_has_privileges( p
->server_info
->ptok
, &se_diskop
);
1533 /* fail out now if you are not root and not a disk op */
1535 if ( p
->server_info
->utok
.uid
!= sec_initial_uid() && !is_disk_op
) {
1536 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1537 "SeDiskOperatorPrivilege privilege needed to modify "
1539 (unsigned int)p
->server_info
->utok
.uid
,
1541 return WERR_ACCESS_DENIED
;
1544 switch (r
->in
.level
) {
1546 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1547 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1548 type
= info
->info1
->type
;
1552 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1553 pathname
= info
->info2
->path
;
1554 type
= info
->info2
->type
;
1555 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1556 0 : info
->info2
->max_users
;
1560 /* not supported on set but here for completeness */
1562 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1563 type
= info
->info501
->type
;
1568 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1569 pathname
= info
->info502
->path
;
1570 type
= info
->info502
->type
;
1571 psd
= info
->info502
->sd_buf
.sd
;
1572 map_generic_share_sd_bits(psd
);
1575 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1576 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1577 type
= STYPE_DISKTREE
;
1580 /* XP re-sets the csc policy even if it wasn't changed by the
1581 user, so we must compare it to see if it's what is set in
1582 smb.conf, so that we can contine other ops like setting
1584 if (((info
->info1005
->dfs_flags
&
1585 SHARE_1005_CSC_POLICY_MASK
) >>
1586 SHARE_1005_CSC_POLICY_SHIFT
) == lp_csc_policy(snum
))
1589 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1590 return WERR_ACCESS_DENIED
;
1594 return WERR_ACCESS_DENIED
;
1596 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1597 comment
= talloc_strdup(ctx
, lp_comment(snum
));
1598 psd
= info
->info1501
->sd
;
1599 map_generic_share_sd_bits(psd
);
1600 type
= STYPE_DISKTREE
;
1603 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1605 return WERR_UNKNOWN_LEVEL
;
1608 /* We can only modify disk shares. */
1609 if (type
!= STYPE_DISKTREE
) {
1610 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1613 return WERR_ACCESS_DENIED
;
1616 if (comment
== NULL
) {
1620 /* Check if the pathname is valid. */
1621 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1622 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1624 return WERR_OBJECT_PATH_INVALID
;
1627 /* Ensure share name, pathname and comment don't contain '"' characters. */
1628 string_replace(share_name
, '"', ' ');
1629 string_replace(path
, '"', ' ');
1630 string_replace(comment
, '"', ' ');
1632 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1633 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1635 /* Only call modify function if something changed. */
1637 if (strcmp(path
, lp_pathname(snum
)) || strcmp(comment
, lp_comment(snum
))
1638 || (lp_max_connections(snum
) != max_connections
)) {
1639 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1640 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1641 return WERR_ACCESS_DENIED
;
1644 command
= talloc_asprintf(p
->mem_ctx
,
1645 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1646 lp_change_share_cmd(),
1647 get_dyn_CONFIGFILE(),
1650 comment
? comment
: "",
1656 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1658 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1663 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1664 /* Tell everyone we updated smb.conf. */
1665 message_send_all(smbd_messaging_context(),
1666 MSG_SMB_CONF_UPDATED
, NULL
, 0,
1673 /********* END SeDiskOperatorPrivilege BLOCK *********/
1675 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1678 TALLOC_FREE(command
);
1681 return WERR_ACCESS_DENIED
;
1683 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1687 /* Replace SD if changed. */
1692 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(snum
), &sd_size
);
1694 if (old_sd
&& !sec_desc_equal(old_sd
, psd
)) {
1695 if (!set_share_security(share_name
, psd
))
1696 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1701 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1706 /*******************************************************************
1707 _srvsvc_NetShareAdd.
1708 Call 'add_share_command "sharename" "pathname"
1709 "comment" "max connections = "
1710 ********************************************************************/
1712 WERROR
_srvsvc_NetShareAdd(pipes_struct
*p
,
1713 struct srvsvc_NetShareAdd
*r
)
1715 char *command
= NULL
;
1716 char *share_name
= NULL
;
1717 char *comment
= NULL
;
1718 char *pathname
= NULL
;
1723 SEC_DESC
*psd
= NULL
;
1724 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
1726 int max_connections
= 0;
1727 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1729 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1731 if (r
->out
.parm_error
) {
1732 *r
->out
.parm_error
= 0;
1735 is_disk_op
= user_has_privileges( p
->server_info
->ptok
, &se_diskop
);
1737 if (p
->server_info
->utok
.uid
!= sec_initial_uid() && !is_disk_op
)
1738 return WERR_ACCESS_DENIED
;
1740 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1741 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1742 return WERR_ACCESS_DENIED
;
1745 switch (r
->in
.level
) {
1747 /* No path. Not enough info in a level 0 to do anything. */
1748 return WERR_ACCESS_DENIED
;
1750 /* Not enough info in a level 1 to do anything. */
1751 return WERR_ACCESS_DENIED
;
1753 share_name
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1754 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1755 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1756 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1757 0 : r
->in
.info
->info2
->max_users
;
1758 type
= r
->in
.info
->info2
->type
;
1761 /* No path. Not enough info in a level 501 to do anything. */
1762 return WERR_ACCESS_DENIED
;
1764 share_name
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1765 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1766 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1767 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1768 0 : r
->in
.info
->info502
->max_users
;
1769 type
= r
->in
.info
->info502
->type
;
1770 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1771 map_generic_share_sd_bits(psd
);
1774 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1780 return WERR_ACCESS_DENIED
;
1782 /* DFS only level. */
1783 return WERR_ACCESS_DENIED
;
1785 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1787 return WERR_UNKNOWN_LEVEL
;
1790 /* check for invalid share names */
1792 if (!share_name
|| !validate_net_name(share_name
,
1793 INVALID_SHARENAME_CHARS
,
1794 strlen(share_name
))) {
1795 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1796 share_name
? share_name
: ""));
1797 return WERR_INVALID_NAME
;
1800 if (strequal(share_name
,"IPC$") || strequal(share_name
,"global")
1801 || (lp_enable_asu_support() &&
1802 strequal(share_name
,"ADMIN$"))) {
1803 return WERR_ACCESS_DENIED
;
1806 snum
= find_service(share_name
);
1808 /* Share already exists. */
1810 return WERR_FILE_EXISTS
;
1813 /* We can only add disk shares. */
1814 if (type
!= STYPE_DISKTREE
) {
1815 return WERR_ACCESS_DENIED
;
1818 /* Check if the pathname is valid. */
1819 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1820 return WERR_OBJECT_PATH_INVALID
;
1823 /* Ensure share name, pathname and comment don't contain '"' characters. */
1824 string_replace(share_name
, '"', ' ');
1825 string_replace(path
, '"', ' ');
1827 string_replace(comment
, '"', ' ');
1830 command
= talloc_asprintf(ctx
,
1831 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1833 get_dyn_CONFIGFILE(),
1836 comment
? comment
: "",
1842 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
1844 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1849 /* FIXME: use libnetconf here - gd */
1851 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1852 /* Tell everyone we updated smb.conf. */
1853 message_send_all(smbd_messaging_context(),
1854 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
1860 /********* END SeDiskOperatorPrivilege BLOCK *********/
1862 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1865 TALLOC_FREE(command
);
1868 return WERR_ACCESS_DENIED
;
1871 if (!set_share_security(share_name
, psd
)) {
1872 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1878 * We don't call reload_services() here, the message will
1879 * cause this to be done before the next packet is read
1880 * from the client. JRA.
1883 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1888 /*******************************************************************
1890 Call "delete share command" with the share name as
1892 ********************************************************************/
1894 WERROR
_srvsvc_NetShareDel(pipes_struct
*p
,
1895 struct srvsvc_NetShareDel
*r
)
1897 char *command
= NULL
;
1898 char *share_name
= NULL
;
1901 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
1903 struct share_params
*params
;
1904 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1906 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
1908 share_name
= talloc_strdup(p
->mem_ctx
, r
->in
.share_name
);
1910 return WERR_NET_NAME_NOT_FOUND
;
1912 if ( strequal(share_name
,"IPC$")
1913 || ( lp_enable_asu_support() && strequal(share_name
,"ADMIN$") )
1914 || strequal(share_name
,"global") )
1916 return WERR_ACCESS_DENIED
;
1919 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
1920 return WERR_NO_SUCH_SHARE
;
1923 snum
= find_service(share_name
);
1925 /* No change to printer shares. */
1926 if (lp_print_ok(snum
))
1927 return WERR_ACCESS_DENIED
;
1929 is_disk_op
= user_has_privileges( p
->server_info
->ptok
, &se_diskop
);
1931 if (p
->server_info
->utok
.uid
!= sec_initial_uid() && !is_disk_op
)
1932 return WERR_ACCESS_DENIED
;
1934 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1935 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1936 return WERR_ACCESS_DENIED
;
1939 command
= talloc_asprintf(ctx
,
1941 lp_delete_share_cmd(),
1942 get_dyn_CONFIGFILE(),
1943 lp_servicename(snum
));
1948 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
1950 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1955 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1956 /* Tell everyone we updated smb.conf. */
1957 message_send_all(smbd_messaging_context(),
1958 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
1964 /********* END SeDiskOperatorPrivilege BLOCK *********/
1966 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
1969 return WERR_ACCESS_DENIED
;
1971 /* Delete the SD in the database. */
1972 delete_share_security(lp_servicename(params
->service
));
1974 lp_killservice(params
->service
);
1979 /*******************************************************************
1980 _srvsvc_NetShareDelSticky
1981 ********************************************************************/
1983 WERROR
_srvsvc_NetShareDelSticky(pipes_struct
*p
,
1984 struct srvsvc_NetShareDelSticky
*r
)
1986 struct srvsvc_NetShareDel q
;
1988 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
1990 q
.in
.server_unc
= r
->in
.server_unc
;
1991 q
.in
.share_name
= r
->in
.share_name
;
1992 q
.in
.reserved
= r
->in
.reserved
;
1994 return _srvsvc_NetShareDel(p
, &q
);
1997 /*******************************************************************
1998 _srvsvc_NetRemoteTOD
1999 ********************************************************************/
2001 WERROR
_srvsvc_NetRemoteTOD(pipes_struct
*p
,
2002 struct srvsvc_NetRemoteTOD
*r
)
2004 struct srvsvc_NetRemoteTODInfo
*tod
;
2006 time_t unixdate
= time(NULL
);
2008 /* We do this call first as if we do it *after* the gmtime call
2009 it overwrites the pointed-to values. JRA */
2011 uint32 zone
= get_time_zone(unixdate
)/60;
2013 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2015 if ( !(tod
= TALLOC_ZERO_P(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2020 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2022 t
= gmtime(&unixdate
);
2025 tod
->elapsed
= unixdate
;
2027 tod
->hours
= t
->tm_hour
;
2028 tod
->mins
= t
->tm_min
;
2029 tod
->secs
= t
->tm_sec
;
2031 tod
->timezone
= zone
;
2032 tod
->tinterval
= 10000;
2033 tod
->day
= t
->tm_mday
;
2034 tod
->month
= t
->tm_mon
+ 1;
2035 tod
->year
= 1900+t
->tm_year
;
2036 tod
->weekday
= t
->tm_wday
;
2038 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2043 /***********************************************************************************
2044 _srvsvc_NetGetFileSecurity
2045 Win9x NT tools get security descriptor.
2046 ***********************************************************************************/
2048 WERROR
_srvsvc_NetGetFileSecurity(pipes_struct
*p
,
2049 struct srvsvc_NetGetFileSecurity
*r
)
2051 SEC_DESC
*psd
= NULL
;
2053 fstring servicename
;
2057 connection_struct
*conn
= NULL
;
2058 struct sec_desc_buf
*sd_buf
= NULL
;
2059 files_struct
*fsp
= NULL
;
2061 char *oldcwd
= NULL
;
2065 fstrcpy(servicename
, r
->in
.share
);
2067 snum
= find_service(servicename
);
2069 DEBUG(10, ("Could not find service %s\n", servicename
));
2070 werr
= WERR_NET_NAME_NOT_FOUND
;
2074 nt_status
= create_conn_struct(talloc_tos(), &conn
, snum
,
2075 lp_pathname(snum
), p
->server_info
,
2077 if (!NT_STATUS_IS_OK(nt_status
)) {
2078 DEBUG(10, ("create_conn_struct failed: %s\n",
2079 nt_errstr(nt_status
)));
2080 werr
= ntstatus_to_werror(nt_status
);
2084 nt_status
= SMB_VFS_CREATE_FILE(
2087 0, /* root_dir_fid */
2088 r
->in
.file
, /* fname */
2089 CFF_DOS_PATH
, /* create_file_flags */
2090 FILE_READ_ATTRIBUTES
, /* access_mask */
2091 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2092 FILE_OPEN
, /* create_disposition*/
2093 0, /* create_options */
2094 0, /* file_attributes */
2095 INTERNAL_OPEN_ONLY
, /* oplock_request */
2096 0, /* allocation_size */
2103 if (!NT_STATUS_IS_OK(nt_status
)) {
2104 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2106 werr
= ntstatus_to_werror(nt_status
);
2110 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2111 (OWNER_SECURITY_INFORMATION
2112 |GROUP_SECURITY_INFORMATION
2113 |DACL_SECURITY_INFORMATION
), &psd
);
2115 if (!NT_STATUS_IS_OK(nt_status
)) {
2116 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2117 "for file %s\n", r
->in
.file
));
2118 werr
= ntstatus_to_werror(nt_status
);
2122 sd_size
= ndr_size_security_descriptor(psd
, NULL
, 0);
2124 sd_buf
= TALLOC_ZERO_P(p
->mem_ctx
, struct sec_desc_buf
);
2130 sd_buf
->sd_size
= sd_size
;
2133 *r
->out
.sd_buf
= sd_buf
;
2135 psd
->dacl
->revision
= NT4_ACL_REVISION
;
2137 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2138 vfs_ChDir(conn
, oldcwd
);
2139 conn_free_internal(conn
);
2145 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2149 vfs_ChDir(conn
, oldcwd
);
2153 conn_free_internal(conn
);
2159 /***********************************************************************************
2160 _srvsvc_NetSetFileSecurity
2161 Win9x NT tools set security descriptor.
2162 ***********************************************************************************/
2164 WERROR
_srvsvc_NetSetFileSecurity(pipes_struct
*p
,
2165 struct srvsvc_NetSetFileSecurity
*r
)
2167 fstring servicename
;
2168 files_struct
*fsp
= NULL
;
2172 connection_struct
*conn
= NULL
;
2174 char *oldcwd
= NULL
;
2175 struct security_descriptor
*psd
= NULL
;
2176 uint32_t security_info_sent
= 0;
2180 fstrcpy(servicename
, r
->in
.share
);
2182 snum
= find_service(servicename
);
2184 DEBUG(10, ("Could not find service %s\n", servicename
));
2185 werr
= WERR_NET_NAME_NOT_FOUND
;
2189 nt_status
= create_conn_struct(talloc_tos(), &conn
, snum
,
2190 lp_pathname(snum
), p
->server_info
,
2192 if (!NT_STATUS_IS_OK(nt_status
)) {
2193 DEBUG(10, ("create_conn_struct failed: %s\n",
2194 nt_errstr(nt_status
)));
2195 werr
= ntstatus_to_werror(nt_status
);
2199 nt_status
= SMB_VFS_CREATE_FILE(
2202 0, /* root_dir_fid */
2203 r
->in
.file
, /* fname */
2204 CFF_DOS_PATH
, /* create_file_flags */
2205 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2206 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2207 FILE_OPEN
, /* create_disposition*/
2208 0, /* create_options */
2209 0, /* file_attributes */
2210 INTERNAL_OPEN_ONLY
, /* oplock_request */
2211 0, /* allocation_size */
2218 if (!NT_STATUS_IS_OK(nt_status
)) {
2219 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2221 werr
= ntstatus_to_werror(nt_status
);
2225 psd
= r
->in
.sd_buf
->sd
;
2226 security_info_sent
= r
->in
.securityinformation
;
2228 if (psd
->owner_sid
==0) {
2229 security_info_sent
&= ~OWNER_SECURITY_INFORMATION
;
2231 if (psd
->group_sid
==0) {
2232 security_info_sent
&= ~GROUP_SECURITY_INFORMATION
;
2235 security_info_sent
&= ~SACL_SECURITY_INFORMATION
;
2238 security_info_sent
&= ~DACL_SECURITY_INFORMATION
;
2241 /* Convert all the generic bits. */
2242 security_acl_map_generic(psd
->dacl
, &file_generic_mapping
);
2243 security_acl_map_generic(psd
->sacl
, &file_generic_mapping
);
2245 nt_status
= SMB_VFS_FSET_NT_ACL(fsp
,
2249 if (!NT_STATUS_IS_OK(nt_status
) ) {
2250 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2251 "on file %s\n", r
->in
.share
));
2252 werr
= WERR_ACCESS_DENIED
;
2256 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2257 vfs_ChDir(conn
, oldcwd
);
2258 conn_free_internal(conn
);
2264 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2268 vfs_ChDir(conn
, oldcwd
);
2272 conn_free_internal(conn
);
2278 /***********************************************************************************
2279 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2280 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2281 These disks would the disks listed by this function.
2282 Users could then create shares relative to these disks. Watch out for moving these disks around.
2283 "Nigel Williams" <nigel@veritas.com>.
2284 ***********************************************************************************/
2286 static const char *server_disks
[] = {"C:"};
2288 static uint32
get_server_disk_count(void)
2290 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2293 static uint32
init_server_disk_enum(uint32
*resume
)
2295 uint32 server_disk_count
= get_server_disk_count();
2297 /*resume can be an offset into the list for now*/
2299 if(*resume
& 0x80000000)
2302 if(*resume
> server_disk_count
)
2303 *resume
= server_disk_count
;
2305 return server_disk_count
- *resume
;
2308 static const char *next_server_disk_enum(uint32
*resume
)
2312 if(init_server_disk_enum(resume
) == 0)
2315 disk
= server_disks
[*resume
];
2319 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2324 /********************************************************************
2326 ********************************************************************/
2328 WERROR
_srvsvc_NetDiskEnum(pipes_struct
*p
,
2329 struct srvsvc_NetDiskEnum
*r
)
2332 const char *disk_name
;
2333 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2335 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2339 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2341 r
->out
.info
->disks
= TALLOC_ZERO_ARRAY(ctx
, struct srvsvc_NetDiskInfo0
,
2342 MAX_SERVER_DISK_ENTRIES
);
2343 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2345 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2347 r
->out
.info
->count
= 0;
2349 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2351 r
->out
.info
->count
++;
2353 /*copy disk name into a unicode string*/
2355 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2356 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2359 /* add a terminating null string. Is this there if there is more data to come? */
2361 r
->out
.info
->count
++;
2363 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2364 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2366 if (r
->out
.resume_handle
) {
2367 *r
->out
.resume_handle
= resume
;
2373 /********************************************************************
2374 _srvsvc_NetNameValidate
2375 ********************************************************************/
2377 WERROR
_srvsvc_NetNameValidate(pipes_struct
*p
,
2378 struct srvsvc_NetNameValidate
*r
)
2380 switch (r
->in
.name_type
) {
2382 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2383 strlen_m(r
->in
.name
)))
2385 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2387 return WERR_INVALID_NAME
;
2392 return WERR_UNKNOWN_LEVEL
;
2398 /*******************************************************************
2399 ********************************************************************/
2401 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2402 const char *sharepath
, const char *fname
,
2403 void *private_data
)
2405 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2406 struct srvsvc_NetFileClose
*r
=
2407 (struct srvsvc_NetFileClose
*)private_data
;
2408 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2410 if (fid
!= r
->in
.fid
) {
2411 return; /* Not this file. */
2414 if (!process_exists(e
->pid
) ) {
2418 /* Ok - send the close message. */
2419 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2421 share_mode_str(talloc_tos(), 0, e
) ));
2423 share_mode_entry_to_message(msg
, e
);
2425 r
->out
.result
= ntstatus_to_werror(
2426 messaging_send_buf(smbd_messaging_context(),
2427 e
->pid
, MSG_SMB_CLOSE_FILE
,
2429 MSG_SMB_SHARE_MODE_ENTRY_SIZE
));
2432 /********************************************************************
2433 Close a file given a 32-bit file id.
2434 ********************************************************************/
2436 WERROR
_srvsvc_NetFileClose(pipes_struct
*p
, struct srvsvc_NetFileClose
*r
)
2438 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
2441 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2443 is_disk_op
= user_has_privileges( p
->server_info
->ptok
, &se_diskop
);
2445 if (p
->server_info
->utok
.uid
!= sec_initial_uid() && !is_disk_op
) {
2446 return WERR_ACCESS_DENIED
;
2449 /* enum_file_close_fn sends the close message to
2450 * the relevent smbd process. */
2452 r
->out
.result
= WERR_BADFILE
;
2453 share_mode_forall( enum_file_close_fn
, (void *)r
);
2454 return r
->out
.result
;
2457 /********************************************************************
2458 ********************************************************************/
2460 WERROR
_srvsvc_NetCharDevEnum(pipes_struct
*p
, struct srvsvc_NetCharDevEnum
*r
)
2462 p
->rng_fault_state
= True
;
2463 return WERR_NOT_SUPPORTED
;
2466 WERROR
_srvsvc_NetCharDevGetInfo(pipes_struct
*p
, struct srvsvc_NetCharDevGetInfo
*r
)
2468 p
->rng_fault_state
= True
;
2469 return WERR_NOT_SUPPORTED
;
2472 WERROR
_srvsvc_NetCharDevControl(pipes_struct
*p
, struct srvsvc_NetCharDevControl
*r
)
2474 p
->rng_fault_state
= True
;
2475 return WERR_NOT_SUPPORTED
;
2478 WERROR
_srvsvc_NetCharDevQEnum(pipes_struct
*p
, struct srvsvc_NetCharDevQEnum
*r
)
2480 p
->rng_fault_state
= True
;
2481 return WERR_NOT_SUPPORTED
;
2484 WERROR
_srvsvc_NetCharDevQGetInfo(pipes_struct
*p
, struct srvsvc_NetCharDevQGetInfo
*r
)
2486 p
->rng_fault_state
= True
;
2487 return WERR_NOT_SUPPORTED
;
2490 WERROR
_srvsvc_NetCharDevQSetInfo(pipes_struct
*p
, struct srvsvc_NetCharDevQSetInfo
*r
)
2492 p
->rng_fault_state
= True
;
2493 return WERR_NOT_SUPPORTED
;
2496 WERROR
_srvsvc_NetCharDevQPurge(pipes_struct
*p
, struct srvsvc_NetCharDevQPurge
*r
)
2498 p
->rng_fault_state
= True
;
2499 return WERR_NOT_SUPPORTED
;
2502 WERROR
_srvsvc_NetCharDevQPurgeSelf(pipes_struct
*p
, struct srvsvc_NetCharDevQPurgeSelf
*r
)
2504 p
->rng_fault_state
= True
;
2505 return WERR_NOT_SUPPORTED
;
2508 WERROR
_srvsvc_NetFileGetInfo(pipes_struct
*p
, struct srvsvc_NetFileGetInfo
*r
)
2510 p
->rng_fault_state
= True
;
2511 return WERR_NOT_SUPPORTED
;
2514 WERROR
_srvsvc_NetShareCheck(pipes_struct
*p
, struct srvsvc_NetShareCheck
*r
)
2516 p
->rng_fault_state
= True
;
2517 return WERR_NOT_SUPPORTED
;
2520 WERROR
_srvsvc_NetServerStatisticsGet(pipes_struct
*p
, struct srvsvc_NetServerStatisticsGet
*r
)
2522 p
->rng_fault_state
= True
;
2523 return WERR_NOT_SUPPORTED
;
2526 WERROR
_srvsvc_NetTransportAdd(pipes_struct
*p
, struct srvsvc_NetTransportAdd
*r
)
2528 p
->rng_fault_state
= True
;
2529 return WERR_NOT_SUPPORTED
;
2532 WERROR
_srvsvc_NetTransportEnum(pipes_struct
*p
, struct srvsvc_NetTransportEnum
*r
)
2534 p
->rng_fault_state
= True
;
2535 return WERR_NOT_SUPPORTED
;
2538 WERROR
_srvsvc_NetTransportDel(pipes_struct
*p
, struct srvsvc_NetTransportDel
*r
)
2540 p
->rng_fault_state
= True
;
2541 return WERR_NOT_SUPPORTED
;
2544 WERROR
_srvsvc_NetSetServiceBits(pipes_struct
*p
, struct srvsvc_NetSetServiceBits
*r
)
2546 p
->rng_fault_state
= True
;
2547 return WERR_NOT_SUPPORTED
;
2550 WERROR
_srvsvc_NetPathType(pipes_struct
*p
, struct srvsvc_NetPathType
*r
)
2552 p
->rng_fault_state
= True
;
2553 return WERR_NOT_SUPPORTED
;
2556 WERROR
_srvsvc_NetPathCanonicalize(pipes_struct
*p
, struct srvsvc_NetPathCanonicalize
*r
)
2558 p
->rng_fault_state
= True
;
2559 return WERR_NOT_SUPPORTED
;
2562 WERROR
_srvsvc_NetPathCompare(pipes_struct
*p
, struct srvsvc_NetPathCompare
*r
)
2564 p
->rng_fault_state
= True
;
2565 return WERR_NOT_SUPPORTED
;
2568 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(pipes_struct
*p
, struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2570 p
->rng_fault_state
= True
;
2571 return WERR_NOT_SUPPORTED
;
2574 WERROR
_srvsvc_NetPRNameCompare(pipes_struct
*p
, struct srvsvc_NetPRNameCompare
*r
)
2576 p
->rng_fault_state
= True
;
2577 return WERR_NOT_SUPPORTED
;
2580 WERROR
_srvsvc_NetShareDelStart(pipes_struct
*p
, struct srvsvc_NetShareDelStart
*r
)
2582 p
->rng_fault_state
= True
;
2583 return WERR_NOT_SUPPORTED
;
2586 WERROR
_srvsvc_NetShareDelCommit(pipes_struct
*p
, struct srvsvc_NetShareDelCommit
*r
)
2588 p
->rng_fault_state
= True
;
2589 return WERR_NOT_SUPPORTED
;
2592 WERROR
_srvsvc_NetServerTransportAddEx(pipes_struct
*p
, struct srvsvc_NetServerTransportAddEx
*r
)
2594 p
->rng_fault_state
= True
;
2595 return WERR_NOT_SUPPORTED
;
2598 WERROR
_srvsvc_NetServerSetServiceBitsEx(pipes_struct
*p
, struct srvsvc_NetServerSetServiceBitsEx
*r
)
2600 p
->rng_fault_state
= True
;
2601 return WERR_NOT_SUPPORTED
;
2604 WERROR
_srvsvc_NETRDFSGETVERSION(pipes_struct
*p
, struct srvsvc_NETRDFSGETVERSION
*r
)
2606 p
->rng_fault_state
= True
;
2607 return WERR_NOT_SUPPORTED
;
2610 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct
*p
, struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2612 p
->rng_fault_state
= True
;
2613 return WERR_NOT_SUPPORTED
;
2616 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct
*p
, struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2618 p
->rng_fault_state
= True
;
2619 return WERR_NOT_SUPPORTED
;
2622 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct
*p
, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2624 p
->rng_fault_state
= True
;
2625 return WERR_NOT_SUPPORTED
;
2628 WERROR
_srvsvc_NETRDFSSETSERVERINFO(pipes_struct
*p
, struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2630 p
->rng_fault_state
= True
;
2631 return WERR_NOT_SUPPORTED
;
2634 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct
*p
, struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2636 p
->rng_fault_state
= True
;
2637 return WERR_NOT_SUPPORTED
;
2640 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct
*p
, struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2642 p
->rng_fault_state
= True
;
2643 return WERR_NOT_SUPPORTED
;
2646 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(pipes_struct
*p
, struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2648 p
->rng_fault_state
= True
;
2649 return WERR_NOT_SUPPORTED
;
2652 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct
*p
, struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2654 p
->rng_fault_state
= True
;
2655 return WERR_NOT_SUPPORTED
;
2658 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct
*p
, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2660 p
->rng_fault_state
= True
;
2661 return WERR_NOT_SUPPORTED
;
2664 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct
*p
, struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2666 p
->rng_fault_state
= True
;
2667 return WERR_NOT_SUPPORTED
;