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_info
{
58 struct srvsvc_NetSessCtr1
*ctr
;
59 struct sessionid
*session_list
;
60 uint32_t resume_handle
;
64 struct share_file_stat
{
65 struct srvsvc_NetConnInfo1
*netconn_arr
;
66 struct server_id
*svrid_arr
;
67 const char *in_sharepath
;
68 uint32_t resp_entries
;
69 uint32_t total_entries
;
72 struct share_conn_stat
{
74 const char *sharename
;
75 struct server_id
*svrid_arr
;
79 /*******************************************************************
80 ********************************************************************/
82 static int enum_file_fn(const struct share_mode_entry
*e
,
83 const char *sharepath
, const char *fname
,
86 struct file_enum_count
*fenum
=
87 (struct file_enum_count
*)private_data
;
89 struct srvsvc_NetFileInfo3
*f
;
90 int i
= fenum
->ctr3
->count
;
92 struct byte_range_lock
*brl
;
94 char *fullpath
= NULL
;
98 /* If the pid was not found delete the entry from connections.tdb */
100 if ( !process_exists(e
->pid
) ) {
104 username
= uidtoname(e
->uid
);
106 if ((fenum
->username
!= NULL
)
107 && !strequal(username
, fenum
->username
)) {
111 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
112 struct srvsvc_NetFileInfo3
, i
+1);
114 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
117 fenum
->ctr3
->array
= f
;
119 /* need to count the number of locks on a file */
124 if ( (brl
= brl_get_locks(talloc_tos(), &fsp
)) != NULL
) {
125 num_locks
= brl_num_locks(brl
);
129 if ( strcmp( fname
, "." ) == 0 ) {
130 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s", sharepath
);
132 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s/%s",
138 string_replace( fullpath
, '/', '\\' );
140 /* mask out create (what ever that is) */
141 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
143 /* now fill in the srvsvc_NetFileInfo3 struct */
145 fenum
->ctr3
->array
[i
].fid
=
146 (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
147 fenum
->ctr3
->array
[i
].permissions
= permissions
;
148 fenum
->ctr3
->array
[i
].num_locks
= num_locks
;
149 fenum
->ctr3
->array
[i
].path
= fullpath
;
150 fenum
->ctr3
->array
[i
].user
= username
;
152 fenum
->ctr3
->count
++;
157 /*******************************************************************
158 ********************************************************************/
160 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
161 const char *username
,
162 struct srvsvc_NetFileCtr3
**ctr3
,
165 struct file_enum_count f_enum_cnt
;
167 f_enum_cnt
.ctx
= ctx
;
168 f_enum_cnt
.username
= username
;
169 f_enum_cnt
.ctr3
= *ctr3
;
171 share_entry_forall( enum_file_fn
, (void *)&f_enum_cnt
);
173 *ctr3
= f_enum_cnt
.ctr3
;
178 /*******************************************************************
179 Utility function to get the 'type' of a share from an snum.
180 ********************************************************************/
181 static enum srvsvc_ShareType
get_share_type(int snum
)
183 /* work out the share type */
184 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
186 if (lp_printable(snum
)) {
187 type
= lp_administrative_share(snum
)
188 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
190 if (strequal(lp_fstype(snum
), "IPC")) {
191 type
= lp_administrative_share(snum
)
192 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
197 /*******************************************************************
198 Fill in a share info level 0 structure.
199 ********************************************************************/
201 static void init_srv_share_info_0(struct pipes_struct
*p
,
202 struct srvsvc_NetShareInfo0
*r
, int snum
)
204 r
->name
= lp_servicename(talloc_tos(), snum
);
207 /*******************************************************************
208 Fill in a share info level 1 structure.
209 ********************************************************************/
211 static void init_srv_share_info_1(struct pipes_struct
*p
,
212 struct srvsvc_NetShareInfo1
*r
,
215 char *net_name
= lp_servicename(talloc_tos(), snum
);
216 char *remark
= lp_comment(p
->mem_ctx
, snum
);
219 remark
= talloc_sub_advanced(
220 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
221 get_current_username(), lp_path(talloc_tos(), snum
),
222 p
->session_info
->unix_token
->uid
, get_current_username(),
227 r
->type
= get_share_type(snum
);
228 r
->comment
= remark
? remark
: "";
231 /*******************************************************************
232 Fill in a share info level 2 structure.
233 ********************************************************************/
235 static void init_srv_share_info_2(struct pipes_struct
*p
,
236 struct srvsvc_NetShareInfo2
*r
,
241 int max_connections
= lp_max_connections(snum
);
242 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
243 char *net_name
= lp_servicename(talloc_tos(), snum
);
245 remark
= lp_comment(p
->mem_ctx
, snum
);
247 remark
= talloc_sub_advanced(
248 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
249 get_current_username(), lp_path(talloc_tos(), snum
),
250 p
->session_info
->unix_token
->uid
, get_current_username(),
253 path
= talloc_asprintf(p
->mem_ctx
,
254 "C:%s", lp_path(talloc_tos(), snum
));
258 * Change / to \\ so that win2k will see it as a valid path.
259 * This was added to enable use of browsing in win2k add
263 string_replace(path
, '/', '\\');
267 r
->type
= get_share_type(snum
);
268 r
->comment
= remark
? remark
: "";
270 r
->max_users
= max_uses
;
271 r
->current_users
= 0; /* computed later */
272 r
->path
= path
? path
: "";
276 /*******************************************************************
277 Map any generic bits to file specific bits.
278 ********************************************************************/
280 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
283 struct security_acl
*ps_dacl
= NULL
;
292 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
293 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
294 uint32 orig_mask
= psa
->access_mask
;
296 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
297 psa
->access_mask
|= orig_mask
;
301 /*******************************************************************
302 Fill in a share info level 501 structure.
303 ********************************************************************/
305 static void init_srv_share_info_501(struct pipes_struct
*p
,
306 struct srvsvc_NetShareInfo501
*r
, int snum
)
308 const char *net_name
= lp_servicename(talloc_tos(), snum
);
309 char *remark
= lp_comment(p
->mem_ctx
, snum
);
312 remark
= talloc_sub_advanced(
313 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
314 get_current_username(), lp_path(talloc_tos(), snum
),
315 p
->session_info
->unix_token
->uid
, get_current_username(),
320 r
->type
= get_share_type(snum
);
321 r
->comment
= remark
? remark
: "";
324 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
327 r
->csc_policy
= (lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
);
330 /*******************************************************************
331 Fill in a share info level 502 structure.
332 ********************************************************************/
334 static void init_srv_share_info_502(struct pipes_struct
*p
,
335 struct srvsvc_NetShareInfo502
*r
, int snum
)
337 const char *net_name
= lp_servicename(talloc_tos(), snum
);
339 struct security_descriptor
*sd
= NULL
;
340 struct sec_desc_buf
*sd_buf
= NULL
;
342 TALLOC_CTX
*ctx
= p
->mem_ctx
;
343 char *remark
= lp_comment(ctx
, snum
);
346 remark
= talloc_sub_advanced(
347 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
348 get_current_username(), lp_path(talloc_tos(), snum
),
349 p
->session_info
->unix_token
->uid
, get_current_username(),
352 path
= talloc_asprintf(ctx
, "C:%s", lp_path(talloc_tos(), snum
));
355 * Change / to \\ so that win2k will see it as a valid path. This was added to
356 * enable use of browsing in win2k add share dialog.
358 string_replace(path
, '/', '\\');
361 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
363 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
366 r
->type
= get_share_type(snum
);
367 r
->comment
= remark
? remark
: "";
369 r
->max_users
= (uint32_t)-1;
370 r
->current_users
= 1; /* ??? */
371 r
->path
= path
? path
: "";
376 /***************************************************************************
377 Fill in a share info level 1004 structure.
378 ***************************************************************************/
380 static void init_srv_share_info_1004(struct pipes_struct
*p
,
381 struct srvsvc_NetShareInfo1004
*r
,
384 char *remark
= lp_comment(p
->mem_ctx
, snum
);
387 remark
= talloc_sub_advanced(
388 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
389 get_current_username(), lp_path(talloc_tos(), snum
),
390 p
->session_info
->unix_token
->uid
, get_current_username(),
394 r
->comment
= remark
? remark
: "";
397 /***************************************************************************
398 Fill in a share info level 1005 structure.
399 ***************************************************************************/
401 static void init_srv_share_info_1005(struct pipes_struct
*p
,
402 struct srvsvc_NetShareInfo1005
*r
,
405 uint32_t dfs_flags
= 0;
407 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
408 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
411 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
413 r
->dfs_flags
= dfs_flags
;
416 /***************************************************************************
417 Fill in a share info level 1006 structure.
418 ***************************************************************************/
420 static void init_srv_share_info_1006(struct pipes_struct
*p
,
421 struct srvsvc_NetShareInfo1006
*r
,
424 r
->max_users
= (uint32_t)-1;
427 /***************************************************************************
428 Fill in a share info level 1007 structure.
429 ***************************************************************************/
431 static void init_srv_share_info_1007(struct pipes_struct
*p
,
432 struct srvsvc_NetShareInfo1007
*r
,
436 r
->alternate_directory_name
= "";
439 /*******************************************************************
440 Fill in a share info level 1501 structure.
441 ********************************************************************/
443 static void init_srv_share_info_1501(struct pipes_struct
*p
,
444 struct sec_desc_buf
**r
,
447 struct security_descriptor
*sd
;
448 struct sec_desc_buf
*sd_buf
= NULL
;
450 TALLOC_CTX
*ctx
= p
->mem_ctx
;
452 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
454 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
460 /*******************************************************************
461 True if it ends in '$'.
462 ********************************************************************/
464 static bool is_hidden_share(int snum
)
466 const char *net_name
= lp_servicename(talloc_tos(), snum
);
468 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
471 /*******************************************************************
472 Verify user is allowed to view share, access based enumeration
473 ********************************************************************/
474 static bool is_enumeration_allowed(struct pipes_struct
*p
,
477 if (!lp_access_based_share_enum(snum
))
480 return share_access_check(p
->session_info
->security_token
,
481 lp_servicename(talloc_tos(), snum
),
482 FILE_READ_DATA
, NULL
);
485 /****************************************************************************
486 Count an entry against the respective service.
487 ****************************************************************************/
489 static int count_for_all_fn(struct smbXsrv_tcon_global0
*tcon
, void *udp
)
491 union srvsvc_NetShareCtr
*ctr
= NULL
;
492 struct srvsvc_NetShareInfo2
*info2
= NULL
;
493 int share_entries
= 0;
496 ctr
= (union srvsvc_NetShareCtr
*) udp
;
499 share_entries
= ctr
->ctr2
->count
;
500 info2
= &ctr
->ctr2
->array
[0];
502 for (i
= 0; i
< share_entries
; i
++, info2
++) {
503 if (strequal(tcon
->share_name
, info2
->name
)) {
504 info2
->current_users
++;
512 /****************************************************************************
513 Count the entries belonging to all services in the connection db.
514 ****************************************************************************/
516 static void count_connections_for_all_shares(union srvsvc_NetShareCtr
*ctr
)
519 status
= smbXsrv_tcon_global_traverse(count_for_all_fn
, ctr
);
521 if (!NT_STATUS_IS_OK(status
)) {
522 DEBUG(0,("count_connections_for_all_shares: traverse of "
523 "smbXsrv_tcon_global.tdb failed - %s\n",
528 /*******************************************************************
529 Fill in a share info structure.
530 ********************************************************************/
532 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
533 struct srvsvc_NetShareInfoCtr
*info_ctr
,
534 uint32_t *resume_handle_p
,
535 uint32_t *total_entries
,
539 int alloc_entries
= 0;
540 int num_services
= 0;
542 TALLOC_CTX
*ctx
= p
->mem_ctx
;
544 int valid_share_count
= 0;
546 union srvsvc_NetShareCtr ctr
;
547 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
549 DEBUG(5,("init_srv_share_info_ctr\n"));
551 /* Ensure all the usershares are loaded. */
553 delete_and_reload_printers(server_event_context(), p
->msg_ctx
);
554 load_usershare_shares(NULL
, connections_snum_used
);
555 load_registry_shares();
556 num_services
= lp_numservices();
559 allowed
= talloc_zero_array(ctx
, bool, num_services
);
560 W_ERROR_HAVE_NO_MEMORY(allowed
);
562 /* Count the number of entries. */
563 for (snum
= 0; snum
< num_services
; snum
++) {
564 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
565 is_enumeration_allowed(p
, snum
) &&
566 (all_shares
|| !is_hidden_share(snum
)) ) {
567 DEBUG(10, ("counting service %s\n",
568 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
569 allowed
[snum
] = true;
572 DEBUG(10, ("NOT counting service %s\n",
573 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
577 if (!num_entries
|| (resume_handle
>= num_entries
)) {
581 /* Calculate alloc entries. */
582 alloc_entries
= num_entries
- resume_handle
;
583 switch (info_ctr
->level
) {
585 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
586 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
588 ctr
.ctr0
->count
= alloc_entries
;
589 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
590 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
592 for (snum
= 0; snum
< num_services
; snum
++) {
594 (resume_handle
<= (i
+ valid_share_count
++)) ) {
595 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
602 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
603 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
605 ctr
.ctr1
->count
= alloc_entries
;
606 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
607 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
609 for (snum
= 0; snum
< num_services
; snum
++) {
611 (resume_handle
<= (i
+ valid_share_count
++)) ) {
612 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
619 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
620 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
622 ctr
.ctr2
->count
= alloc_entries
;
623 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
624 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
626 for (snum
= 0; snum
< num_services
; snum
++) {
628 (resume_handle
<= (i
+ valid_share_count
++)) ) {
629 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
633 count_connections_for_all_shares(&ctr
);
637 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
638 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
640 ctr
.ctr501
->count
= alloc_entries
;
641 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
642 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
644 for (snum
= 0; snum
< num_services
; snum
++) {
646 (resume_handle
<= (i
+ valid_share_count
++)) ) {
647 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
654 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
655 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
657 ctr
.ctr502
->count
= alloc_entries
;
658 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
659 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
661 for (snum
= 0; snum
< num_services
; snum
++) {
663 (resume_handle
<= (i
+ valid_share_count
++)) ) {
664 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
671 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
672 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
674 ctr
.ctr1004
->count
= alloc_entries
;
675 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
676 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
678 for (snum
= 0; snum
< num_services
; snum
++) {
680 (resume_handle
<= (i
+ valid_share_count
++)) ) {
681 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
688 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
689 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
691 ctr
.ctr1005
->count
= alloc_entries
;
692 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
693 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
695 for (snum
= 0; snum
< num_services
; snum
++) {
697 (resume_handle
<= (i
+ valid_share_count
++)) ) {
698 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
705 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
706 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
708 ctr
.ctr1006
->count
= alloc_entries
;
709 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
710 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
712 for (snum
= 0; snum
< num_services
; snum
++) {
714 (resume_handle
<= (i
+ valid_share_count
++)) ) {
715 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
722 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
723 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
725 ctr
.ctr1007
->count
= alloc_entries
;
726 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
727 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
729 for (snum
= 0; snum
< num_services
; snum
++) {
731 (resume_handle
<= (i
+ valid_share_count
++)) ) {
732 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
739 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
740 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
742 ctr
.ctr1501
->count
= alloc_entries
;
743 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
744 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
746 for (snum
= 0; snum
< num_services
; snum
++) {
748 (resume_handle
<= (i
+ valid_share_count
++)) ) {
749 struct sec_desc_buf
*sd_buf
= NULL
;
750 init_srv_share_info_1501(p
, &sd_buf
, snum
);
751 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
758 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
760 return WERR_UNKNOWN_LEVEL
;
763 *total_entries
= alloc_entries
;
764 if (resume_handle_p
) {
766 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
768 *resume_handle_p
= num_entries
;
777 /*******************************************************************
778 fill in a sess info level 0 structure.
779 ********************************************************************/
781 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
782 struct srvsvc_NetSessCtr0
*ctr0
,
783 uint32_t *resume_handle_p
,
784 uint32_t *total_entries
)
786 struct sessionid
*session_list
;
787 uint32_t num_entries
= 0;
788 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
789 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
791 DEBUG(5,("init_srv_sess_info_0\n"));
794 if (resume_handle_p
) {
795 *resume_handle_p
= 0;
800 for (; resume_handle
< *total_entries
; resume_handle
++) {
802 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
804 struct srvsvc_NetSessInfo0
,
806 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
808 ctr0
->array
[num_entries
].client
=
809 session_list
[resume_handle
].remote_machine
;
814 ctr0
->count
= num_entries
;
816 if (resume_handle_p
) {
817 if (*resume_handle_p
>= *total_entries
) {
818 *resume_handle_p
= 0;
820 *resume_handle_p
= resume_handle
;
827 /***********************************************************************
828 * find out the session on which this file is open and bump up its count
829 **********************************************************************/
831 static int count_sess_files_fn(const struct share_mode_entry
*e
,
832 const char *sharepath
, const char *fname
,
835 struct sess_file_info
*info
= data
;
836 uint32_t rh
= info
->resume_handle
;
839 for (i
=0; i
< info
->num_entries
; i
++) {
840 /* rh+info->num_entries is safe, as we've
842 *total_entries > resume_handle &&
843 info->num_entries = *total_entries - resume_handle;
844 inside init_srv_sess_info_1() below.
846 struct sessionid
*sess
= &info
->session_list
[rh
+ i
];
847 if ((e
->uid
== sess
->uid
) &&
848 serverid_equal(&e
->pid
, &sess
->pid
)) {
850 info
->ctr
->array
[i
].num_open
++;
857 /*******************************************************************
858 * count the num of open files on all sessions
859 *******************************************************************/
861 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1
*ctr1
,
862 struct sessionid
*session_list
,
863 uint32_t resume_handle
,
864 uint32_t num_entries
)
866 struct sess_file_info s_file_info
;
868 s_file_info
.ctr
= ctr1
;
869 s_file_info
.session_list
= session_list
;
870 s_file_info
.resume_handle
= resume_handle
;
871 s_file_info
.num_entries
= num_entries
;
873 share_entry_forall(count_sess_files_fn
, &s_file_info
);
876 /*******************************************************************
877 fill in a sess info level 1 structure.
878 ********************************************************************/
880 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
881 struct srvsvc_NetSessCtr1
*ctr1
,
882 uint32_t *resume_handle_p
,
883 uint32_t *total_entries
)
885 struct sessionid
*session_list
;
886 uint32_t num_entries
= 0;
887 time_t now
= time(NULL
);
888 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
893 if (resume_handle_p
) {
894 *resume_handle_p
= 0;
899 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
901 if (resume_handle
>= *total_entries
) {
902 if (resume_handle_p
) {
903 *resume_handle_p
= 0;
908 /* We know num_entries must be positive, due to
909 the check resume_handle >= *total_entries above. */
911 num_entries
= *total_entries
- resume_handle
;
913 ctr1
->array
= talloc_zero_array(p
->mem_ctx
,
914 struct srvsvc_NetSessInfo1
,
917 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
919 for (num_entries
= 0; resume_handle
< *total_entries
; num_entries
++, resume_handle
++) {
923 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
924 guest
= strequal( session_list
[resume_handle
].username
, lp_guest_account() );
926 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
927 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
928 ctr1
->array
[num_entries
].num_open
= 0;/* computed later */
929 ctr1
->array
[num_entries
].time
= connect_time
;
930 ctr1
->array
[num_entries
].idle_time
= 0;
931 ctr1
->array
[num_entries
].user_flags
= guest
;
934 ctr1
->count
= num_entries
;
936 /* count open files on all sessions in single tdb traversal */
937 net_count_files_for_all_sess(ctr1
, session_list
,
938 resume_handle_p
? *resume_handle_p
: 0,
941 if (resume_handle_p
) {
942 if (*resume_handle_p
>= *total_entries
) {
943 *resume_handle_p
= 0;
945 *resume_handle_p
= resume_handle
;
952 /*******************************************************************
953 find the share connection on which this open exists.
954 ********************************************************************/
956 static int share_file_fn(const struct share_mode_entry
*e
,
957 const char *sharepath
, const char *fname
,
960 struct share_file_stat
*sfs
= data
;
962 uint32_t offset
= sfs
->total_entries
- sfs
->resp_entries
;
964 if (strequal(sharepath
, sfs
->in_sharepath
)) {
965 for (i
=0; i
< sfs
->resp_entries
; i
++) {
966 if (serverid_equal(&e
->pid
, &sfs
->svrid_arr
[offset
+ i
])) {
967 sfs
->netconn_arr
[i
].num_open
++;
975 /*******************************************************************
976 count number of open files on given share connections.
977 ********************************************************************/
979 static void count_share_opens(struct srvsvc_NetConnInfo1
*arr
,
980 struct server_id
*svrid_arr
, char *sharepath
,
981 uint32_t resp_entries
, uint32_t total_entries
)
983 struct share_file_stat sfs
;
985 sfs
.netconn_arr
= arr
;
986 sfs
.svrid_arr
= svrid_arr
;
987 sfs
.in_sharepath
= sharepath
;
988 sfs
.resp_entries
= resp_entries
;
989 sfs
.total_entries
= total_entries
;
991 share_entry_forall(share_file_fn
, &sfs
);
994 /****************************************************************************
995 process an entry from the connection db.
996 ****************************************************************************/
998 static int share_conn_fn(struct smbXsrv_tcon_global0
*tcon
,
1001 struct share_conn_stat
*scs
= data
;
1003 if (!process_exists(tcon
->server_id
)) {
1007 if (strequal(tcon
->share_name
, scs
->sharename
)) {
1008 scs
->svrid_arr
= talloc_realloc(scs
->ctx
, scs
->svrid_arr
,
1011 if (!scs
->svrid_arr
) {
1015 scs
->svrid_arr
[scs
->count
] = tcon
->server_id
;
1022 /****************************************************************************
1023 Count the connections to a share. Build an array of serverid's owning these
1025 ****************************************************************************/
1027 static uint32_t count_share_conns(TALLOC_CTX
*ctx
, const char *sharename
,
1028 struct server_id
**arr
)
1030 struct share_conn_stat scs
;
1034 scs
.sharename
= sharename
;
1035 scs
.svrid_arr
= NULL
;
1038 status
= smbXsrv_tcon_global_traverse(share_conn_fn
, &scs
);
1040 if (!NT_STATUS_IS_OK(status
)) {
1041 DEBUG(0,("count_share_conns: traverse of "
1042 "smbXsrv_tcon_global.tdb failed - %s\n",
1043 nt_errstr(status
)));
1047 *arr
= scs
.svrid_arr
;
1051 /*******************************************************************
1052 fill in a conn info level 0 structure.
1053 ********************************************************************/
1055 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
1056 uint32_t *resume_handle_p
,
1057 uint32_t *total_entries
)
1059 uint32_t num_entries
= 0;
1060 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1062 DEBUG(5,("init_srv_conn_info_0\n"));
1065 if (resume_handle_p
) {
1066 *resume_handle_p
= 0;
1075 for (; resume_handle
< *total_entries
; resume_handle
++) {
1077 ctr0
->array
= talloc_realloc(talloc_tos(),
1079 struct srvsvc_NetConnInfo0
,
1085 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
1087 /* move on to creating next connection */
1091 ctr0
->count
= num_entries
;
1092 *total_entries
= num_entries
;
1094 if (resume_handle_p
) {
1095 if (*resume_handle_p
>= *total_entries
) {
1096 *resume_handle_p
= 0;
1098 *resume_handle_p
= resume_handle
;
1105 /*******************************************************************
1106 fill in a conn info level 1 structure.
1107 ********************************************************************/
1109 static WERROR
init_srv_conn_info_1(const char *name
,
1110 struct srvsvc_NetConnCtr1
*ctr1
,
1111 uint32_t *resume_handle_p
,
1112 uint32_t *total_entries
)
1114 uint32_t num_entries
= 0, snum
= 0;
1115 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1116 char *share_name
= NULL
;
1117 struct server_id
*svrid_arr
= NULL
;
1119 DEBUG(5,("init_srv_conn_info_1\n"));
1122 if (resume_handle_p
) {
1123 *resume_handle_p
= 0;
1128 /* check if this is a server name or a share name */
1129 if (name
&& (strlen(name
) > 2) && (name
[0] == '\\') &&
1130 (name
[1] == '\\')) {
1132 /* 'name' is a server name - this part is unimplemented */
1135 /* 'name' is a share name */
1136 snum
= find_service(talloc_tos(), name
, &share_name
);
1143 return WERR_INVALID_NAME
;
1147 * count the num of connections to this share. Also,
1148 * build a list of serverid's that own these
1149 * connections. The serverid list is used later to
1150 * identify the share connection on which an open exists.
1153 *total_entries
= count_share_conns(talloc_tos(),
1158 if (resume_handle
>= *total_entries
) {
1159 if (resume_handle_p
) {
1160 *resume_handle_p
= 0;
1166 * We know num_entries must be positive, due to
1167 * the check resume_handle >= *total_entries above.
1170 num_entries
= *total_entries
- resume_handle
;
1174 ctr1
->array
= talloc_zero_array(talloc_tos(),
1175 struct srvsvc_NetConnInfo1
,
1178 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
1180 for (num_entries
= 0; resume_handle
< *total_entries
;
1181 num_entries
++, resume_handle
++) {
1183 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1184 ctr1
->array
[num_entries
].conn_type
= 0x3;
1187 * if these are connections to a share, we are going to
1188 * compute the opens on them later. If it's for the server,
1189 * it's unimplemented.
1193 ctr1
->array
[num_entries
].num_open
= 1;
1196 ctr1
->array
[num_entries
].num_users
= 1;
1197 ctr1
->array
[num_entries
].conn_time
= 3;
1198 ctr1
->array
[num_entries
].user
= "dummy_user";
1199 ctr1
->array
[num_entries
].share
= "IPC$";
1202 /* now compute open files on the share connections */
1207 * the locking tdb, which has the open files information,
1208 * does not store share name or share (service) number, but
1209 * just the share path. So, we can compute open files only
1210 * on the share path. If more than one shares are defined
1211 * on a share path, open files on all of them are included
1214 * To have the correct behavior in case multiple shares
1215 * are defined on the same path, changes to tdb records
1216 * would be required. That would be lot more effort, so
1217 * this seems a good stopgap fix.
1220 count_share_opens(ctr1
->array
, svrid_arr
,
1221 lp_path(talloc_tos(), snum
),
1222 num_entries
, *total_entries
);
1226 ctr1
->count
= num_entries
;
1227 *total_entries
= num_entries
;
1229 if (resume_handle_p
) {
1230 *resume_handle_p
= resume_handle
;
1236 /*******************************************************************
1238 *******************************************************************/
1240 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1241 struct srvsvc_NetFileEnum
*r
)
1243 TALLOC_CTX
*ctx
= NULL
;
1244 struct srvsvc_NetFileCtr3
*ctr3
;
1245 uint32_t resume_hnd
= 0;
1248 switch (r
->in
.info_ctr
->level
) {
1252 return WERR_UNKNOWN_LEVEL
;
1255 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1256 p
->session_info
->security_token
)) {
1257 DEBUG(1, ("Enumerating files only allowed for "
1258 "administrators\n"));
1259 return WERR_ACCESS_DENIED
;
1263 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1265 werr
= WERR_INVALID_PARAM
;
1269 /* TODO -- Windows enumerates
1271 (c) open directories and files */
1273 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1274 if (!W_ERROR_IS_OK(werr
)) {
1278 *r
->out
.totalentries
= ctr3
->count
;
1279 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1280 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1288 /*******************************************************************
1289 _srvsvc_NetSrvGetInfo
1290 ********************************************************************/
1292 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1293 struct srvsvc_NetSrvGetInfo
*r
)
1295 WERROR status
= WERR_OK
;
1297 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1299 if (!pipe_access_check(p
)) {
1300 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1301 return WERR_ACCESS_DENIED
;
1304 switch (r
->in
.level
) {
1306 /* Technically level 102 should only be available to
1307 Administrators but there isn't anything super-secret
1308 here, as most of it is made up. */
1311 struct srvsvc_NetSrvInfo102
*info102
;
1313 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1318 info102
->platform_id
= PLATFORM_ID_NT
;
1319 info102
->server_name
= lp_netbios_name();
1320 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1321 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1322 info102
->server_type
= lp_default_server_announce();
1323 info102
->comment
= string_truncate(lp_server_string(talloc_tos()),
1324 MAX_SERVER_STRING_LENGTH
);
1325 info102
->users
= 0xffffffff;
1326 info102
->disc
= 0xf;
1327 info102
->hidden
= 0;
1328 info102
->announce
= 240;
1329 info102
->anndelta
= 3000;
1330 info102
->licenses
= 100000;
1331 info102
->userpath
= "C:\\";
1333 r
->out
.info
->info102
= info102
;
1337 struct srvsvc_NetSrvInfo101
*info101
;
1339 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1344 info101
->platform_id
= PLATFORM_ID_NT
;
1345 info101
->server_name
= lp_netbios_name();
1346 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1347 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1348 info101
->server_type
= lp_default_server_announce();
1349 info101
->comment
= string_truncate(lp_server_string(talloc_tos()),
1350 MAX_SERVER_STRING_LENGTH
);
1352 r
->out
.info
->info101
= info101
;
1356 struct srvsvc_NetSrvInfo100
*info100
;
1358 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1363 info100
->platform_id
= PLATFORM_ID_NT
;
1364 info100
->server_name
= lp_netbios_name();
1366 r
->out
.info
->info100
= info100
;
1371 status
= WERR_UNKNOWN_LEVEL
;
1375 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1380 /*******************************************************************
1381 _srvsvc_NetSrvSetInfo
1382 ********************************************************************/
1384 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1385 struct srvsvc_NetSrvSetInfo
*r
)
1387 WERROR status
= WERR_OK
;
1389 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1391 /* Set up the net server set info structure. */
1393 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1398 /*******************************************************************
1400 ********************************************************************/
1402 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1403 struct srvsvc_NetConnEnum
*r
)
1407 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1409 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1410 p
->session_info
->security_token
)) {
1411 DEBUG(1, ("Enumerating connections only allowed for "
1412 "administrators\n"));
1413 return WERR_ACCESS_DENIED
;
1416 switch (r
->in
.info_ctr
->level
) {
1418 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1419 r
->in
.resume_handle
,
1420 r
->out
.totalentries
);
1423 werr
= init_srv_conn_info_1(r
->in
.path
,
1424 r
->in
.info_ctr
->ctr
.ctr1
,
1425 r
->in
.resume_handle
,
1426 r
->out
.totalentries
);
1429 return WERR_UNKNOWN_LEVEL
;
1432 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1437 /*******************************************************************
1439 ********************************************************************/
1441 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1442 struct srvsvc_NetSessEnum
*r
)
1446 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1448 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1449 p
->session_info
->security_token
)) {
1450 DEBUG(1, ("Enumerating sessions only allowed for "
1451 "administrators\n"));
1452 return WERR_ACCESS_DENIED
;
1455 switch (r
->in
.info_ctr
->level
) {
1457 werr
= init_srv_sess_info_0(p
,
1458 r
->in
.info_ctr
->ctr
.ctr0
,
1459 r
->in
.resume_handle
,
1460 r
->out
.totalentries
);
1463 werr
= init_srv_sess_info_1(p
,
1464 r
->in
.info_ctr
->ctr
.ctr1
,
1465 r
->in
.resume_handle
,
1466 r
->out
.totalentries
);
1469 return WERR_UNKNOWN_LEVEL
;
1472 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1477 /*******************************************************************
1479 ********************************************************************/
1481 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1482 struct srvsvc_NetSessDel
*r
)
1484 struct sessionid
*session_list
;
1485 int num_sessions
, snum
;
1486 const char *username
;
1487 const char *machine
;
1488 bool not_root
= False
;
1491 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1493 werr
= WERR_ACCESS_DENIED
;
1495 /* fail out now if you are not root or not a domain admin */
1497 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1498 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1499 DOMAIN_RID_ADMINS
))) {
1504 username
= r
->in
.user
;
1505 machine
= r
->in
.client
;
1507 /* strip leading backslashes if any */
1508 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1512 num_sessions
= find_sessions(p
->mem_ctx
, username
, machine
,
1515 for (snum
= 0; snum
< num_sessions
; snum
++) {
1519 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1524 ntstat
= messaging_send(p
->msg_ctx
,
1525 session_list
[snum
].pid
,
1526 MSG_SHUTDOWN
, &data_blob_null
);
1528 if (NT_STATUS_IS_OK(ntstat
))
1535 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1542 /*******************************************************************
1543 _srvsvc_NetShareEnumAll
1544 ********************************************************************/
1546 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1547 struct srvsvc_NetShareEnumAll
*r
)
1551 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1553 if (!pipe_access_check(p
)) {
1554 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1555 return WERR_ACCESS_DENIED
;
1558 /* Create the list of shares for the response. */
1559 werr
= init_srv_share_info_ctr(p
,
1561 r
->in
.resume_handle
,
1562 r
->out
.totalentries
,
1565 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1570 /*******************************************************************
1571 _srvsvc_NetShareEnum
1572 ********************************************************************/
1574 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1575 struct srvsvc_NetShareEnum
*r
)
1579 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1581 if (!pipe_access_check(p
)) {
1582 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1583 return WERR_ACCESS_DENIED
;
1586 /* Create the list of shares for the response. */
1587 werr
= init_srv_share_info_ctr(p
,
1589 r
->in
.resume_handle
,
1590 r
->out
.totalentries
,
1593 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1598 /*******************************************************************
1599 _srvsvc_NetShareGetInfo
1600 ********************************************************************/
1602 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1603 struct srvsvc_NetShareGetInfo
*r
)
1605 WERROR status
= WERR_OK
;
1606 char *share_name
= NULL
;
1608 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1610 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1612 if (!r
->in
.share_name
) {
1613 return WERR_INVALID_NAME
;
1616 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1621 return WERR_INVALID_NAME
;
1624 switch (r
->in
.level
) {
1626 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1627 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1628 init_srv_share_info_0(p
, info
->info0
, snum
);
1631 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1632 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1633 init_srv_share_info_1(p
, info
->info1
, snum
);
1636 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1637 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1638 init_srv_share_info_2(p
, info
->info2
, snum
);
1639 info
->info2
->current_users
=
1640 count_current_connections(info
->info2
->name
, false);
1643 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1644 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1645 init_srv_share_info_501(p
, info
->info501
, snum
);
1648 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1649 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1650 init_srv_share_info_502(p
, info
->info502
, snum
);
1653 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1654 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1655 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1658 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1659 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1660 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1663 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1664 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1665 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1668 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1669 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1670 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1673 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1676 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1678 status
= WERR_UNKNOWN_LEVEL
;
1682 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1687 /*******************************************************************
1688 _srvsvc_NetShareSetInfo. Modify share details.
1689 ********************************************************************/
1691 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1692 struct srvsvc_NetShareSetInfo
*r
)
1694 char *command
= NULL
;
1695 char *share_name
= NULL
;
1696 char *comment
= NULL
;
1697 const char *pathname
= NULL
;
1702 struct security_descriptor
*psd
= NULL
;
1703 bool is_disk_op
= False
;
1704 const char *csc_policy
= NULL
;
1705 bool csc_policy_changed
= false;
1706 const char *csc_policies
[] = {"manual", "documents", "programs",
1708 uint32_t client_csc_policy
;
1709 int max_connections
= 0;
1710 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1711 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1713 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1715 if (!r
->in
.share_name
) {
1716 return WERR_INVALID_NAME
;
1719 if (r
->out
.parm_error
) {
1720 *r
->out
.parm_error
= 0;
1723 if ( strequal(r
->in
.share_name
,"IPC$")
1724 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1725 || strequal(r
->in
.share_name
,"global") )
1727 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1728 "modified by a remote user.\n",
1729 r
->in
.share_name
));
1730 return WERR_ACCESS_DENIED
;
1733 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1738 /* Does this share exist ? */
1740 return WERR_NET_NAME_NOT_FOUND
;
1742 /* No change to printer shares. */
1743 if (lp_printable(snum
))
1744 return WERR_ACCESS_DENIED
;
1746 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1748 /* fail out now if you are not root and not a disk op */
1750 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1751 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1752 "SeDiskOperatorPrivilege privilege needed to modify "
1754 (unsigned int)p
->session_info
->unix_token
->uid
,
1756 return WERR_ACCESS_DENIED
;
1759 max_connections
= lp_max_connections(snum
);
1760 csc_policy
= csc_policies
[lp_csc_policy(snum
)];
1762 switch (r
->in
.level
) {
1764 pathname
= lp_path(ctx
, snum
);
1765 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1766 type
= info
->info1
->type
;
1770 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1771 pathname
= info
->info2
->path
;
1772 type
= info
->info2
->type
;
1773 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1774 0 : info
->info2
->max_users
;
1778 /* not supported on set but here for completeness */
1780 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1781 type
= info
->info501
->type
;
1786 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1787 pathname
= info
->info502
->path
;
1788 type
= info
->info502
->type
;
1789 psd
= info
->info502
->sd_buf
.sd
;
1790 map_generic_share_sd_bits(psd
);
1793 pathname
= lp_path(ctx
, snum
);
1794 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1795 type
= STYPE_DISKTREE
;
1798 /* XP re-sets the csc policy even if it wasn't changed by the
1799 user, so we must compare it to see if it's what is set in
1800 smb.conf, so that we can contine other ops like setting
1802 client_csc_policy
= (info
->info1005
->dfs_flags
&
1803 SHARE_1005_CSC_POLICY_MASK
) >>
1804 SHARE_1005_CSC_POLICY_SHIFT
;
1806 if (client_csc_policy
== lp_csc_policy(snum
))
1809 csc_policy
= csc_policies
[client_csc_policy
];
1810 csc_policy_changed
= true;
1813 pathname
= lp_path(ctx
, snum
);
1814 comment
= lp_comment(ctx
, snum
);
1815 type
= STYPE_DISKTREE
;
1819 return WERR_ACCESS_DENIED
;
1821 pathname
= lp_path(ctx
, snum
);
1822 comment
= lp_comment(ctx
, snum
);
1823 psd
= info
->info1501
->sd
;
1824 map_generic_share_sd_bits(psd
);
1825 type
= STYPE_DISKTREE
;
1828 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1830 return WERR_UNKNOWN_LEVEL
;
1833 /* We can only modify disk shares. */
1834 if (type
!= STYPE_DISKTREE
) {
1835 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1838 return WERR_ACCESS_DENIED
;
1841 if (comment
== NULL
) {
1845 /* Check if the pathname is valid. */
1846 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1847 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1849 return WERR_OBJECT_PATH_INVALID
;
1852 /* Ensure share name, pathname and comment don't contain '"' characters. */
1853 string_replace(share_name
, '"', ' ');
1854 string_replace(path
, '"', ' ');
1855 string_replace(comment
, '"', ' ');
1857 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1858 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1860 /* Only call modify function if something changed. */
1862 if (strcmp(path
, lp_path(talloc_tos(), snum
)) || strcmp(comment
, lp_comment(talloc_tos(), snum
))
1863 || (lp_max_connections(snum
) != max_connections
)
1864 || csc_policy_changed
) {
1866 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1867 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1868 return WERR_ACCESS_DENIED
;
1871 command
= talloc_asprintf(p
->mem_ctx
,
1872 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1873 lp_change_share_command(talloc_tos()),
1874 get_dyn_CONFIGFILE(),
1877 comment
? comment
: "",
1884 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1886 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1891 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1892 /* Tell everyone we updated smb.conf. */
1893 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1900 /********* END SeDiskOperatorPrivilege BLOCK *********/
1902 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1905 TALLOC_FREE(command
);
1908 return WERR_ACCESS_DENIED
;
1910 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1914 /* Replace SD if changed. */
1916 struct security_descriptor
*old_sd
;
1919 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
1921 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1922 if (!set_share_security(share_name
, psd
))
1923 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1928 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1933 /*******************************************************************
1934 _srvsvc_NetShareAdd.
1935 Call 'add_share_command "sharename" "pathname"
1936 "comment" "max connections = "
1937 ********************************************************************/
1939 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1940 struct srvsvc_NetShareAdd
*r
)
1942 char *command
= NULL
;
1943 char *share_name_in
= NULL
;
1944 char *share_name
= NULL
;
1945 char *comment
= NULL
;
1946 char *pathname
= NULL
;
1951 struct security_descriptor
*psd
= NULL
;
1953 int max_connections
= 0;
1955 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1957 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1959 if (r
->out
.parm_error
) {
1960 *r
->out
.parm_error
= 0;
1963 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1965 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1966 return WERR_ACCESS_DENIED
;
1968 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1969 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1970 return WERR_ACCESS_DENIED
;
1973 switch (r
->in
.level
) {
1975 /* No path. Not enough info in a level 0 to do anything. */
1976 return WERR_ACCESS_DENIED
;
1978 /* Not enough info in a level 1 to do anything. */
1979 return WERR_ACCESS_DENIED
;
1981 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1982 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1983 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1984 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1985 0 : r
->in
.info
->info2
->max_users
;
1986 type
= r
->in
.info
->info2
->type
;
1989 /* No path. Not enough info in a level 501 to do anything. */
1990 return WERR_ACCESS_DENIED
;
1992 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1993 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1994 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1995 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1996 0 : r
->in
.info
->info502
->max_users
;
1997 type
= r
->in
.info
->info502
->type
;
1998 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1999 map_generic_share_sd_bits(psd
);
2002 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2008 return WERR_ACCESS_DENIED
;
2010 /* DFS only level. */
2011 return WERR_ACCESS_DENIED
;
2013 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2015 return WERR_UNKNOWN_LEVEL
;
2018 /* check for invalid share names */
2020 if (!share_name_in
|| !validate_net_name(share_name_in
,
2021 INVALID_SHARENAME_CHARS
,
2022 strlen(share_name_in
))) {
2023 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2024 share_name_in
? share_name_in
: ""));
2025 return WERR_INVALID_NAME
;
2028 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
2029 || (lp_enable_asu_support() &&
2030 strequal(share_name_in
,"ADMIN$"))) {
2031 return WERR_ACCESS_DENIED
;
2034 snum
= find_service(ctx
, share_name_in
, &share_name
);
2039 /* Share already exists. */
2041 return WERR_FILE_EXISTS
;
2044 /* We can only add disk shares. */
2045 if (type
!= STYPE_DISKTREE
) {
2046 return WERR_ACCESS_DENIED
;
2049 /* Check if the pathname is valid. */
2050 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
2051 return WERR_OBJECT_PATH_INVALID
;
2054 ret
= sys_lstat(path
, &st
, false);
2055 if (ret
== -1 && (errno
!= EACCES
)) {
2057 * If path has any other than permission
2058 * problem, return WERR_BADFILE (as Windows
2061 return WERR_BADFILE
;
2064 /* Ensure share name, pathname and comment don't contain '"' characters. */
2065 string_replace(share_name_in
, '"', ' ');
2066 string_replace(share_name
, '"', ' ');
2067 string_replace(path
, '"', ' ');
2069 string_replace(comment
, '"', ' ');
2072 command
= talloc_asprintf(ctx
,
2073 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2074 lp_add_share_command(talloc_tos()),
2075 get_dyn_CONFIGFILE(),
2078 comment
? comment
: "",
2084 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
2086 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2091 /* FIXME: use libnetconf here - gd */
2093 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2094 /* Tell everyone we updated smb.conf. */
2095 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2102 /********* END SeDiskOperatorPrivilege BLOCK *********/
2104 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2107 TALLOC_FREE(command
);
2110 return WERR_ACCESS_DENIED
;
2113 /* Note we use share_name here, not share_name_in as
2114 we need a canonicalized name for setting security. */
2115 if (!set_share_security(share_name
, psd
)) {
2116 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2122 * We don't call reload_services() here, the message will
2123 * cause this to be done before the next packet is read
2124 * from the client. JRA.
2127 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
2132 /*******************************************************************
2134 Call "delete share command" with the share name as
2136 ********************************************************************/
2138 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
2139 struct srvsvc_NetShareDel
*r
)
2141 char *command
= NULL
;
2142 char *share_name
= NULL
;
2146 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2148 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
2150 if (!r
->in
.share_name
) {
2151 return WERR_NET_NAME_NOT_FOUND
;
2154 if ( strequal(r
->in
.share_name
,"IPC$")
2155 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
2156 || strequal(r
->in
.share_name
,"global") )
2158 return WERR_ACCESS_DENIED
;
2161 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
2167 return WERR_NO_SUCH_SHARE
;
2170 /* No change to printer shares. */
2171 if (lp_printable(snum
))
2172 return WERR_ACCESS_DENIED
;
2174 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2176 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
2177 return WERR_ACCESS_DENIED
;
2179 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2180 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2181 return WERR_ACCESS_DENIED
;
2184 command
= talloc_asprintf(ctx
,
2186 lp_delete_share_command(talloc_tos()),
2187 get_dyn_CONFIGFILE(),
2193 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
2195 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2200 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2201 /* Tell everyone we updated smb.conf. */
2202 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2209 /********* END SeDiskOperatorPrivilege BLOCK *********/
2211 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2214 return WERR_ACCESS_DENIED
;
2216 /* Delete the SD in the database. */
2217 delete_share_security(share_name
);
2219 lp_killservice(snum
);
2224 /*******************************************************************
2225 _srvsvc_NetShareDelSticky
2226 ********************************************************************/
2228 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2229 struct srvsvc_NetShareDelSticky
*r
)
2231 struct srvsvc_NetShareDel q
;
2233 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2235 q
.in
.server_unc
= r
->in
.server_unc
;
2236 q
.in
.share_name
= r
->in
.share_name
;
2237 q
.in
.reserved
= r
->in
.reserved
;
2239 return _srvsvc_NetShareDel(p
, &q
);
2242 /*******************************************************************
2243 _srvsvc_NetRemoteTOD
2244 ********************************************************************/
2246 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2247 struct srvsvc_NetRemoteTOD
*r
)
2249 struct srvsvc_NetRemoteTODInfo
*tod
;
2251 time_t unixdate
= time(NULL
);
2253 /* We do this call first as if we do it *after* the gmtime call
2254 it overwrites the pointed-to values. JRA */
2256 uint32 zone
= get_time_zone(unixdate
)/60;
2258 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2260 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2265 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2267 t
= gmtime(&unixdate
);
2270 tod
->elapsed
= unixdate
;
2272 tod
->hours
= t
->tm_hour
;
2273 tod
->mins
= t
->tm_min
;
2274 tod
->secs
= t
->tm_sec
;
2276 tod
->timezone
= zone
;
2277 tod
->tinterval
= 10000;
2278 tod
->day
= t
->tm_mday
;
2279 tod
->month
= t
->tm_mon
+ 1;
2280 tod
->year
= 1900+t
->tm_year
;
2281 tod
->weekday
= t
->tm_wday
;
2283 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2288 /***********************************************************************************
2289 _srvsvc_NetGetFileSecurity
2290 Win9x NT tools get security descriptor.
2291 ***********************************************************************************/
2293 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2294 struct srvsvc_NetGetFileSecurity
*r
)
2296 struct smb_filename
*smb_fname
= NULL
;
2298 char *servicename
= NULL
;
2302 connection_struct
*conn
= NULL
;
2303 struct sec_desc_buf
*sd_buf
= NULL
;
2304 files_struct
*fsp
= NULL
;
2306 char *oldcwd
= NULL
;
2311 werr
= WERR_NET_NAME_NOT_FOUND
;
2314 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2320 DEBUG(10, ("Could not find service %s\n", servicename
));
2321 werr
= WERR_NET_NAME_NOT_FOUND
;
2325 nt_status
= create_conn_struct_cwd(talloc_tos(),
2326 server_event_context(),
2327 server_messaging_context(),
2329 snum
, lp_path(talloc_tos(), snum
),
2330 p
->session_info
, &oldcwd
);
2331 if (!NT_STATUS_IS_OK(nt_status
)) {
2332 DEBUG(10, ("create_conn_struct failed: %s\n",
2333 nt_errstr(nt_status
)));
2334 werr
= ntstatus_to_werror(nt_status
);
2338 nt_status
= filename_convert(talloc_tos(),
2345 if (!NT_STATUS_IS_OK(nt_status
)) {
2346 werr
= ntstatus_to_werror(nt_status
);
2350 nt_status
= SMB_VFS_CREATE_FILE(
2353 0, /* root_dir_fid */
2354 smb_fname
, /* fname */
2355 FILE_READ_ATTRIBUTES
, /* access_mask */
2356 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2357 FILE_OPEN
, /* create_disposition*/
2358 0, /* create_options */
2359 0, /* file_attributes */
2360 INTERNAL_OPEN_ONLY
, /* oplock_request */
2362 0, /* allocation_size */
2363 0, /* private_flags */
2368 NULL
, NULL
); /* create context */
2370 if (!NT_STATUS_IS_OK(nt_status
)) {
2371 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2372 smb_fname_str_dbg(smb_fname
)));
2373 werr
= ntstatus_to_werror(nt_status
);
2377 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2383 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2386 |SECINFO_DACL
), sd_buf
, &sd_buf
->sd
);
2388 if (!NT_STATUS_IS_OK(nt_status
)) {
2389 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2390 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2391 werr
= ntstatus_to_werror(nt_status
);
2392 TALLOC_FREE(sd_buf
);
2396 if (sd_buf
->sd
->dacl
) {
2397 sd_buf
->sd
->dacl
->revision
= NT4_ACL_REVISION
;
2400 sd_size
= ndr_size_security_descriptor(sd_buf
->sd
, 0);
2402 sd_buf
->sd_size
= sd_size
;
2404 *r
->out
.sd_buf
= sd_buf
;
2406 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2407 vfs_ChDir(conn
, oldcwd
);
2408 SMB_VFS_DISCONNECT(conn
);
2416 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2420 vfs_ChDir(conn
, oldcwd
);
2424 SMB_VFS_DISCONNECT(conn
);
2430 TALLOC_FREE(smb_fname
);
2435 /***********************************************************************************
2436 _srvsvc_NetSetFileSecurity
2437 Win9x NT tools set security descriptor.
2438 ***********************************************************************************/
2440 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2441 struct srvsvc_NetSetFileSecurity
*r
)
2443 struct smb_filename
*smb_fname
= NULL
;
2444 char *servicename
= NULL
;
2445 files_struct
*fsp
= NULL
;
2449 connection_struct
*conn
= NULL
;
2451 char *oldcwd
= NULL
;
2452 struct security_descriptor
*psd
= NULL
;
2453 uint32_t security_info_sent
= 0;
2458 werr
= WERR_NET_NAME_NOT_FOUND
;
2462 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2469 DEBUG(10, ("Could not find service %s\n", servicename
));
2470 werr
= WERR_NET_NAME_NOT_FOUND
;
2474 nt_status
= create_conn_struct_cwd(talloc_tos(),
2475 server_event_context(),
2476 server_messaging_context(),
2478 snum
, lp_path(talloc_tos(), snum
),
2479 p
->session_info
, &oldcwd
);
2480 if (!NT_STATUS_IS_OK(nt_status
)) {
2481 DEBUG(10, ("create_conn_struct failed: %s\n",
2482 nt_errstr(nt_status
)));
2483 werr
= ntstatus_to_werror(nt_status
);
2487 nt_status
= filename_convert(talloc_tos(),
2494 if (!NT_STATUS_IS_OK(nt_status
)) {
2495 werr
= ntstatus_to_werror(nt_status
);
2499 nt_status
= SMB_VFS_CREATE_FILE(
2502 0, /* root_dir_fid */
2503 smb_fname
, /* fname */
2504 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2505 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2506 FILE_OPEN
, /* create_disposition*/
2507 0, /* create_options */
2508 0, /* file_attributes */
2509 INTERNAL_OPEN_ONLY
, /* oplock_request */
2511 0, /* allocation_size */
2512 0, /* private_flags */
2517 NULL
, NULL
); /* create context */
2519 if (!NT_STATUS_IS_OK(nt_status
)) {
2520 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2521 smb_fname_str_dbg(smb_fname
)));
2522 werr
= ntstatus_to_werror(nt_status
);
2526 psd
= r
->in
.sd_buf
->sd
;
2527 security_info_sent
= r
->in
.securityinformation
;
2529 nt_status
= set_sd(fsp
, psd
, security_info_sent
);
2531 if (!NT_STATUS_IS_OK(nt_status
) ) {
2532 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2533 "on file %s\n", r
->in
.share
));
2534 werr
= WERR_ACCESS_DENIED
;
2538 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2539 vfs_ChDir(conn
, oldcwd
);
2540 SMB_VFS_DISCONNECT(conn
);
2548 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2552 vfs_ChDir(conn
, oldcwd
);
2556 SMB_VFS_DISCONNECT(conn
);
2561 TALLOC_FREE(smb_fname
);
2566 /***********************************************************************************
2567 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2568 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2569 These disks would the disks listed by this function.
2570 Users could then create shares relative to these disks. Watch out for moving these disks around.
2571 "Nigel Williams" <nigel@veritas.com>.
2572 ***********************************************************************************/
2574 static const char *server_disks
[] = {"C:"};
2576 static uint32
get_server_disk_count(void)
2578 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2581 static uint32
init_server_disk_enum(uint32
*resume
)
2583 uint32 server_disk_count
= get_server_disk_count();
2585 /*resume can be an offset into the list for now*/
2587 if(*resume
& 0x80000000)
2590 if(*resume
> server_disk_count
)
2591 *resume
= server_disk_count
;
2593 return server_disk_count
- *resume
;
2596 static const char *next_server_disk_enum(uint32
*resume
)
2600 if(init_server_disk_enum(resume
) == 0)
2603 disk
= server_disks
[*resume
];
2607 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2612 /********************************************************************
2614 ********************************************************************/
2616 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2617 struct srvsvc_NetDiskEnum
*r
)
2620 const char *disk_name
;
2621 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2623 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2627 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2629 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2630 MAX_SERVER_DISK_ENTRIES
);
2631 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2633 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2635 r
->out
.info
->count
= 0;
2637 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2639 r
->out
.info
->count
++;
2641 /*copy disk name into a unicode string*/
2643 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2644 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2647 /* add a terminating null string. Is this there if there is more data to come? */
2649 r
->out
.info
->count
++;
2651 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2652 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2654 if (r
->out
.resume_handle
) {
2655 *r
->out
.resume_handle
= resume
;
2661 /********************************************************************
2662 _srvsvc_NetNameValidate
2663 ********************************************************************/
2665 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2666 struct srvsvc_NetNameValidate
*r
)
2668 switch (r
->in
.name_type
) {
2670 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2671 strlen_m(r
->in
.name
)))
2673 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2675 return WERR_INVALID_NAME
;
2680 return WERR_UNKNOWN_LEVEL
;
2686 /*******************************************************************
2687 ********************************************************************/
2689 struct enum_file_close_state
{
2690 struct srvsvc_NetFileClose
*r
;
2691 struct messaging_context
*msg_ctx
;
2694 static int enum_file_close_fn(const struct share_mode_entry
*e
,
2695 const char *sharepath
, const char *fname
,
2698 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2699 struct enum_file_close_state
*state
=
2700 (struct enum_file_close_state
*)private_data
;
2701 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2703 if (fid
!= state
->r
->in
.fid
) {
2704 return 0; /* Not this file. */
2707 if (!process_exists(e
->pid
) ) {
2711 /* Ok - send the close message. */
2712 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2714 share_mode_str(talloc_tos(), 0, e
) ));
2716 share_mode_entry_to_message(msg
, e
);
2718 state
->r
->out
.result
= ntstatus_to_werror(
2719 messaging_send_buf(state
->msg_ctx
,
2720 e
->pid
, MSG_SMB_CLOSE_FILE
,
2721 (uint8
*)msg
, sizeof(msg
)));
2726 /********************************************************************
2727 Close a file given a 32-bit file id.
2728 ********************************************************************/
2730 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2731 struct srvsvc_NetFileClose
*r
)
2733 struct enum_file_close_state state
;
2736 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2738 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2740 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2741 return WERR_ACCESS_DENIED
;
2744 /* enum_file_close_fn sends the close message to
2745 * the relevant smbd process. */
2747 r
->out
.result
= WERR_BADFILE
;
2749 state
.msg_ctx
= p
->msg_ctx
;
2750 share_entry_forall(enum_file_close_fn
, &state
);
2751 return r
->out
.result
;
2754 /********************************************************************
2755 ********************************************************************/
2757 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2758 struct srvsvc_NetCharDevEnum
*r
)
2760 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2761 return WERR_NOT_SUPPORTED
;
2764 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2765 struct srvsvc_NetCharDevGetInfo
*r
)
2767 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2768 return WERR_NOT_SUPPORTED
;
2771 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2772 struct srvsvc_NetCharDevControl
*r
)
2774 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2775 return WERR_NOT_SUPPORTED
;
2778 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2779 struct srvsvc_NetCharDevQEnum
*r
)
2781 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2782 return WERR_NOT_SUPPORTED
;
2785 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2786 struct srvsvc_NetCharDevQGetInfo
*r
)
2788 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2789 return WERR_NOT_SUPPORTED
;
2792 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2793 struct srvsvc_NetCharDevQSetInfo
*r
)
2795 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2796 return WERR_NOT_SUPPORTED
;
2799 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2800 struct srvsvc_NetCharDevQPurge
*r
)
2802 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2803 return WERR_NOT_SUPPORTED
;
2806 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2807 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2809 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2810 return WERR_NOT_SUPPORTED
;
2813 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2814 struct srvsvc_NetFileGetInfo
*r
)
2816 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2817 return WERR_NOT_SUPPORTED
;
2820 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2821 struct srvsvc_NetShareCheck
*r
)
2823 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2824 return WERR_NOT_SUPPORTED
;
2827 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2828 struct srvsvc_NetServerStatisticsGet
*r
)
2830 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2831 return WERR_NOT_SUPPORTED
;
2834 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2835 struct srvsvc_NetTransportAdd
*r
)
2837 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2838 return WERR_NOT_SUPPORTED
;
2841 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2842 struct srvsvc_NetTransportEnum
*r
)
2844 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2845 return WERR_NOT_SUPPORTED
;
2848 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2849 struct srvsvc_NetTransportDel
*r
)
2851 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2852 return WERR_NOT_SUPPORTED
;
2855 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2856 struct srvsvc_NetSetServiceBits
*r
)
2858 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2859 return WERR_NOT_SUPPORTED
;
2862 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2863 struct srvsvc_NetPathType
*r
)
2865 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2866 return WERR_NOT_SUPPORTED
;
2869 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2870 struct srvsvc_NetPathCanonicalize
*r
)
2872 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2873 return WERR_NOT_SUPPORTED
;
2876 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2877 struct srvsvc_NetPathCompare
*r
)
2879 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2880 return WERR_NOT_SUPPORTED
;
2883 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2884 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2886 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2887 return WERR_NOT_SUPPORTED
;
2890 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2891 struct srvsvc_NetPRNameCompare
*r
)
2893 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2894 return WERR_NOT_SUPPORTED
;
2897 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2898 struct srvsvc_NetShareDelStart
*r
)
2900 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2901 return WERR_NOT_SUPPORTED
;
2904 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2905 struct srvsvc_NetShareDelCommit
*r
)
2907 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2908 return WERR_NOT_SUPPORTED
;
2911 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2912 struct srvsvc_NetServerTransportAddEx
*r
)
2914 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2915 return WERR_NOT_SUPPORTED
;
2918 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2919 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2921 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2922 return WERR_NOT_SUPPORTED
;
2925 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2926 struct srvsvc_NETRDFSGETVERSION
*r
)
2928 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2929 return WERR_NOT_SUPPORTED
;
2932 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2933 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2935 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2936 return WERR_NOT_SUPPORTED
;
2939 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2940 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2942 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2943 return WERR_NOT_SUPPORTED
;
2946 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2947 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2949 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2950 return WERR_NOT_SUPPORTED
;
2953 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2954 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2956 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2957 return WERR_NOT_SUPPORTED
;
2960 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2961 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2963 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2964 return WERR_NOT_SUPPORTED
;
2967 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2968 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2970 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2971 return WERR_NOT_SUPPORTED
;
2974 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2975 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2977 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2978 return WERR_NOT_SUPPORTED
;
2981 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2982 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2984 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2985 return WERR_NOT_SUPPORTED
;
2988 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2989 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2991 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2992 return WERR_NOT_SUPPORTED
;
2995 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2996 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2998 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2999 return WERR_NOT_SUPPORTED
;