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"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping
;
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count
{
54 struct srvsvc_NetFileCtr3
*ctr3
;
57 struct sess_file_count
{
63 /*******************************************************************
64 ********************************************************************/
66 static void enum_file_fn( const struct share_mode_entry
*e
,
67 const char *sharepath
, const char *fname
,
70 struct file_enum_count
*fenum
=
71 (struct file_enum_count
*)private_data
;
73 struct srvsvc_NetFileInfo3
*f
;
74 int i
= fenum
->ctr3
->count
;
76 struct byte_range_lock
*brl
;
78 char *fullpath
= NULL
;
82 /* If the pid was not found delete the entry from connections.tdb */
84 if ( !process_exists(e
->pid
) ) {
88 username
= uidtoname(e
->uid
);
90 if ((fenum
->username
!= NULL
)
91 && !strequal(username
, fenum
->username
)) {
95 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
96 struct srvsvc_NetFileInfo3
, i
+1);
98 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
101 fenum
->ctr3
->array
= f
;
103 /* need to count the number of locks on a file */
108 if ( (brl
= brl_get_locks(talloc_tos(), &fsp
)) != NULL
) {
109 num_locks
= brl
->num_locks
;
113 if ( strcmp( fname
, "." ) == 0 ) {
114 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s", sharepath
);
116 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s/%s",
122 string_replace( fullpath
, '/', '\\' );
124 /* mask out create (what ever that is) */
125 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
127 /* now fill in the srvsvc_NetFileInfo3 struct */
129 fenum
->ctr3
->array
[i
].fid
=
130 (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
131 fenum
->ctr3
->array
[i
].permissions
= permissions
;
132 fenum
->ctr3
->array
[i
].num_locks
= num_locks
;
133 fenum
->ctr3
->array
[i
].path
= fullpath
;
134 fenum
->ctr3
->array
[i
].user
= username
;
136 fenum
->ctr3
->count
++;
139 /*******************************************************************
140 ********************************************************************/
142 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
143 const char *username
,
144 struct srvsvc_NetFileCtr3
**ctr3
,
147 struct file_enum_count f_enum_cnt
;
149 f_enum_cnt
.ctx
= ctx
;
150 f_enum_cnt
.username
= username
;
151 f_enum_cnt
.ctr3
= *ctr3
;
153 share_mode_forall( enum_file_fn
, (void *)&f_enum_cnt
);
155 *ctr3
= f_enum_cnt
.ctr3
;
160 /*******************************************************************
161 Utility function to get the 'type' of a share from an snum.
162 ********************************************************************/
163 static enum srvsvc_ShareType
get_share_type(int snum
)
165 /* work out the share type */
166 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
168 if (lp_print_ok(snum
)) {
169 type
= lp_administrative_share(snum
)
170 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
172 if (strequal(lp_fstype(talloc_tos(), snum
), "IPC")) {
173 type
= lp_administrative_share(snum
)
174 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
179 /*******************************************************************
180 Fill in a share info level 0 structure.
181 ********************************************************************/
183 static void init_srv_share_info_0(struct pipes_struct
*p
,
184 struct srvsvc_NetShareInfo0
*r
, int snum
)
186 r
->name
= lp_servicename(talloc_tos(), snum
);
189 /*******************************************************************
190 Fill in a share info level 1 structure.
191 ********************************************************************/
193 static void init_srv_share_info_1(struct pipes_struct
*p
,
194 struct srvsvc_NetShareInfo1
*r
,
197 char *net_name
= lp_servicename(talloc_tos(), snum
);
198 char *remark
= lp_comment(p
->mem_ctx
, snum
);
201 remark
= talloc_sub_advanced(
202 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
203 get_current_username(), lp_pathname(talloc_tos(), snum
),
204 p
->session_info
->unix_token
->uid
, get_current_username(),
209 r
->type
= get_share_type(snum
);
210 r
->comment
= remark
? remark
: "";
213 /*******************************************************************
214 Fill in a share info level 2 structure.
215 ********************************************************************/
217 static void init_srv_share_info_2(struct pipes_struct
*p
,
218 struct srvsvc_NetShareInfo2
*r
,
223 int max_connections
= lp_max_connections(snum
);
224 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
225 char *net_name
= lp_servicename(talloc_tos(), snum
);
227 remark
= lp_comment(p
->mem_ctx
, snum
);
229 remark
= talloc_sub_advanced(
230 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
231 get_current_username(), lp_pathname(talloc_tos(), snum
),
232 p
->session_info
->unix_token
->uid
, get_current_username(),
235 path
= talloc_asprintf(p
->mem_ctx
,
236 "C:%s", lp_pathname(talloc_tos(), snum
));
240 * Change / to \\ so that win2k will see it as a valid path.
241 * This was added to enable use of browsing in win2k add
245 string_replace(path
, '/', '\\');
249 r
->type
= get_share_type(snum
);
250 r
->comment
= remark
? remark
: "";
252 r
->max_users
= max_uses
;
253 r
->current_users
= count_current_connections(net_name
, false);
254 r
->path
= path
? path
: "";
258 /*******************************************************************
259 Map any generic bits to file specific bits.
260 ********************************************************************/
262 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
265 struct security_acl
*ps_dacl
= NULL
;
274 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
275 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
276 uint32 orig_mask
= psa
->access_mask
;
278 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
279 psa
->access_mask
|= orig_mask
;
283 /*******************************************************************
284 Fill in a share info level 501 structure.
285 ********************************************************************/
287 static void init_srv_share_info_501(struct pipes_struct
*p
,
288 struct srvsvc_NetShareInfo501
*r
, int snum
)
290 const char *net_name
= lp_servicename(talloc_tos(), snum
);
291 char *remark
= lp_comment(p
->mem_ctx
, snum
);
294 remark
= talloc_sub_advanced(
295 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
296 get_current_username(), lp_pathname(talloc_tos(), snum
),
297 p
->session_info
->unix_token
->uid
, get_current_username(),
302 r
->type
= get_share_type(snum
);
303 r
->comment
= remark
? remark
: "";
304 r
->csc_policy
= (lp_csc_policy(snum
) << 4);
307 /*******************************************************************
308 Fill in a share info level 502 structure.
309 ********************************************************************/
311 static void init_srv_share_info_502(struct pipes_struct
*p
,
312 struct srvsvc_NetShareInfo502
*r
, int snum
)
314 const char *net_name
= lp_servicename(talloc_tos(), snum
);
316 struct security_descriptor
*sd
= NULL
;
317 struct sec_desc_buf
*sd_buf
= NULL
;
319 TALLOC_CTX
*ctx
= p
->mem_ctx
;
320 char *remark
= lp_comment(ctx
, snum
);
323 remark
= talloc_sub_advanced(
324 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
325 get_current_username(), lp_pathname(talloc_tos(), snum
),
326 p
->session_info
->unix_token
->uid
, get_current_username(),
329 path
= talloc_asprintf(ctx
, "C:%s", lp_pathname(talloc_tos(), snum
));
332 * Change / to \\ so that win2k will see it as a valid path. This was added to
333 * enable use of browsing in win2k add share dialog.
335 string_replace(path
, '/', '\\');
338 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
340 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
343 r
->type
= get_share_type(snum
);
344 r
->comment
= remark
? remark
: "";
346 r
->max_users
= (uint32_t)-1;
347 r
->current_users
= 1; /* ??? */
348 r
->path
= path
? path
: "";
353 /***************************************************************************
354 Fill in a share info level 1004 structure.
355 ***************************************************************************/
357 static void init_srv_share_info_1004(struct pipes_struct
*p
,
358 struct srvsvc_NetShareInfo1004
*r
,
361 char *remark
= lp_comment(p
->mem_ctx
, snum
);
364 remark
= talloc_sub_advanced(
365 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
366 get_current_username(), lp_pathname(talloc_tos(), snum
),
367 p
->session_info
->unix_token
->uid
, get_current_username(),
371 r
->comment
= remark
? remark
: "";
374 /***************************************************************************
375 Fill in a share info level 1005 structure.
376 ***************************************************************************/
378 static void init_srv_share_info_1005(struct pipes_struct
*p
,
379 struct srvsvc_NetShareInfo1005
*r
,
382 uint32_t dfs_flags
= 0;
384 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
385 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
388 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
390 r
->dfs_flags
= dfs_flags
;
393 /***************************************************************************
394 Fill in a share info level 1006 structure.
395 ***************************************************************************/
397 static void init_srv_share_info_1006(struct pipes_struct
*p
,
398 struct srvsvc_NetShareInfo1006
*r
,
401 r
->max_users
= (uint32_t)-1;
404 /***************************************************************************
405 Fill in a share info level 1007 structure.
406 ***************************************************************************/
408 static void init_srv_share_info_1007(struct pipes_struct
*p
,
409 struct srvsvc_NetShareInfo1007
*r
,
413 r
->alternate_directory_name
= "";
416 /*******************************************************************
417 Fill in a share info level 1501 structure.
418 ********************************************************************/
420 static void init_srv_share_info_1501(struct pipes_struct
*p
,
421 struct sec_desc_buf
**r
,
424 struct security_descriptor
*sd
;
425 struct sec_desc_buf
*sd_buf
= NULL
;
427 TALLOC_CTX
*ctx
= p
->mem_ctx
;
429 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
431 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
437 /*******************************************************************
438 True if it ends in '$'.
439 ********************************************************************/
441 static bool is_hidden_share(int snum
)
443 const char *net_name
= lp_servicename(talloc_tos(), snum
);
445 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
448 /*******************************************************************
449 Verify user is allowed to view share, access based enumeration
450 ********************************************************************/
451 static bool is_enumeration_allowed(struct pipes_struct
*p
,
454 if (!lp_access_based_share_enum(snum
))
457 return share_access_check(p
->session_info
->security_token
,
458 lp_servicename(talloc_tos(), snum
),
459 FILE_READ_DATA
, NULL
);
462 /*******************************************************************
463 Fill in a share info structure.
464 ********************************************************************/
466 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
467 struct srvsvc_NetShareInfoCtr
*info_ctr
,
468 uint32_t *resume_handle_p
,
469 uint32_t *total_entries
,
473 int alloc_entries
= 0;
474 int num_services
= 0;
476 TALLOC_CTX
*ctx
= p
->mem_ctx
;
478 int valid_share_count
= 0;
480 union srvsvc_NetShareCtr ctr
;
481 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
483 DEBUG(5,("init_srv_share_info_ctr\n"));
485 /* Ensure all the usershares are loaded. */
487 load_usershare_shares(NULL
, connections_snum_used
);
488 load_registry_shares();
489 num_services
= lp_numservices();
492 allowed
= talloc_zero_array(ctx
, bool, num_services
);
493 W_ERROR_HAVE_NO_MEMORY(allowed
);
495 /* Count the number of entries. */
496 for (snum
= 0; snum
< num_services
; snum
++) {
497 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
498 is_enumeration_allowed(p
, snum
) &&
499 (all_shares
|| !is_hidden_share(snum
)) ) {
500 DEBUG(10, ("counting service %s\n",
501 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
502 allowed
[snum
] = true;
505 DEBUG(10, ("NOT counting service %s\n",
506 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
510 if (!num_entries
|| (resume_handle
>= num_entries
)) {
514 /* Calculate alloc entries. */
515 alloc_entries
= num_entries
- resume_handle
;
516 switch (info_ctr
->level
) {
518 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
519 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
521 ctr
.ctr0
->count
= alloc_entries
;
522 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
523 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
525 for (snum
= 0; snum
< num_services
; snum
++) {
527 (resume_handle
<= (i
+ valid_share_count
++)) ) {
528 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
535 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
536 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
538 ctr
.ctr1
->count
= alloc_entries
;
539 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
540 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
542 for (snum
= 0; snum
< num_services
; snum
++) {
544 (resume_handle
<= (i
+ valid_share_count
++)) ) {
545 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
552 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
553 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
555 ctr
.ctr2
->count
= alloc_entries
;
556 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
557 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
559 for (snum
= 0; snum
< num_services
; snum
++) {
561 (resume_handle
<= (i
+ valid_share_count
++)) ) {
562 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
569 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
570 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
572 ctr
.ctr501
->count
= alloc_entries
;
573 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
574 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
576 for (snum
= 0; snum
< num_services
; snum
++) {
578 (resume_handle
<= (i
+ valid_share_count
++)) ) {
579 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
586 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
587 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
589 ctr
.ctr502
->count
= alloc_entries
;
590 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
591 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
593 for (snum
= 0; snum
< num_services
; snum
++) {
595 (resume_handle
<= (i
+ valid_share_count
++)) ) {
596 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
603 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
604 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
606 ctr
.ctr1004
->count
= alloc_entries
;
607 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
608 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
610 for (snum
= 0; snum
< num_services
; snum
++) {
612 (resume_handle
<= (i
+ valid_share_count
++)) ) {
613 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
620 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
621 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
623 ctr
.ctr1005
->count
= alloc_entries
;
624 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
625 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
627 for (snum
= 0; snum
< num_services
; snum
++) {
629 (resume_handle
<= (i
+ valid_share_count
++)) ) {
630 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
637 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
638 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
640 ctr
.ctr1006
->count
= alloc_entries
;
641 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
642 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
644 for (snum
= 0; snum
< num_services
; snum
++) {
646 (resume_handle
<= (i
+ valid_share_count
++)) ) {
647 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
654 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
655 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
657 ctr
.ctr1007
->count
= alloc_entries
;
658 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
659 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
661 for (snum
= 0; snum
< num_services
; snum
++) {
663 (resume_handle
<= (i
+ valid_share_count
++)) ) {
664 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
671 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
672 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
674 ctr
.ctr1501
->count
= alloc_entries
;
675 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
676 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
678 for (snum
= 0; snum
< num_services
; snum
++) {
680 (resume_handle
<= (i
+ valid_share_count
++)) ) {
681 struct sec_desc_buf
*sd_buf
= NULL
;
682 init_srv_share_info_1501(p
, &sd_buf
, snum
);
683 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
690 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
692 return WERR_UNKNOWN_LEVEL
;
695 *total_entries
= alloc_entries
;
696 if (resume_handle_p
) {
698 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
700 *resume_handle_p
= num_entries
;
709 /*******************************************************************
710 fill in a sess info level 0 structure.
711 ********************************************************************/
713 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
714 struct srvsvc_NetSessCtr0
*ctr0
,
715 uint32_t *resume_handle_p
,
716 uint32_t *total_entries
)
718 struct sessionid
*session_list
;
719 uint32_t num_entries
= 0;
720 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
721 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
723 DEBUG(5,("init_srv_sess_info_0\n"));
726 if (resume_handle_p
) {
727 *resume_handle_p
= 0;
732 for (; resume_handle
< *total_entries
; resume_handle
++) {
734 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
736 struct srvsvc_NetSessInfo0
,
738 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
740 ctr0
->array
[num_entries
].client
=
741 session_list
[resume_handle
].remote_machine
;
746 ctr0
->count
= num_entries
;
748 if (resume_handle_p
) {
749 if (*resume_handle_p
>= *total_entries
) {
750 *resume_handle_p
= 0;
752 *resume_handle_p
= resume_handle
;
759 /*******************************************************************
760 ********************************************************************/
762 static void sess_file_fn( const struct share_mode_entry
*e
,
763 const char *sharepath
, const char *fname
,
766 struct sess_file_count
*sess
= (struct sess_file_count
*)data
;
768 if (serverid_equal(&e
->pid
, &sess
->pid
) && (sess
->uid
== e
->uid
)) {
775 /*******************************************************************
776 ********************************************************************/
778 static int net_count_files( uid_t uid
, struct server_id pid
)
780 struct sess_file_count s_file_cnt
;
782 s_file_cnt
.count
= 0;
783 s_file_cnt
.uid
= uid
;
784 s_file_cnt
.pid
= pid
;
786 share_mode_forall( sess_file_fn
, &s_file_cnt
);
788 return s_file_cnt
.count
;
791 /*******************************************************************
792 fill in a sess info level 1 structure.
793 ********************************************************************/
795 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
796 struct srvsvc_NetSessCtr1
*ctr1
,
797 uint32_t *resume_handle_p
,
798 uint32_t *total_entries
)
800 struct sessionid
*session_list
;
801 uint32_t num_entries
= 0;
802 time_t now
= time(NULL
);
803 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
808 if (resume_handle_p
) {
809 *resume_handle_p
= 0;
814 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
816 for (; resume_handle
< *total_entries
; resume_handle
++) {
819 struct passwd
*pw
= getpwnam(session_list
[resume_handle
].username
);
823 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
824 session_list
[resume_handle
].username
));
828 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
829 num_files
= net_count_files(pw
->pw_uid
, session_list
[resume_handle
].pid
);
830 guest
= strequal( session_list
[resume_handle
].username
, lp_guestaccount() );
832 ctr1
->array
= talloc_realloc(p
->mem_ctx
,
834 struct srvsvc_NetSessInfo1
,
836 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
838 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
839 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
840 ctr1
->array
[num_entries
].num_open
= num_files
;
841 ctr1
->array
[num_entries
].time
= connect_time
;
842 ctr1
->array
[num_entries
].idle_time
= 0;
843 ctr1
->array
[num_entries
].user_flags
= guest
;
848 ctr1
->count
= num_entries
;
850 if (resume_handle_p
) {
851 if (*resume_handle_p
>= *total_entries
) {
852 *resume_handle_p
= 0;
854 *resume_handle_p
= resume_handle
;
861 /*******************************************************************
862 fill in a conn info level 0 structure.
863 ********************************************************************/
865 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
866 uint32_t *resume_handle_p
,
867 uint32_t *total_entries
)
869 uint32_t num_entries
= 0;
870 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
872 DEBUG(5,("init_srv_conn_info_0\n"));
875 if (resume_handle_p
) {
876 *resume_handle_p
= 0;
885 for (; resume_handle
< *total_entries
; resume_handle
++) {
887 ctr0
->array
= talloc_realloc(talloc_tos(),
889 struct srvsvc_NetConnInfo0
,
895 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
897 /* move on to creating next connection */
901 ctr0
->count
= num_entries
;
902 *total_entries
= num_entries
;
904 if (resume_handle_p
) {
905 if (*resume_handle_p
>= *total_entries
) {
906 *resume_handle_p
= 0;
908 *resume_handle_p
= resume_handle
;
915 /*******************************************************************
916 fill in a conn info level 1 structure.
917 ********************************************************************/
919 static WERROR
init_srv_conn_info_1(struct srvsvc_NetConnCtr1
*ctr1
,
920 uint32_t *resume_handle_p
,
921 uint32_t *total_entries
)
923 uint32_t num_entries
= 0;
924 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
926 DEBUG(5,("init_srv_conn_info_1\n"));
929 if (resume_handle_p
) {
930 *resume_handle_p
= 0;
939 for (; resume_handle
< *total_entries
; resume_handle
++) {
941 ctr1
->array
= talloc_realloc(talloc_tos(),
943 struct srvsvc_NetConnInfo1
,
949 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
950 ctr1
->array
[num_entries
].conn_type
= 0x3;
951 ctr1
->array
[num_entries
].num_open
= 1;
952 ctr1
->array
[num_entries
].num_users
= 1;
953 ctr1
->array
[num_entries
].conn_time
= 3;
954 ctr1
->array
[num_entries
].user
= "dummy_user";
955 ctr1
->array
[num_entries
].share
= "IPC$";
957 /* move on to creating next connection */
961 ctr1
->count
= num_entries
;
962 *total_entries
= num_entries
;
964 if (resume_handle_p
) {
965 if (*resume_handle_p
>= *total_entries
) {
966 *resume_handle_p
= 0;
968 *resume_handle_p
= resume_handle
;
975 /*******************************************************************
977 *******************************************************************/
979 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
980 struct srvsvc_NetFileEnum
*r
)
982 TALLOC_CTX
*ctx
= NULL
;
983 struct srvsvc_NetFileCtr3
*ctr3
;
984 uint32_t resume_hnd
= 0;
987 switch (r
->in
.info_ctr
->level
) {
991 return WERR_UNKNOWN_LEVEL
;
994 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
995 p
->session_info
->security_token
)) {
996 DEBUG(1, ("Enumerating files only allowed for "
997 "administrators\n"));
998 return WERR_ACCESS_DENIED
;
1002 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1004 werr
= WERR_INVALID_PARAM
;
1008 /* TODO -- Windows enumerates
1010 (c) open directories and files */
1012 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1013 if (!W_ERROR_IS_OK(werr
)) {
1017 *r
->out
.totalentries
= ctr3
->count
;
1018 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1019 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1027 /*******************************************************************
1028 _srvsvc_NetSrvGetInfo
1029 ********************************************************************/
1031 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1032 struct srvsvc_NetSrvGetInfo
*r
)
1034 WERROR status
= WERR_OK
;
1036 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1038 if (!pipe_access_check(p
)) {
1039 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1040 return WERR_ACCESS_DENIED
;
1043 switch (r
->in
.level
) {
1045 /* Technically level 102 should only be available to
1046 Administrators but there isn't anything super-secret
1047 here, as most of it is made up. */
1050 struct srvsvc_NetSrvInfo102
*info102
;
1052 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1057 info102
->platform_id
= PLATFORM_ID_NT
;
1058 info102
->server_name
= lp_netbios_name();
1059 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1060 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1061 info102
->server_type
= lp_default_server_announce();
1062 info102
->comment
= string_truncate(lp_serverstring(talloc_tos()),
1063 MAX_SERVER_STRING_LENGTH
);
1064 info102
->users
= 0xffffffff;
1065 info102
->disc
= 0xf;
1066 info102
->hidden
= 0;
1067 info102
->announce
= 240;
1068 info102
->anndelta
= 3000;
1069 info102
->licenses
= 100000;
1070 info102
->userpath
= "C:\\";
1072 r
->out
.info
->info102
= info102
;
1076 struct srvsvc_NetSrvInfo101
*info101
;
1078 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1083 info101
->platform_id
= PLATFORM_ID_NT
;
1084 info101
->server_name
= lp_netbios_name();
1085 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1086 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1087 info101
->server_type
= lp_default_server_announce();
1088 info101
->comment
= string_truncate(lp_serverstring(talloc_tos()),
1089 MAX_SERVER_STRING_LENGTH
);
1091 r
->out
.info
->info101
= info101
;
1095 struct srvsvc_NetSrvInfo100
*info100
;
1097 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1102 info100
->platform_id
= PLATFORM_ID_NT
;
1103 info100
->server_name
= lp_netbios_name();
1105 r
->out
.info
->info100
= info100
;
1110 status
= WERR_UNKNOWN_LEVEL
;
1114 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1119 /*******************************************************************
1120 _srvsvc_NetSrvSetInfo
1121 ********************************************************************/
1123 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1124 struct srvsvc_NetSrvSetInfo
*r
)
1126 WERROR status
= WERR_OK
;
1128 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1130 /* Set up the net server set info structure. */
1132 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1137 /*******************************************************************
1139 ********************************************************************/
1141 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1142 struct srvsvc_NetConnEnum
*r
)
1146 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1148 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1149 p
->session_info
->security_token
)) {
1150 DEBUG(1, ("Enumerating connections only allowed for "
1151 "administrators\n"));
1152 return WERR_ACCESS_DENIED
;
1155 switch (r
->in
.info_ctr
->level
) {
1157 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1158 r
->in
.resume_handle
,
1159 r
->out
.totalentries
);
1162 werr
= init_srv_conn_info_1(r
->in
.info_ctr
->ctr
.ctr1
,
1163 r
->in
.resume_handle
,
1164 r
->out
.totalentries
);
1167 return WERR_UNKNOWN_LEVEL
;
1170 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1175 /*******************************************************************
1177 ********************************************************************/
1179 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1180 struct srvsvc_NetSessEnum
*r
)
1184 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1186 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1187 p
->session_info
->security_token
)) {
1188 DEBUG(1, ("Enumerating sessions only allowed for "
1189 "administrators\n"));
1190 return WERR_ACCESS_DENIED
;
1193 switch (r
->in
.info_ctr
->level
) {
1195 werr
= init_srv_sess_info_0(p
,
1196 r
->in
.info_ctr
->ctr
.ctr0
,
1197 r
->in
.resume_handle
,
1198 r
->out
.totalentries
);
1201 werr
= init_srv_sess_info_1(p
,
1202 r
->in
.info_ctr
->ctr
.ctr1
,
1203 r
->in
.resume_handle
,
1204 r
->out
.totalentries
);
1207 return WERR_UNKNOWN_LEVEL
;
1210 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1215 /*******************************************************************
1217 ********************************************************************/
1219 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1220 struct srvsvc_NetSessDel
*r
)
1222 struct sessionid
*session_list
;
1223 int num_sessions
, snum
;
1224 const char *username
;
1225 const char *machine
;
1226 bool not_root
= False
;
1229 username
= r
->in
.user
;
1230 machine
= r
->in
.client
;
1232 /* strip leading backslashes if any */
1233 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1237 num_sessions
= list_sessions(p
->mem_ctx
, &session_list
);
1239 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1241 werr
= WERR_ACCESS_DENIED
;
1243 /* fail out now if you are not root or not a domain admin */
1245 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1246 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1247 DOMAIN_RID_ADMINS
))) {
1252 for (snum
= 0; snum
< num_sessions
; snum
++) {
1254 if ((strequal(session_list
[snum
].username
, username
) || username
[0] == '\0' ) &&
1255 strequal(session_list
[snum
].remote_machine
, machine
)) {
1259 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1264 ntstat
= messaging_send(p
->msg_ctx
,
1265 session_list
[snum
].pid
,
1266 MSG_SHUTDOWN
, &data_blob_null
);
1268 if (NT_STATUS_IS_OK(ntstat
))
1276 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1283 /*******************************************************************
1284 _srvsvc_NetShareEnumAll
1285 ********************************************************************/
1287 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1288 struct srvsvc_NetShareEnumAll
*r
)
1292 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1294 if (!pipe_access_check(p
)) {
1295 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1296 return WERR_ACCESS_DENIED
;
1299 /* Create the list of shares for the response. */
1300 werr
= init_srv_share_info_ctr(p
,
1302 r
->in
.resume_handle
,
1303 r
->out
.totalentries
,
1306 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1311 /*******************************************************************
1312 _srvsvc_NetShareEnum
1313 ********************************************************************/
1315 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1316 struct srvsvc_NetShareEnum
*r
)
1320 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1322 if (!pipe_access_check(p
)) {
1323 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1324 return WERR_ACCESS_DENIED
;
1327 /* Create the list of shares for the response. */
1328 werr
= init_srv_share_info_ctr(p
,
1330 r
->in
.resume_handle
,
1331 r
->out
.totalentries
,
1334 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1339 /*******************************************************************
1340 _srvsvc_NetShareGetInfo
1341 ********************************************************************/
1343 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1344 struct srvsvc_NetShareGetInfo
*r
)
1346 WERROR status
= WERR_OK
;
1347 char *share_name
= NULL
;
1349 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1351 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1353 if (!r
->in
.share_name
) {
1354 return WERR_INVALID_NAME
;
1357 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1362 return WERR_INVALID_NAME
;
1365 switch (r
->in
.level
) {
1367 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1368 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1369 init_srv_share_info_0(p
, info
->info0
, snum
);
1372 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1373 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1374 init_srv_share_info_1(p
, info
->info1
, snum
);
1377 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1378 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1379 init_srv_share_info_2(p
, info
->info2
, snum
);
1382 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1383 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1384 init_srv_share_info_501(p
, info
->info501
, snum
);
1387 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1388 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1389 init_srv_share_info_502(p
, info
->info502
, snum
);
1392 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1393 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1394 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1397 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1398 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1399 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1402 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1403 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1404 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1407 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1408 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1409 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1412 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1415 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1417 status
= WERR_UNKNOWN_LEVEL
;
1421 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1426 /*******************************************************************
1427 _srvsvc_NetShareSetInfo. Modify share details.
1428 ********************************************************************/
1430 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1431 struct srvsvc_NetShareSetInfo
*r
)
1433 char *command
= NULL
;
1434 char *share_name
= NULL
;
1435 char *comment
= NULL
;
1436 const char *pathname
= NULL
;
1441 struct security_descriptor
*psd
= NULL
;
1442 bool is_disk_op
= False
;
1443 int max_connections
= 0;
1444 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1445 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1447 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1449 if (!r
->in
.share_name
) {
1450 return WERR_INVALID_NAME
;
1453 if (r
->out
.parm_error
) {
1454 *r
->out
.parm_error
= 0;
1457 if ( strequal(r
->in
.share_name
,"IPC$")
1458 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1459 || strequal(r
->in
.share_name
,"global") )
1461 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1462 "modified by a remote user.\n",
1463 r
->in
.share_name
));
1464 return WERR_ACCESS_DENIED
;
1467 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1472 /* Does this share exist ? */
1474 return WERR_NET_NAME_NOT_FOUND
;
1476 /* No change to printer shares. */
1477 if (lp_print_ok(snum
))
1478 return WERR_ACCESS_DENIED
;
1480 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1482 /* fail out now if you are not root and not a disk op */
1484 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1485 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1486 "SeDiskOperatorPrivilege privilege needed to modify "
1488 (unsigned int)p
->session_info
->unix_token
->uid
,
1490 return WERR_ACCESS_DENIED
;
1493 switch (r
->in
.level
) {
1495 pathname
= lp_pathname(ctx
, snum
);
1496 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1497 type
= info
->info1
->type
;
1501 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1502 pathname
= info
->info2
->path
;
1503 type
= info
->info2
->type
;
1504 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1505 0 : info
->info2
->max_users
;
1509 /* not supported on set but here for completeness */
1511 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1512 type
= info
->info501
->type
;
1517 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1518 pathname
= info
->info502
->path
;
1519 type
= info
->info502
->type
;
1520 psd
= info
->info502
->sd_buf
.sd
;
1521 map_generic_share_sd_bits(psd
);
1524 pathname
= lp_pathname(ctx
, snum
);
1525 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1526 type
= STYPE_DISKTREE
;
1529 /* XP re-sets the csc policy even if it wasn't changed by the
1530 user, so we must compare it to see if it's what is set in
1531 smb.conf, so that we can contine other ops like setting
1533 if (((info
->info1005
->dfs_flags
&
1534 SHARE_1005_CSC_POLICY_MASK
) >>
1535 SHARE_1005_CSC_POLICY_SHIFT
) == lp_csc_policy(snum
))
1538 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1539 return WERR_ACCESS_DENIED
;
1543 return WERR_ACCESS_DENIED
;
1545 pathname
= lp_pathname(ctx
, snum
);
1546 comment
= lp_comment(ctx
, snum
);
1547 psd
= info
->info1501
->sd
;
1548 map_generic_share_sd_bits(psd
);
1549 type
= STYPE_DISKTREE
;
1552 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1554 return WERR_UNKNOWN_LEVEL
;
1557 /* We can only modify disk shares. */
1558 if (type
!= STYPE_DISKTREE
) {
1559 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1562 return WERR_ACCESS_DENIED
;
1565 if (comment
== NULL
) {
1569 /* Check if the pathname is valid. */
1570 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1571 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1573 return WERR_OBJECT_PATH_INVALID
;
1576 /* Ensure share name, pathname and comment don't contain '"' characters. */
1577 string_replace(share_name
, '"', ' ');
1578 string_replace(path
, '"', ' ');
1579 string_replace(comment
, '"', ' ');
1581 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1582 lp_change_share_cmd(talloc_tos()) ? lp_change_share_cmd(talloc_tos()) : "NULL" ));
1584 /* Only call modify function if something changed. */
1586 if (strcmp(path
, lp_pathname(talloc_tos(), snum
)) || strcmp(comment
, lp_comment(talloc_tos(), snum
))
1587 || (lp_max_connections(snum
) != max_connections
)) {
1588 if (!lp_change_share_cmd(talloc_tos()) || !*lp_change_share_cmd(talloc_tos())) {
1589 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1590 return WERR_ACCESS_DENIED
;
1593 command
= talloc_asprintf(p
->mem_ctx
,
1594 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1595 lp_change_share_cmd(talloc_tos()),
1596 get_dyn_CONFIGFILE(),
1599 comment
? comment
: "",
1605 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1607 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1612 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1613 /* Tell everyone we updated smb.conf. */
1614 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1621 /********* END SeDiskOperatorPrivilege BLOCK *********/
1623 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1626 TALLOC_FREE(command
);
1629 return WERR_ACCESS_DENIED
;
1631 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1635 /* Replace SD if changed. */
1637 struct security_descriptor
*old_sd
;
1640 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
1642 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1643 if (!set_share_security(share_name
, psd
))
1644 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1649 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1654 /*******************************************************************
1655 _srvsvc_NetShareAdd.
1656 Call 'add_share_command "sharename" "pathname"
1657 "comment" "max connections = "
1658 ********************************************************************/
1660 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1661 struct srvsvc_NetShareAdd
*r
)
1663 char *command
= NULL
;
1664 char *share_name_in
= NULL
;
1665 char *share_name
= NULL
;
1666 char *comment
= NULL
;
1667 char *pathname
= NULL
;
1672 struct security_descriptor
*psd
= NULL
;
1674 int max_connections
= 0;
1675 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1677 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1679 if (r
->out
.parm_error
) {
1680 *r
->out
.parm_error
= 0;
1683 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1685 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1686 return WERR_ACCESS_DENIED
;
1688 if (!lp_add_share_cmd(talloc_tos()) || !*lp_add_share_cmd(talloc_tos())) {
1689 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1690 return WERR_ACCESS_DENIED
;
1693 switch (r
->in
.level
) {
1695 /* No path. Not enough info in a level 0 to do anything. */
1696 return WERR_ACCESS_DENIED
;
1698 /* Not enough info in a level 1 to do anything. */
1699 return WERR_ACCESS_DENIED
;
1701 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1702 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1703 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1704 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1705 0 : r
->in
.info
->info2
->max_users
;
1706 type
= r
->in
.info
->info2
->type
;
1709 /* No path. Not enough info in a level 501 to do anything. */
1710 return WERR_ACCESS_DENIED
;
1712 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1713 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1714 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1715 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1716 0 : r
->in
.info
->info502
->max_users
;
1717 type
= r
->in
.info
->info502
->type
;
1718 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1719 map_generic_share_sd_bits(psd
);
1722 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1728 return WERR_ACCESS_DENIED
;
1730 /* DFS only level. */
1731 return WERR_ACCESS_DENIED
;
1733 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1735 return WERR_UNKNOWN_LEVEL
;
1738 /* check for invalid share names */
1740 if (!share_name_in
|| !validate_net_name(share_name_in
,
1741 INVALID_SHARENAME_CHARS
,
1742 strlen(share_name_in
))) {
1743 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1744 share_name_in
? share_name_in
: ""));
1745 return WERR_INVALID_NAME
;
1748 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
1749 || (lp_enable_asu_support() &&
1750 strequal(share_name_in
,"ADMIN$"))) {
1751 return WERR_ACCESS_DENIED
;
1754 snum
= find_service(ctx
, share_name_in
, &share_name
);
1759 /* Share already exists. */
1761 return WERR_FILE_EXISTS
;
1764 /* We can only add disk shares. */
1765 if (type
!= STYPE_DISKTREE
) {
1766 return WERR_ACCESS_DENIED
;
1769 /* Check if the pathname is valid. */
1770 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1771 return WERR_OBJECT_PATH_INVALID
;
1774 /* Ensure share name, pathname and comment don't contain '"' characters. */
1775 string_replace(share_name_in
, '"', ' ');
1776 string_replace(share_name
, '"', ' ');
1777 string_replace(path
, '"', ' ');
1779 string_replace(comment
, '"', ' ');
1782 command
= talloc_asprintf(ctx
,
1783 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1784 lp_add_share_cmd(talloc_tos()),
1785 get_dyn_CONFIGFILE(),
1788 comment
? comment
: "",
1794 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
1796 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1801 /* FIXME: use libnetconf here - gd */
1803 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1804 /* Tell everyone we updated smb.conf. */
1805 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
1812 /********* END SeDiskOperatorPrivilege BLOCK *********/
1814 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1817 TALLOC_FREE(command
);
1820 return WERR_ACCESS_DENIED
;
1823 /* Note we use share_name here, not share_name_in as
1824 we need a canonicalized name for setting security. */
1825 if (!set_share_security(share_name
, psd
)) {
1826 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1832 * We don't call reload_services() here, the message will
1833 * cause this to be done before the next packet is read
1834 * from the client. JRA.
1837 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1842 /*******************************************************************
1844 Call "delete share command" with the share name as
1846 ********************************************************************/
1848 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
1849 struct srvsvc_NetShareDel
*r
)
1851 char *command
= NULL
;
1852 char *share_name
= NULL
;
1856 struct share_params
*params
;
1857 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1859 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
1861 if (!r
->in
.share_name
) {
1862 return WERR_NET_NAME_NOT_FOUND
;
1865 if ( strequal(r
->in
.share_name
,"IPC$")
1866 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1867 || strequal(r
->in
.share_name
,"global") )
1869 return WERR_ACCESS_DENIED
;
1872 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1878 return WERR_NO_SUCH_SHARE
;
1881 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
1882 return WERR_NO_SUCH_SHARE
;
1885 /* No change to printer shares. */
1886 if (lp_print_ok(snum
))
1887 return WERR_ACCESS_DENIED
;
1889 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1891 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1892 return WERR_ACCESS_DENIED
;
1894 if (!lp_delete_share_cmd(talloc_tos()) || !*lp_delete_share_cmd(talloc_tos())) {
1895 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1896 return WERR_ACCESS_DENIED
;
1899 command
= talloc_asprintf(ctx
,
1901 lp_delete_share_cmd(talloc_tos()),
1902 get_dyn_CONFIGFILE(),
1903 lp_servicename(talloc_tos(), snum
));
1908 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
1910 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1915 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1916 /* Tell everyone we updated smb.conf. */
1917 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
1924 /********* END SeDiskOperatorPrivilege BLOCK *********/
1926 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
1929 return WERR_ACCESS_DENIED
;
1931 /* Delete the SD in the database. */
1932 delete_share_security(lp_servicename(talloc_tos(), params
->service
));
1934 lp_killservice(params
->service
);
1939 /*******************************************************************
1940 _srvsvc_NetShareDelSticky
1941 ********************************************************************/
1943 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
1944 struct srvsvc_NetShareDelSticky
*r
)
1946 struct srvsvc_NetShareDel q
;
1948 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
1950 q
.in
.server_unc
= r
->in
.server_unc
;
1951 q
.in
.share_name
= r
->in
.share_name
;
1952 q
.in
.reserved
= r
->in
.reserved
;
1954 return _srvsvc_NetShareDel(p
, &q
);
1957 /*******************************************************************
1958 _srvsvc_NetRemoteTOD
1959 ********************************************************************/
1961 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
1962 struct srvsvc_NetRemoteTOD
*r
)
1964 struct srvsvc_NetRemoteTODInfo
*tod
;
1966 time_t unixdate
= time(NULL
);
1968 /* We do this call first as if we do it *after* the gmtime call
1969 it overwrites the pointed-to values. JRA */
1971 uint32 zone
= get_time_zone(unixdate
)/60;
1973 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
1975 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
1980 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
1982 t
= gmtime(&unixdate
);
1985 tod
->elapsed
= unixdate
;
1987 tod
->hours
= t
->tm_hour
;
1988 tod
->mins
= t
->tm_min
;
1989 tod
->secs
= t
->tm_sec
;
1991 tod
->timezone
= zone
;
1992 tod
->tinterval
= 10000;
1993 tod
->day
= t
->tm_mday
;
1994 tod
->month
= t
->tm_mon
+ 1;
1995 tod
->year
= 1900+t
->tm_year
;
1996 tod
->weekday
= t
->tm_wday
;
1998 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2003 /***********************************************************************************
2004 _srvsvc_NetGetFileSecurity
2005 Win9x NT tools get security descriptor.
2006 ***********************************************************************************/
2008 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2009 struct srvsvc_NetGetFileSecurity
*r
)
2011 struct smb_filename
*smb_fname
= NULL
;
2013 char *servicename
= NULL
;
2017 connection_struct
*conn
= NULL
;
2018 struct sec_desc_buf
*sd_buf
= NULL
;
2019 files_struct
*fsp
= NULL
;
2021 char *oldcwd
= NULL
;
2026 werr
= WERR_NET_NAME_NOT_FOUND
;
2029 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2035 DEBUG(10, ("Could not find service %s\n", servicename
));
2036 werr
= WERR_NET_NAME_NOT_FOUND
;
2040 nt_status
= create_conn_struct(talloc_tos(),
2041 server_event_context(),
2042 server_messaging_context(),
2044 snum
, lp_pathname(talloc_tos(), snum
),
2045 p
->session_info
, &oldcwd
);
2046 if (!NT_STATUS_IS_OK(nt_status
)) {
2047 DEBUG(10, ("create_conn_struct failed: %s\n",
2048 nt_errstr(nt_status
)));
2049 werr
= ntstatus_to_werror(nt_status
);
2053 nt_status
= filename_convert(talloc_tos(),
2060 if (!NT_STATUS_IS_OK(nt_status
)) {
2061 werr
= ntstatus_to_werror(nt_status
);
2065 nt_status
= SMB_VFS_CREATE_FILE(
2068 0, /* root_dir_fid */
2069 smb_fname
, /* fname */
2070 FILE_READ_ATTRIBUTES
, /* access_mask */
2071 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2072 FILE_OPEN
, /* create_disposition*/
2073 0, /* create_options */
2074 0, /* file_attributes */
2075 INTERNAL_OPEN_ONLY
, /* oplock_request */
2076 0, /* allocation_size */
2077 0, /* private_flags */
2083 if (!NT_STATUS_IS_OK(nt_status
)) {
2084 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2085 smb_fname_str_dbg(smb_fname
)));
2086 werr
= ntstatus_to_werror(nt_status
);
2090 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2096 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2099 |SECINFO_DACL
), sd_buf
, &sd_buf
->sd
);
2101 if (!NT_STATUS_IS_OK(nt_status
)) {
2102 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2103 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2104 werr
= ntstatus_to_werror(nt_status
);
2105 TALLOC_FREE(sd_buf
);
2109 if (sd_buf
->sd
->dacl
) {
2110 sd_buf
->sd
->dacl
->revision
= NT4_ACL_REVISION
;
2113 sd_size
= ndr_size_security_descriptor(sd_buf
->sd
, 0);
2115 sd_buf
->sd_size
= sd_size
;
2117 *r
->out
.sd_buf
= sd_buf
;
2119 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2120 vfs_ChDir(conn
, oldcwd
);
2121 SMB_VFS_DISCONNECT(conn
);
2129 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2133 vfs_ChDir(conn
, oldcwd
);
2137 SMB_VFS_DISCONNECT(conn
);
2143 TALLOC_FREE(smb_fname
);
2148 /***********************************************************************************
2149 _srvsvc_NetSetFileSecurity
2150 Win9x NT tools set security descriptor.
2151 ***********************************************************************************/
2153 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2154 struct srvsvc_NetSetFileSecurity
*r
)
2156 struct smb_filename
*smb_fname
= NULL
;
2157 char *servicename
= NULL
;
2158 files_struct
*fsp
= NULL
;
2162 connection_struct
*conn
= NULL
;
2164 char *oldcwd
= NULL
;
2165 struct security_descriptor
*psd
= NULL
;
2166 uint32_t security_info_sent
= 0;
2171 werr
= WERR_NET_NAME_NOT_FOUND
;
2175 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2182 DEBUG(10, ("Could not find service %s\n", servicename
));
2183 werr
= WERR_NET_NAME_NOT_FOUND
;
2187 nt_status
= create_conn_struct(talloc_tos(),
2188 server_event_context(),
2189 server_messaging_context(),
2191 snum
, lp_pathname(talloc_tos(), snum
),
2192 p
->session_info
, &oldcwd
);
2193 if (!NT_STATUS_IS_OK(nt_status
)) {
2194 DEBUG(10, ("create_conn_struct failed: %s\n",
2195 nt_errstr(nt_status
)));
2196 werr
= ntstatus_to_werror(nt_status
);
2200 nt_status
= filename_convert(talloc_tos(),
2207 if (!NT_STATUS_IS_OK(nt_status
)) {
2208 werr
= ntstatus_to_werror(nt_status
);
2212 nt_status
= SMB_VFS_CREATE_FILE(
2215 0, /* root_dir_fid */
2216 smb_fname
, /* fname */
2217 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2218 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2219 FILE_OPEN
, /* create_disposition*/
2220 0, /* create_options */
2221 0, /* file_attributes */
2222 INTERNAL_OPEN_ONLY
, /* oplock_request */
2223 0, /* allocation_size */
2224 0, /* private_flags */
2230 if (!NT_STATUS_IS_OK(nt_status
)) {
2231 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2232 smb_fname_str_dbg(smb_fname
)));
2233 werr
= ntstatus_to_werror(nt_status
);
2237 psd
= r
->in
.sd_buf
->sd
;
2238 security_info_sent
= r
->in
.securityinformation
;
2240 nt_status
= set_sd(fsp
, psd
, security_info_sent
);
2242 if (!NT_STATUS_IS_OK(nt_status
) ) {
2243 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2244 "on file %s\n", r
->in
.share
));
2245 werr
= WERR_ACCESS_DENIED
;
2249 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2250 vfs_ChDir(conn
, oldcwd
);
2251 SMB_VFS_DISCONNECT(conn
);
2259 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2263 vfs_ChDir(conn
, oldcwd
);
2267 SMB_VFS_DISCONNECT(conn
);
2272 TALLOC_FREE(smb_fname
);
2277 /***********************************************************************************
2278 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2279 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2280 These disks would the disks listed by this function.
2281 Users could then create shares relative to these disks. Watch out for moving these disks around.
2282 "Nigel Williams" <nigel@veritas.com>.
2283 ***********************************************************************************/
2285 static const char *server_disks
[] = {"C:"};
2287 static uint32
get_server_disk_count(void)
2289 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2292 static uint32
init_server_disk_enum(uint32
*resume
)
2294 uint32 server_disk_count
= get_server_disk_count();
2296 /*resume can be an offset into the list for now*/
2298 if(*resume
& 0x80000000)
2301 if(*resume
> server_disk_count
)
2302 *resume
= server_disk_count
;
2304 return server_disk_count
- *resume
;
2307 static const char *next_server_disk_enum(uint32
*resume
)
2311 if(init_server_disk_enum(resume
) == 0)
2314 disk
= server_disks
[*resume
];
2318 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2323 /********************************************************************
2325 ********************************************************************/
2327 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2328 struct srvsvc_NetDiskEnum
*r
)
2331 const char *disk_name
;
2332 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2334 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2338 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2340 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2341 MAX_SERVER_DISK_ENTRIES
);
2342 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2344 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2346 r
->out
.info
->count
= 0;
2348 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2350 r
->out
.info
->count
++;
2352 /*copy disk name into a unicode string*/
2354 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2355 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2358 /* add a terminating null string. Is this there if there is more data to come? */
2360 r
->out
.info
->count
++;
2362 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2363 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2365 if (r
->out
.resume_handle
) {
2366 *r
->out
.resume_handle
= resume
;
2372 /********************************************************************
2373 _srvsvc_NetNameValidate
2374 ********************************************************************/
2376 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2377 struct srvsvc_NetNameValidate
*r
)
2379 switch (r
->in
.name_type
) {
2381 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2382 strlen_m(r
->in
.name
)))
2384 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2386 return WERR_INVALID_NAME
;
2391 return WERR_UNKNOWN_LEVEL
;
2397 /*******************************************************************
2398 ********************************************************************/
2400 struct enum_file_close_state
{
2401 struct srvsvc_NetFileClose
*r
;
2402 struct messaging_context
*msg_ctx
;
2405 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2406 const char *sharepath
, const char *fname
,
2407 void *private_data
)
2409 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2410 struct enum_file_close_state
*state
=
2411 (struct enum_file_close_state
*)private_data
;
2412 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2414 if (fid
!= state
->r
->in
.fid
) {
2415 return; /* Not this file. */
2418 if (!process_exists(e
->pid
) ) {
2422 /* Ok - send the close message. */
2423 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2425 share_mode_str(talloc_tos(), 0, e
) ));
2427 share_mode_entry_to_message(msg
, e
);
2429 state
->r
->out
.result
= ntstatus_to_werror(
2430 messaging_send_buf(state
->msg_ctx
,
2431 e
->pid
, MSG_SMB_CLOSE_FILE
,
2433 MSG_SMB_SHARE_MODE_ENTRY_SIZE
));
2436 /********************************************************************
2437 Close a file given a 32-bit file id.
2438 ********************************************************************/
2440 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2441 struct srvsvc_NetFileClose
*r
)
2443 struct enum_file_close_state state
;
2446 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2448 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2450 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2451 return WERR_ACCESS_DENIED
;
2454 /* enum_file_close_fn sends the close message to
2455 * the relevent smbd process. */
2457 r
->out
.result
= WERR_BADFILE
;
2459 state
.msg_ctx
= p
->msg_ctx
;
2460 share_mode_forall(enum_file_close_fn
, &state
);
2461 return r
->out
.result
;
2464 /********************************************************************
2465 ********************************************************************/
2467 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2468 struct srvsvc_NetCharDevEnum
*r
)
2470 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2471 return WERR_NOT_SUPPORTED
;
2474 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2475 struct srvsvc_NetCharDevGetInfo
*r
)
2477 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2478 return WERR_NOT_SUPPORTED
;
2481 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2482 struct srvsvc_NetCharDevControl
*r
)
2484 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2485 return WERR_NOT_SUPPORTED
;
2488 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2489 struct srvsvc_NetCharDevQEnum
*r
)
2491 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2492 return WERR_NOT_SUPPORTED
;
2495 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2496 struct srvsvc_NetCharDevQGetInfo
*r
)
2498 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2499 return WERR_NOT_SUPPORTED
;
2502 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2503 struct srvsvc_NetCharDevQSetInfo
*r
)
2505 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2506 return WERR_NOT_SUPPORTED
;
2509 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2510 struct srvsvc_NetCharDevQPurge
*r
)
2512 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2513 return WERR_NOT_SUPPORTED
;
2516 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2517 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2519 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2520 return WERR_NOT_SUPPORTED
;
2523 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2524 struct srvsvc_NetFileGetInfo
*r
)
2526 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2527 return WERR_NOT_SUPPORTED
;
2530 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2531 struct srvsvc_NetShareCheck
*r
)
2533 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2534 return WERR_NOT_SUPPORTED
;
2537 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2538 struct srvsvc_NetServerStatisticsGet
*r
)
2540 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2541 return WERR_NOT_SUPPORTED
;
2544 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2545 struct srvsvc_NetTransportAdd
*r
)
2547 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2548 return WERR_NOT_SUPPORTED
;
2551 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2552 struct srvsvc_NetTransportEnum
*r
)
2554 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2555 return WERR_NOT_SUPPORTED
;
2558 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2559 struct srvsvc_NetTransportDel
*r
)
2561 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2562 return WERR_NOT_SUPPORTED
;
2565 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2566 struct srvsvc_NetSetServiceBits
*r
)
2568 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2569 return WERR_NOT_SUPPORTED
;
2572 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2573 struct srvsvc_NetPathType
*r
)
2575 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2576 return WERR_NOT_SUPPORTED
;
2579 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2580 struct srvsvc_NetPathCanonicalize
*r
)
2582 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2583 return WERR_NOT_SUPPORTED
;
2586 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2587 struct srvsvc_NetPathCompare
*r
)
2589 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2590 return WERR_NOT_SUPPORTED
;
2593 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2594 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2596 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2597 return WERR_NOT_SUPPORTED
;
2600 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2601 struct srvsvc_NetPRNameCompare
*r
)
2603 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2604 return WERR_NOT_SUPPORTED
;
2607 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2608 struct srvsvc_NetShareDelStart
*r
)
2610 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2611 return WERR_NOT_SUPPORTED
;
2614 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2615 struct srvsvc_NetShareDelCommit
*r
)
2617 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2618 return WERR_NOT_SUPPORTED
;
2621 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2622 struct srvsvc_NetServerTransportAddEx
*r
)
2624 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2625 return WERR_NOT_SUPPORTED
;
2628 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2629 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2631 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2632 return WERR_NOT_SUPPORTED
;
2635 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2636 struct srvsvc_NETRDFSGETVERSION
*r
)
2638 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2639 return WERR_NOT_SUPPORTED
;
2642 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2643 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2645 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2646 return WERR_NOT_SUPPORTED
;
2649 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2650 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2652 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2653 return WERR_NOT_SUPPORTED
;
2656 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2657 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2659 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2660 return WERR_NOT_SUPPORTED
;
2663 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2664 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2666 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2667 return WERR_NOT_SUPPORTED
;
2670 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2671 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2673 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2674 return WERR_NOT_SUPPORTED
;
2677 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2678 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2680 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2681 return WERR_NOT_SUPPORTED
;
2684 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2685 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2687 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2688 return WERR_NOT_SUPPORTED
;
2691 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2692 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2694 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2695 return WERR_NOT_SUPPORTED
;
2698 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2699 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2701 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2702 return WERR_NOT_SUPPORTED
;
2705 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2706 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2708 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2709 return WERR_NOT_SUPPORTED
;