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 void 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
++;
155 /*******************************************************************
156 ********************************************************************/
158 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
159 const char *username
,
160 struct srvsvc_NetFileCtr3
**ctr3
,
163 struct file_enum_count f_enum_cnt
;
165 f_enum_cnt
.ctx
= ctx
;
166 f_enum_cnt
.username
= username
;
167 f_enum_cnt
.ctr3
= *ctr3
;
169 share_mode_forall( enum_file_fn
, (void *)&f_enum_cnt
);
171 *ctr3
= f_enum_cnt
.ctr3
;
176 /*******************************************************************
177 Utility function to get the 'type' of a share from an snum.
178 ********************************************************************/
179 static enum srvsvc_ShareType
get_share_type(int snum
)
181 /* work out the share type */
182 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
184 if (lp_printable(snum
)) {
185 type
= lp_administrative_share(snum
)
186 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
188 if (strequal(lp_fstype(snum
), "IPC")) {
189 type
= lp_administrative_share(snum
)
190 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
195 /*******************************************************************
196 Fill in a share info level 0 structure.
197 ********************************************************************/
199 static void init_srv_share_info_0(struct pipes_struct
*p
,
200 struct srvsvc_NetShareInfo0
*r
, int snum
)
202 r
->name
= lp_servicename(talloc_tos(), snum
);
205 /*******************************************************************
206 Fill in a share info level 1 structure.
207 ********************************************************************/
209 static void init_srv_share_info_1(struct pipes_struct
*p
,
210 struct srvsvc_NetShareInfo1
*r
,
213 char *net_name
= lp_servicename(talloc_tos(), snum
);
214 char *remark
= lp_comment(p
->mem_ctx
, snum
);
217 remark
= talloc_sub_advanced(
218 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
219 get_current_username(), lp_path(talloc_tos(), snum
),
220 p
->session_info
->unix_token
->uid
, get_current_username(),
225 r
->type
= get_share_type(snum
);
226 r
->comment
= remark
? remark
: "";
229 /*******************************************************************
230 Fill in a share info level 2 structure.
231 ********************************************************************/
233 static void init_srv_share_info_2(struct pipes_struct
*p
,
234 struct srvsvc_NetShareInfo2
*r
,
239 int max_connections
= lp_max_connections(snum
);
240 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
241 char *net_name
= lp_servicename(talloc_tos(), snum
);
243 remark
= lp_comment(p
->mem_ctx
, snum
);
245 remark
= talloc_sub_advanced(
246 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
247 get_current_username(), lp_path(talloc_tos(), snum
),
248 p
->session_info
->unix_token
->uid
, get_current_username(),
251 path
= talloc_asprintf(p
->mem_ctx
,
252 "C:%s", lp_path(talloc_tos(), snum
));
256 * Change / to \\ so that win2k will see it as a valid path.
257 * This was added to enable use of browsing in win2k add
261 string_replace(path
, '/', '\\');
265 r
->type
= get_share_type(snum
);
266 r
->comment
= remark
? remark
: "";
268 r
->max_users
= max_uses
;
269 r
->current_users
= 0; /* computed later */
270 r
->path
= path
? path
: "";
274 /*******************************************************************
275 Map any generic bits to file specific bits.
276 ********************************************************************/
278 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
281 struct security_acl
*ps_dacl
= NULL
;
290 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
291 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
292 uint32 orig_mask
= psa
->access_mask
;
294 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
295 psa
->access_mask
|= orig_mask
;
299 /*******************************************************************
300 Fill in a share info level 501 structure.
301 ********************************************************************/
303 static void init_srv_share_info_501(struct pipes_struct
*p
,
304 struct srvsvc_NetShareInfo501
*r
, int snum
)
306 const char *net_name
= lp_servicename(talloc_tos(), snum
);
307 char *remark
= lp_comment(p
->mem_ctx
, snum
);
310 remark
= talloc_sub_advanced(
311 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
312 get_current_username(), lp_path(talloc_tos(), snum
),
313 p
->session_info
->unix_token
->uid
, get_current_username(),
318 r
->type
= get_share_type(snum
);
319 r
->comment
= remark
? remark
: "";
322 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
325 r
->csc_policy
= (lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
);
328 /*******************************************************************
329 Fill in a share info level 502 structure.
330 ********************************************************************/
332 static void init_srv_share_info_502(struct pipes_struct
*p
,
333 struct srvsvc_NetShareInfo502
*r
, int snum
)
335 const char *net_name
= lp_servicename(talloc_tos(), snum
);
337 struct security_descriptor
*sd
= NULL
;
338 struct sec_desc_buf
*sd_buf
= NULL
;
340 TALLOC_CTX
*ctx
= p
->mem_ctx
;
341 char *remark
= lp_comment(ctx
, snum
);
344 remark
= talloc_sub_advanced(
345 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
346 get_current_username(), lp_path(talloc_tos(), snum
),
347 p
->session_info
->unix_token
->uid
, get_current_username(),
350 path
= talloc_asprintf(ctx
, "C:%s", lp_path(talloc_tos(), snum
));
353 * Change / to \\ so that win2k will see it as a valid path. This was added to
354 * enable use of browsing in win2k add share dialog.
356 string_replace(path
, '/', '\\');
359 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
361 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
364 r
->type
= get_share_type(snum
);
365 r
->comment
= remark
? remark
: "";
367 r
->max_users
= (uint32_t)-1;
368 r
->current_users
= 1; /* ??? */
369 r
->path
= path
? path
: "";
374 /***************************************************************************
375 Fill in a share info level 1004 structure.
376 ***************************************************************************/
378 static void init_srv_share_info_1004(struct pipes_struct
*p
,
379 struct srvsvc_NetShareInfo1004
*r
,
382 char *remark
= lp_comment(p
->mem_ctx
, snum
);
385 remark
= talloc_sub_advanced(
386 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
387 get_current_username(), lp_path(talloc_tos(), snum
),
388 p
->session_info
->unix_token
->uid
, get_current_username(),
392 r
->comment
= remark
? remark
: "";
395 /***************************************************************************
396 Fill in a share info level 1005 structure.
397 ***************************************************************************/
399 static void init_srv_share_info_1005(struct pipes_struct
*p
,
400 struct srvsvc_NetShareInfo1005
*r
,
403 uint32_t dfs_flags
= 0;
405 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
406 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
409 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
411 r
->dfs_flags
= dfs_flags
;
414 /***************************************************************************
415 Fill in a share info level 1006 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1006(struct pipes_struct
*p
,
419 struct srvsvc_NetShareInfo1006
*r
,
422 r
->max_users
= (uint32_t)-1;
425 /***************************************************************************
426 Fill in a share info level 1007 structure.
427 ***************************************************************************/
429 static void init_srv_share_info_1007(struct pipes_struct
*p
,
430 struct srvsvc_NetShareInfo1007
*r
,
434 r
->alternate_directory_name
= "";
437 /*******************************************************************
438 Fill in a share info level 1501 structure.
439 ********************************************************************/
441 static void init_srv_share_info_1501(struct pipes_struct
*p
,
442 struct sec_desc_buf
**r
,
445 struct security_descriptor
*sd
;
446 struct sec_desc_buf
*sd_buf
= NULL
;
448 TALLOC_CTX
*ctx
= p
->mem_ctx
;
450 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
452 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
458 /*******************************************************************
459 True if it ends in '$'.
460 ********************************************************************/
462 static bool is_hidden_share(int snum
)
464 const char *net_name
= lp_servicename(talloc_tos(), snum
);
466 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
469 /*******************************************************************
470 Verify user is allowed to view share, access based enumeration
471 ********************************************************************/
472 static bool is_enumeration_allowed(struct pipes_struct
*p
,
475 if (!lp_access_based_share_enum(snum
))
478 return share_access_check(p
->session_info
->security_token
,
479 lp_servicename(talloc_tos(), snum
),
480 FILE_READ_DATA
, NULL
);
483 /****************************************************************************
484 Count an entry against the respective service.
485 ****************************************************************************/
487 static int count_for_all_fn(struct smbXsrv_tcon_global0
*tcon
, void *udp
)
489 union srvsvc_NetShareCtr
*ctr
= NULL
;
490 struct srvsvc_NetShareInfo2
*info2
= NULL
;
491 int share_entries
= 0;
494 ctr
= (union srvsvc_NetShareCtr
*) udp
;
497 share_entries
= ctr
->ctr2
->count
;
498 info2
= &ctr
->ctr2
->array
[0];
500 for (i
= 0; i
< share_entries
; i
++, info2
++) {
501 if (strequal(tcon
->share_name
, info2
->name
)) {
502 info2
->current_users
++;
510 /****************************************************************************
511 Count the entries belonging to all services in the connection db.
512 ****************************************************************************/
514 static void count_connections_for_all_shares(union srvsvc_NetShareCtr
*ctr
)
517 status
= smbXsrv_tcon_global_traverse(count_for_all_fn
, ctr
);
519 if (!NT_STATUS_IS_OK(status
)) {
520 DEBUG(0,("count_connections_for_all_shares: traverse of "
521 "smbXsrv_tcon_global.tdb failed - %s\n",
526 /*******************************************************************
527 Fill in a share info structure.
528 ********************************************************************/
530 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
531 struct srvsvc_NetShareInfoCtr
*info_ctr
,
532 uint32_t *resume_handle_p
,
533 uint32_t *total_entries
,
537 int alloc_entries
= 0;
538 int num_services
= 0;
540 TALLOC_CTX
*ctx
= p
->mem_ctx
;
542 int valid_share_count
= 0;
544 union srvsvc_NetShareCtr ctr
;
545 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
547 DEBUG(5,("init_srv_share_info_ctr\n"));
549 /* Ensure all the usershares are loaded. */
551 load_usershare_shares(NULL
, connections_snum_used
);
552 load_registry_shares();
553 num_services
= lp_numservices();
556 allowed
= talloc_zero_array(ctx
, bool, num_services
);
557 W_ERROR_HAVE_NO_MEMORY(allowed
);
559 /* Count the number of entries. */
560 for (snum
= 0; snum
< num_services
; snum
++) {
561 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
562 is_enumeration_allowed(p
, snum
) &&
563 (all_shares
|| !is_hidden_share(snum
)) ) {
564 DEBUG(10, ("counting service %s\n",
565 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
566 allowed
[snum
] = true;
569 DEBUG(10, ("NOT counting service %s\n",
570 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
574 if (!num_entries
|| (resume_handle
>= num_entries
)) {
578 /* Calculate alloc entries. */
579 alloc_entries
= num_entries
- resume_handle
;
580 switch (info_ctr
->level
) {
582 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
583 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
585 ctr
.ctr0
->count
= alloc_entries
;
586 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
587 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
589 for (snum
= 0; snum
< num_services
; snum
++) {
591 (resume_handle
<= (i
+ valid_share_count
++)) ) {
592 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
599 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
600 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
602 ctr
.ctr1
->count
= alloc_entries
;
603 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
604 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
606 for (snum
= 0; snum
< num_services
; snum
++) {
608 (resume_handle
<= (i
+ valid_share_count
++)) ) {
609 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
616 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
617 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
619 ctr
.ctr2
->count
= alloc_entries
;
620 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
621 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
623 for (snum
= 0; snum
< num_services
; snum
++) {
625 (resume_handle
<= (i
+ valid_share_count
++)) ) {
626 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
630 count_connections_for_all_shares(&ctr
);
634 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
635 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
637 ctr
.ctr501
->count
= alloc_entries
;
638 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
639 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
641 for (snum
= 0; snum
< num_services
; snum
++) {
643 (resume_handle
<= (i
+ valid_share_count
++)) ) {
644 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
651 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
652 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
654 ctr
.ctr502
->count
= alloc_entries
;
655 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
656 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
658 for (snum
= 0; snum
< num_services
; snum
++) {
660 (resume_handle
<= (i
+ valid_share_count
++)) ) {
661 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
668 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
669 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
671 ctr
.ctr1004
->count
= alloc_entries
;
672 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
673 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
675 for (snum
= 0; snum
< num_services
; snum
++) {
677 (resume_handle
<= (i
+ valid_share_count
++)) ) {
678 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
685 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
686 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
688 ctr
.ctr1005
->count
= alloc_entries
;
689 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
690 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
692 for (snum
= 0; snum
< num_services
; snum
++) {
694 (resume_handle
<= (i
+ valid_share_count
++)) ) {
695 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
702 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
703 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
705 ctr
.ctr1006
->count
= alloc_entries
;
706 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
707 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
709 for (snum
= 0; snum
< num_services
; snum
++) {
711 (resume_handle
<= (i
+ valid_share_count
++)) ) {
712 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
719 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
720 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
722 ctr
.ctr1007
->count
= alloc_entries
;
723 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
724 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
726 for (snum
= 0; snum
< num_services
; snum
++) {
728 (resume_handle
<= (i
+ valid_share_count
++)) ) {
729 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
736 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
737 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
739 ctr
.ctr1501
->count
= alloc_entries
;
740 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
741 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
743 for (snum
= 0; snum
< num_services
; snum
++) {
745 (resume_handle
<= (i
+ valid_share_count
++)) ) {
746 struct sec_desc_buf
*sd_buf
= NULL
;
747 init_srv_share_info_1501(p
, &sd_buf
, snum
);
748 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
755 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
757 return WERR_UNKNOWN_LEVEL
;
760 *total_entries
= alloc_entries
;
761 if (resume_handle_p
) {
763 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
765 *resume_handle_p
= num_entries
;
774 /*******************************************************************
775 fill in a sess info level 0 structure.
776 ********************************************************************/
778 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
779 struct srvsvc_NetSessCtr0
*ctr0
,
780 uint32_t *resume_handle_p
,
781 uint32_t *total_entries
)
783 struct sessionid
*session_list
;
784 uint32_t num_entries
= 0;
785 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
786 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
788 DEBUG(5,("init_srv_sess_info_0\n"));
791 if (resume_handle_p
) {
792 *resume_handle_p
= 0;
797 for (; resume_handle
< *total_entries
; resume_handle
++) {
799 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
801 struct srvsvc_NetSessInfo0
,
803 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
805 ctr0
->array
[num_entries
].client
=
806 session_list
[resume_handle
].remote_machine
;
811 ctr0
->count
= num_entries
;
813 if (resume_handle_p
) {
814 if (*resume_handle_p
>= *total_entries
) {
815 *resume_handle_p
= 0;
817 *resume_handle_p
= resume_handle
;
824 /***********************************************************************
825 * find out the session on which this file is open and bump up its count
826 **********************************************************************/
828 static void count_sess_files_fn(const struct share_mode_entry
*e
,
829 const char *sharepath
, const char *fname
,
832 struct sess_file_info
*info
= data
;
833 uint32_t rh
= info
->resume_handle
;
836 for (i
=0; i
< info
->num_entries
; i
++) {
837 /* rh+info->num_entries is safe, as we've
839 *total_entries > resume_handle &&
840 info->num_entries = *total_entries - resume_handle;
841 inside init_srv_sess_info_1() below.
843 struct sessionid
*sess
= &info
->session_list
[rh
+ i
];
844 if ((e
->uid
== sess
->uid
) &&
845 serverid_equal(&e
->pid
, &sess
->pid
)) {
847 info
->ctr
->array
[i
].num_open
++;
853 /*******************************************************************
854 * count the num of open files on all sessions
855 *******************************************************************/
857 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1
*ctr1
,
858 struct sessionid
*session_list
,
859 uint32_t resume_handle
,
860 uint32_t num_entries
)
862 struct sess_file_info s_file_info
;
864 s_file_info
.ctr
= ctr1
;
865 s_file_info
.session_list
= session_list
;
866 s_file_info
.resume_handle
= resume_handle
;
867 s_file_info
.num_entries
= num_entries
;
869 share_mode_forall(count_sess_files_fn
, &s_file_info
);
872 /*******************************************************************
873 fill in a sess info level 1 structure.
874 ********************************************************************/
876 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
877 struct srvsvc_NetSessCtr1
*ctr1
,
878 uint32_t *resume_handle_p
,
879 uint32_t *total_entries
)
881 struct sessionid
*session_list
;
882 uint32_t num_entries
= 0;
883 time_t now
= time(NULL
);
884 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
889 if (resume_handle_p
) {
890 *resume_handle_p
= 0;
895 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
897 if (resume_handle
>= *total_entries
) {
898 if (resume_handle_p
) {
899 *resume_handle_p
= 0;
904 /* We know num_entries must be positive, due to
905 the check resume_handle >= *total_entries above. */
907 num_entries
= *total_entries
- resume_handle
;
909 ctr1
->array
= talloc_zero_array(p
->mem_ctx
,
910 struct srvsvc_NetSessInfo1
,
913 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
915 for (num_entries
= 0; resume_handle
< *total_entries
; num_entries
++, resume_handle
++) {
919 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
920 guest
= strequal( session_list
[resume_handle
].username
, lp_guest_account() );
922 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
923 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
924 ctr1
->array
[num_entries
].num_open
= 0;/* computed later */
925 ctr1
->array
[num_entries
].time
= connect_time
;
926 ctr1
->array
[num_entries
].idle_time
= 0;
927 ctr1
->array
[num_entries
].user_flags
= guest
;
930 ctr1
->count
= num_entries
;
932 /* count open files on all sessions in single tdb traversal */
933 net_count_files_for_all_sess(ctr1
, session_list
,
934 resume_handle_p
? *resume_handle_p
: 0,
937 if (resume_handle_p
) {
938 if (*resume_handle_p
>= *total_entries
) {
939 *resume_handle_p
= 0;
941 *resume_handle_p
= resume_handle
;
948 /*******************************************************************
949 find the share connection on which this open exists.
950 ********************************************************************/
952 static void share_file_fn(const struct share_mode_entry
*e
,
953 const char *sharepath
, const char *fname
,
956 struct share_file_stat
*sfs
= data
;
958 uint32_t offset
= sfs
->total_entries
- sfs
->resp_entries
;
960 if (strequal(sharepath
, sfs
->in_sharepath
)) {
961 for (i
=0; i
< sfs
->resp_entries
; i
++) {
962 if (serverid_equal(&e
->pid
, &sfs
->svrid_arr
[offset
+ i
])) {
963 sfs
->netconn_arr
[i
].num_open
++;
970 /*******************************************************************
971 count number of open files on given share connections.
972 ********************************************************************/
974 static void count_share_opens(struct srvsvc_NetConnInfo1
*arr
,
975 struct server_id
*svrid_arr
, char *sharepath
,
976 uint32_t resp_entries
, uint32_t total_entries
)
978 struct share_file_stat sfs
;
980 sfs
.netconn_arr
= arr
;
981 sfs
.svrid_arr
= svrid_arr
;
982 sfs
.in_sharepath
= sharepath
;
983 sfs
.resp_entries
= resp_entries
;
984 sfs
.total_entries
= total_entries
;
986 share_mode_forall(share_file_fn
, &sfs
);
989 /****************************************************************************
990 process an entry from the connection db.
991 ****************************************************************************/
993 static int share_conn_fn(struct smbXsrv_tcon_global0
*tcon
,
996 struct share_conn_stat
*scs
= data
;
998 if (!process_exists(tcon
->server_id
)) {
1002 if (strequal(tcon
->share_name
, scs
->sharename
)) {
1003 scs
->svrid_arr
= talloc_realloc(scs
->ctx
, scs
->svrid_arr
,
1006 if (!scs
->svrid_arr
) {
1010 scs
->svrid_arr
[scs
->count
] = tcon
->server_id
;
1017 /****************************************************************************
1018 Count the connections to a share. Build an array of serverid's owning these
1020 ****************************************************************************/
1022 static uint32_t count_share_conns(TALLOC_CTX
*ctx
, const char *sharename
,
1023 struct server_id
**arr
)
1025 struct share_conn_stat scs
;
1029 scs
.sharename
= sharename
;
1030 scs
.svrid_arr
= NULL
;
1033 status
= smbXsrv_tcon_global_traverse(share_conn_fn
, &scs
);
1035 if (!NT_STATUS_IS_OK(status
)) {
1036 DEBUG(0,("count_share_conns: traverse of "
1037 "smbXsrv_tcon_global.tdb failed - %s\n",
1038 nt_errstr(status
)));
1042 *arr
= scs
.svrid_arr
;
1046 /*******************************************************************
1047 fill in a conn info level 0 structure.
1048 ********************************************************************/
1050 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
1051 uint32_t *resume_handle_p
,
1052 uint32_t *total_entries
)
1054 uint32_t num_entries
= 0;
1055 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1057 DEBUG(5,("init_srv_conn_info_0\n"));
1060 if (resume_handle_p
) {
1061 *resume_handle_p
= 0;
1070 for (; resume_handle
< *total_entries
; resume_handle
++) {
1072 ctr0
->array
= talloc_realloc(talloc_tos(),
1074 struct srvsvc_NetConnInfo0
,
1080 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
1082 /* move on to creating next connection */
1086 ctr0
->count
= num_entries
;
1087 *total_entries
= num_entries
;
1089 if (resume_handle_p
) {
1090 if (*resume_handle_p
>= *total_entries
) {
1091 *resume_handle_p
= 0;
1093 *resume_handle_p
= resume_handle
;
1100 /*******************************************************************
1101 fill in a conn info level 1 structure.
1102 ********************************************************************/
1104 static WERROR
init_srv_conn_info_1(const char *name
,
1105 struct srvsvc_NetConnCtr1
*ctr1
,
1106 uint32_t *resume_handle_p
,
1107 uint32_t *total_entries
)
1109 uint32_t num_entries
= 0, snum
= 0;
1110 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1111 char *share_name
= NULL
;
1112 struct server_id
*svrid_arr
= NULL
;
1114 DEBUG(5,("init_srv_conn_info_1\n"));
1117 if (resume_handle_p
) {
1118 *resume_handle_p
= 0;
1123 /* check if this is a server name or a share name */
1124 if (name
&& (strlen(name
) > 2) && (name
[0] == '\\') &&
1125 (name
[1] == '\\')) {
1127 /* 'name' is a server name - this part is unimplemented */
1130 /* 'name' is a share name */
1131 snum
= find_service(talloc_tos(), name
, &share_name
);
1138 return WERR_INVALID_NAME
;
1142 * count the num of connections to this share. Also,
1143 * build a list of serverid's that own these
1144 * connections. The serverid list is used later to
1145 * identify the share connection on which an open exists.
1148 *total_entries
= count_share_conns(talloc_tos(),
1153 if (resume_handle
>= *total_entries
) {
1154 if (resume_handle_p
) {
1155 *resume_handle_p
= 0;
1163 for (; resume_handle
< *total_entries
; resume_handle
++) {
1165 ctr1
->array
= talloc_realloc(talloc_tos(),
1167 struct srvsvc_NetConnInfo1
,
1173 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1174 ctr1
->array
[num_entries
].conn_type
= 0x3;
1175 ctr1
->array
[num_entries
].num_open
= 1;
1176 ctr1
->array
[num_entries
].num_users
= 1;
1177 ctr1
->array
[num_entries
].conn_time
= 3;
1178 ctr1
->array
[num_entries
].user
= "dummy_user";
1179 ctr1
->array
[num_entries
].share
= "IPC$";
1181 /* move on to creating next connection */
1185 ctr1
->count
= num_entries
;
1186 *total_entries
= num_entries
;
1188 if (resume_handle_p
) {
1189 *resume_handle_p
= resume_handle
;
1195 /*******************************************************************
1197 *******************************************************************/
1199 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1200 struct srvsvc_NetFileEnum
*r
)
1202 TALLOC_CTX
*ctx
= NULL
;
1203 struct srvsvc_NetFileCtr3
*ctr3
;
1204 uint32_t resume_hnd
= 0;
1207 switch (r
->in
.info_ctr
->level
) {
1211 return WERR_UNKNOWN_LEVEL
;
1214 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1215 p
->session_info
->security_token
)) {
1216 DEBUG(1, ("Enumerating files only allowed for "
1217 "administrators\n"));
1218 return WERR_ACCESS_DENIED
;
1222 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1224 werr
= WERR_INVALID_PARAM
;
1228 /* TODO -- Windows enumerates
1230 (c) open directories and files */
1232 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1233 if (!W_ERROR_IS_OK(werr
)) {
1237 *r
->out
.totalentries
= ctr3
->count
;
1238 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1239 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1247 /*******************************************************************
1248 _srvsvc_NetSrvGetInfo
1249 ********************************************************************/
1251 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1252 struct srvsvc_NetSrvGetInfo
*r
)
1254 WERROR status
= WERR_OK
;
1256 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1258 if (!pipe_access_check(p
)) {
1259 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1260 return WERR_ACCESS_DENIED
;
1263 switch (r
->in
.level
) {
1265 /* Technically level 102 should only be available to
1266 Administrators but there isn't anything super-secret
1267 here, as most of it is made up. */
1270 struct srvsvc_NetSrvInfo102
*info102
;
1272 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1277 info102
->platform_id
= PLATFORM_ID_NT
;
1278 info102
->server_name
= lp_netbios_name();
1279 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1280 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1281 info102
->server_type
= lp_default_server_announce();
1282 info102
->comment
= string_truncate(lp_server_string(talloc_tos()),
1283 MAX_SERVER_STRING_LENGTH
);
1284 info102
->users
= 0xffffffff;
1285 info102
->disc
= 0xf;
1286 info102
->hidden
= 0;
1287 info102
->announce
= 240;
1288 info102
->anndelta
= 3000;
1289 info102
->licenses
= 100000;
1290 info102
->userpath
= "C:\\";
1292 r
->out
.info
->info102
= info102
;
1296 struct srvsvc_NetSrvInfo101
*info101
;
1298 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1303 info101
->platform_id
= PLATFORM_ID_NT
;
1304 info101
->server_name
= lp_netbios_name();
1305 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1306 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1307 info101
->server_type
= lp_default_server_announce();
1308 info101
->comment
= string_truncate(lp_server_string(talloc_tos()),
1309 MAX_SERVER_STRING_LENGTH
);
1311 r
->out
.info
->info101
= info101
;
1315 struct srvsvc_NetSrvInfo100
*info100
;
1317 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1322 info100
->platform_id
= PLATFORM_ID_NT
;
1323 info100
->server_name
= lp_netbios_name();
1325 r
->out
.info
->info100
= info100
;
1330 status
= WERR_UNKNOWN_LEVEL
;
1334 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1339 /*******************************************************************
1340 _srvsvc_NetSrvSetInfo
1341 ********************************************************************/
1343 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1344 struct srvsvc_NetSrvSetInfo
*r
)
1346 WERROR status
= WERR_OK
;
1348 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1350 /* Set up the net server set info structure. */
1352 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1357 /*******************************************************************
1359 ********************************************************************/
1361 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1362 struct srvsvc_NetConnEnum
*r
)
1366 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1368 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1369 p
->session_info
->security_token
)) {
1370 DEBUG(1, ("Enumerating connections only allowed for "
1371 "administrators\n"));
1372 return WERR_ACCESS_DENIED
;
1375 switch (r
->in
.info_ctr
->level
) {
1377 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1378 r
->in
.resume_handle
,
1379 r
->out
.totalentries
);
1382 werr
= init_srv_conn_info_1(r
->in
.path
,
1383 r
->in
.info_ctr
->ctr
.ctr1
,
1384 r
->in
.resume_handle
,
1385 r
->out
.totalentries
);
1388 return WERR_UNKNOWN_LEVEL
;
1391 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1396 /*******************************************************************
1398 ********************************************************************/
1400 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1401 struct srvsvc_NetSessEnum
*r
)
1405 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1407 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1408 p
->session_info
->security_token
)) {
1409 DEBUG(1, ("Enumerating sessions only allowed for "
1410 "administrators\n"));
1411 return WERR_ACCESS_DENIED
;
1414 switch (r
->in
.info_ctr
->level
) {
1416 werr
= init_srv_sess_info_0(p
,
1417 r
->in
.info_ctr
->ctr
.ctr0
,
1418 r
->in
.resume_handle
,
1419 r
->out
.totalentries
);
1422 werr
= init_srv_sess_info_1(p
,
1423 r
->in
.info_ctr
->ctr
.ctr1
,
1424 r
->in
.resume_handle
,
1425 r
->out
.totalentries
);
1428 return WERR_UNKNOWN_LEVEL
;
1431 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1436 /*******************************************************************
1438 ********************************************************************/
1440 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1441 struct srvsvc_NetSessDel
*r
)
1443 struct sessionid
*session_list
;
1444 int num_sessions
, snum
;
1445 const char *username
;
1446 const char *machine
;
1447 bool not_root
= False
;
1450 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1452 werr
= WERR_ACCESS_DENIED
;
1454 /* fail out now if you are not root or not a domain admin */
1456 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1457 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1458 DOMAIN_RID_ADMINS
))) {
1463 username
= r
->in
.user
;
1464 machine
= r
->in
.client
;
1466 /* strip leading backslashes if any */
1467 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1471 num_sessions
= find_sessions(p
->mem_ctx
, username
, machine
,
1474 for (snum
= 0; snum
< num_sessions
; snum
++) {
1478 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1483 ntstat
= messaging_send(p
->msg_ctx
,
1484 session_list
[snum
].pid
,
1485 MSG_SHUTDOWN
, &data_blob_null
);
1487 if (NT_STATUS_IS_OK(ntstat
))
1494 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1501 /*******************************************************************
1502 _srvsvc_NetShareEnumAll
1503 ********************************************************************/
1505 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1506 struct srvsvc_NetShareEnumAll
*r
)
1510 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1512 if (!pipe_access_check(p
)) {
1513 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1514 return WERR_ACCESS_DENIED
;
1517 /* Create the list of shares for the response. */
1518 werr
= init_srv_share_info_ctr(p
,
1520 r
->in
.resume_handle
,
1521 r
->out
.totalentries
,
1524 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1529 /*******************************************************************
1530 _srvsvc_NetShareEnum
1531 ********************************************************************/
1533 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1534 struct srvsvc_NetShareEnum
*r
)
1538 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1540 if (!pipe_access_check(p
)) {
1541 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1542 return WERR_ACCESS_DENIED
;
1545 /* Create the list of shares for the response. */
1546 werr
= init_srv_share_info_ctr(p
,
1548 r
->in
.resume_handle
,
1549 r
->out
.totalentries
,
1552 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1557 /*******************************************************************
1558 _srvsvc_NetShareGetInfo
1559 ********************************************************************/
1561 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1562 struct srvsvc_NetShareGetInfo
*r
)
1564 WERROR status
= WERR_OK
;
1565 char *share_name
= NULL
;
1567 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1569 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1571 if (!r
->in
.share_name
) {
1572 return WERR_INVALID_NAME
;
1575 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1580 return WERR_INVALID_NAME
;
1583 switch (r
->in
.level
) {
1585 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1586 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1587 init_srv_share_info_0(p
, info
->info0
, snum
);
1590 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1591 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1592 init_srv_share_info_1(p
, info
->info1
, snum
);
1595 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1596 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1597 init_srv_share_info_2(p
, info
->info2
, snum
);
1598 info
->info2
->current_users
=
1599 count_current_connections(info
->info2
->name
, false);
1602 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1603 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1604 init_srv_share_info_501(p
, info
->info501
, snum
);
1607 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1608 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1609 init_srv_share_info_502(p
, info
->info502
, snum
);
1612 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1613 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1614 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1617 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1618 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1619 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1622 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1623 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1624 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1627 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1628 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1629 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1632 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1635 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1637 status
= WERR_UNKNOWN_LEVEL
;
1641 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1646 /*******************************************************************
1647 _srvsvc_NetShareSetInfo. Modify share details.
1648 ********************************************************************/
1650 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1651 struct srvsvc_NetShareSetInfo
*r
)
1653 char *command
= NULL
;
1654 char *share_name
= NULL
;
1655 char *comment
= NULL
;
1656 const char *pathname
= NULL
;
1661 struct security_descriptor
*psd
= NULL
;
1662 bool is_disk_op
= False
;
1663 const char *csc_policy
= NULL
;
1664 bool csc_policy_changed
= false;
1665 const char *csc_policies
[] = {"manual", "documents", "programs",
1667 uint32_t client_csc_policy
;
1668 int max_connections
= 0;
1669 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1670 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1672 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1674 if (!r
->in
.share_name
) {
1675 return WERR_INVALID_NAME
;
1678 if (r
->out
.parm_error
) {
1679 *r
->out
.parm_error
= 0;
1682 if ( strequal(r
->in
.share_name
,"IPC$")
1683 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1684 || strequal(r
->in
.share_name
,"global") )
1686 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1687 "modified by a remote user.\n",
1688 r
->in
.share_name
));
1689 return WERR_ACCESS_DENIED
;
1692 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1697 /* Does this share exist ? */
1699 return WERR_NET_NAME_NOT_FOUND
;
1701 /* No change to printer shares. */
1702 if (lp_printable(snum
))
1703 return WERR_ACCESS_DENIED
;
1705 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1707 /* fail out now if you are not root and not a disk op */
1709 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1710 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1711 "SeDiskOperatorPrivilege privilege needed to modify "
1713 (unsigned int)p
->session_info
->unix_token
->uid
,
1715 return WERR_ACCESS_DENIED
;
1718 max_connections
= lp_max_connections(snum
);
1719 csc_policy
= csc_policies
[lp_csc_policy(snum
)];
1721 switch (r
->in
.level
) {
1723 pathname
= lp_path(ctx
, snum
);
1724 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1725 type
= info
->info1
->type
;
1729 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1730 pathname
= info
->info2
->path
;
1731 type
= info
->info2
->type
;
1732 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1733 0 : info
->info2
->max_users
;
1737 /* not supported on set but here for completeness */
1739 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1740 type
= info
->info501
->type
;
1745 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1746 pathname
= info
->info502
->path
;
1747 type
= info
->info502
->type
;
1748 psd
= info
->info502
->sd_buf
.sd
;
1749 map_generic_share_sd_bits(psd
);
1752 pathname
= lp_path(ctx
, snum
);
1753 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1754 type
= STYPE_DISKTREE
;
1757 /* XP re-sets the csc policy even if it wasn't changed by the
1758 user, so we must compare it to see if it's what is set in
1759 smb.conf, so that we can contine other ops like setting
1761 client_csc_policy
= (info
->info1005
->dfs_flags
&
1762 SHARE_1005_CSC_POLICY_MASK
) >>
1763 SHARE_1005_CSC_POLICY_SHIFT
;
1765 if (client_csc_policy
== lp_csc_policy(snum
))
1768 csc_policy
= csc_policies
[client_csc_policy
];
1769 csc_policy_changed
= true;
1772 pathname
= lp_path(ctx
, snum
);
1773 comment
= lp_comment(ctx
, snum
);
1774 type
= STYPE_DISKTREE
;
1778 return WERR_ACCESS_DENIED
;
1780 pathname
= lp_path(ctx
, snum
);
1781 comment
= lp_comment(ctx
, snum
);
1782 psd
= info
->info1501
->sd
;
1783 map_generic_share_sd_bits(psd
);
1784 type
= STYPE_DISKTREE
;
1787 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1789 return WERR_UNKNOWN_LEVEL
;
1792 /* We can only modify disk shares. */
1793 if (type
!= STYPE_DISKTREE
) {
1794 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1797 return WERR_ACCESS_DENIED
;
1800 if (comment
== NULL
) {
1804 /* Check if the pathname is valid. */
1805 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1806 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1808 return WERR_OBJECT_PATH_INVALID
;
1811 /* Ensure share name, pathname and comment don't contain '"' characters. */
1812 string_replace(share_name
, '"', ' ');
1813 string_replace(path
, '"', ' ');
1814 string_replace(comment
, '"', ' ');
1816 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1817 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1819 /* Only call modify function if something changed. */
1821 if (strcmp(path
, lp_path(talloc_tos(), snum
)) || strcmp(comment
, lp_comment(talloc_tos(), snum
))
1822 || (lp_max_connections(snum
) != max_connections
)
1823 || csc_policy_changed
) {
1825 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1826 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1827 return WERR_ACCESS_DENIED
;
1830 command
= talloc_asprintf(p
->mem_ctx
,
1831 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1832 lp_change_share_command(talloc_tos()),
1833 get_dyn_CONFIGFILE(),
1836 comment
? comment
: "",
1843 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1845 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1850 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1851 /* Tell everyone we updated smb.conf. */
1852 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1859 /********* END SeDiskOperatorPrivilege BLOCK *********/
1861 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1864 TALLOC_FREE(command
);
1867 return WERR_ACCESS_DENIED
;
1869 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1873 /* Replace SD if changed. */
1875 struct security_descriptor
*old_sd
;
1878 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
1880 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1881 if (!set_share_security(share_name
, psd
))
1882 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1887 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1892 /*******************************************************************
1893 _srvsvc_NetShareAdd.
1894 Call 'add_share_command "sharename" "pathname"
1895 "comment" "max connections = "
1896 ********************************************************************/
1898 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1899 struct srvsvc_NetShareAdd
*r
)
1901 char *command
= NULL
;
1902 char *share_name_in
= NULL
;
1903 char *share_name
= NULL
;
1904 char *comment
= NULL
;
1905 char *pathname
= NULL
;
1910 struct security_descriptor
*psd
= NULL
;
1912 int max_connections
= 0;
1913 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1915 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1917 if (r
->out
.parm_error
) {
1918 *r
->out
.parm_error
= 0;
1921 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1923 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1924 return WERR_ACCESS_DENIED
;
1926 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1927 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1928 return WERR_ACCESS_DENIED
;
1931 switch (r
->in
.level
) {
1933 /* No path. Not enough info in a level 0 to do anything. */
1934 return WERR_ACCESS_DENIED
;
1936 /* Not enough info in a level 1 to do anything. */
1937 return WERR_ACCESS_DENIED
;
1939 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1940 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1941 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1942 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1943 0 : r
->in
.info
->info2
->max_users
;
1944 type
= r
->in
.info
->info2
->type
;
1947 /* No path. Not enough info in a level 501 to do anything. */
1948 return WERR_ACCESS_DENIED
;
1950 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1951 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1952 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1953 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1954 0 : r
->in
.info
->info502
->max_users
;
1955 type
= r
->in
.info
->info502
->type
;
1956 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1957 map_generic_share_sd_bits(psd
);
1960 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1966 return WERR_ACCESS_DENIED
;
1968 /* DFS only level. */
1969 return WERR_ACCESS_DENIED
;
1971 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1973 return WERR_UNKNOWN_LEVEL
;
1976 /* check for invalid share names */
1978 if (!share_name_in
|| !validate_net_name(share_name_in
,
1979 INVALID_SHARENAME_CHARS
,
1980 strlen(share_name_in
))) {
1981 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1982 share_name_in
? share_name_in
: ""));
1983 return WERR_INVALID_NAME
;
1986 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
1987 || (lp_enable_asu_support() &&
1988 strequal(share_name_in
,"ADMIN$"))) {
1989 return WERR_ACCESS_DENIED
;
1992 snum
= find_service(ctx
, share_name_in
, &share_name
);
1997 /* Share already exists. */
1999 return WERR_FILE_EXISTS
;
2002 /* We can only add disk shares. */
2003 if (type
!= STYPE_DISKTREE
) {
2004 return WERR_ACCESS_DENIED
;
2007 /* Check if the pathname is valid. */
2008 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
2009 return WERR_OBJECT_PATH_INVALID
;
2012 /* Ensure share name, pathname and comment don't contain '"' characters. */
2013 string_replace(share_name_in
, '"', ' ');
2014 string_replace(share_name
, '"', ' ');
2015 string_replace(path
, '"', ' ');
2017 string_replace(comment
, '"', ' ');
2020 command
= talloc_asprintf(ctx
,
2021 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2022 lp_add_share_command(talloc_tos()),
2023 get_dyn_CONFIGFILE(),
2026 comment
? comment
: "",
2032 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
2034 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2039 /* FIXME: use libnetconf here - gd */
2041 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2042 /* Tell everyone we updated smb.conf. */
2043 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2050 /********* END SeDiskOperatorPrivilege BLOCK *********/
2052 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2055 TALLOC_FREE(command
);
2058 return WERR_ACCESS_DENIED
;
2061 /* Note we use share_name here, not share_name_in as
2062 we need a canonicalized name for setting security. */
2063 if (!set_share_security(share_name
, psd
)) {
2064 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2070 * We don't call reload_services() here, the message will
2071 * cause this to be done before the next packet is read
2072 * from the client. JRA.
2075 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
2080 /*******************************************************************
2082 Call "delete share command" with the share name as
2084 ********************************************************************/
2086 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
2087 struct srvsvc_NetShareDel
*r
)
2089 char *command
= NULL
;
2090 char *share_name
= NULL
;
2094 struct share_params
*params
;
2095 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2097 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
2099 if (!r
->in
.share_name
) {
2100 return WERR_NET_NAME_NOT_FOUND
;
2103 if ( strequal(r
->in
.share_name
,"IPC$")
2104 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
2105 || strequal(r
->in
.share_name
,"global") )
2107 return WERR_ACCESS_DENIED
;
2110 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
2116 return WERR_NO_SUCH_SHARE
;
2119 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
2120 return WERR_NO_SUCH_SHARE
;
2123 /* No change to printer shares. */
2124 if (lp_printable(snum
))
2125 return WERR_ACCESS_DENIED
;
2127 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2129 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
2130 return WERR_ACCESS_DENIED
;
2132 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2133 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2134 return WERR_ACCESS_DENIED
;
2137 command
= talloc_asprintf(ctx
,
2139 lp_delete_share_command(talloc_tos()),
2140 get_dyn_CONFIGFILE(),
2141 lp_servicename(talloc_tos(), snum
));
2146 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
2148 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2153 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2154 /* Tell everyone we updated smb.conf. */
2155 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2162 /********* END SeDiskOperatorPrivilege BLOCK *********/
2164 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2167 return WERR_ACCESS_DENIED
;
2169 /* Delete the SD in the database. */
2170 delete_share_security(lp_servicename(talloc_tos(), params
->service
));
2172 lp_killservice(params
->service
);
2177 /*******************************************************************
2178 _srvsvc_NetShareDelSticky
2179 ********************************************************************/
2181 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2182 struct srvsvc_NetShareDelSticky
*r
)
2184 struct srvsvc_NetShareDel q
;
2186 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2188 q
.in
.server_unc
= r
->in
.server_unc
;
2189 q
.in
.share_name
= r
->in
.share_name
;
2190 q
.in
.reserved
= r
->in
.reserved
;
2192 return _srvsvc_NetShareDel(p
, &q
);
2195 /*******************************************************************
2196 _srvsvc_NetRemoteTOD
2197 ********************************************************************/
2199 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2200 struct srvsvc_NetRemoteTOD
*r
)
2202 struct srvsvc_NetRemoteTODInfo
*tod
;
2204 time_t unixdate
= time(NULL
);
2206 /* We do this call first as if we do it *after* the gmtime call
2207 it overwrites the pointed-to values. JRA */
2209 uint32 zone
= get_time_zone(unixdate
)/60;
2211 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2213 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2218 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2220 t
= gmtime(&unixdate
);
2223 tod
->elapsed
= unixdate
;
2225 tod
->hours
= t
->tm_hour
;
2226 tod
->mins
= t
->tm_min
;
2227 tod
->secs
= t
->tm_sec
;
2229 tod
->timezone
= zone
;
2230 tod
->tinterval
= 10000;
2231 tod
->day
= t
->tm_mday
;
2232 tod
->month
= t
->tm_mon
+ 1;
2233 tod
->year
= 1900+t
->tm_year
;
2234 tod
->weekday
= t
->tm_wday
;
2236 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2241 /***********************************************************************************
2242 _srvsvc_NetGetFileSecurity
2243 Win9x NT tools get security descriptor.
2244 ***********************************************************************************/
2246 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2247 struct srvsvc_NetGetFileSecurity
*r
)
2249 struct smb_filename
*smb_fname
= NULL
;
2251 char *servicename
= NULL
;
2255 connection_struct
*conn
= NULL
;
2256 struct sec_desc_buf
*sd_buf
= NULL
;
2257 files_struct
*fsp
= NULL
;
2259 char *oldcwd
= NULL
;
2264 werr
= WERR_NET_NAME_NOT_FOUND
;
2267 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2273 DEBUG(10, ("Could not find service %s\n", servicename
));
2274 werr
= WERR_NET_NAME_NOT_FOUND
;
2278 nt_status
= create_conn_struct_cwd(talloc_tos(),
2279 server_event_context(),
2280 server_messaging_context(),
2282 snum
, lp_path(talloc_tos(), snum
),
2283 p
->session_info
, &oldcwd
);
2284 if (!NT_STATUS_IS_OK(nt_status
)) {
2285 DEBUG(10, ("create_conn_struct failed: %s\n",
2286 nt_errstr(nt_status
)));
2287 werr
= ntstatus_to_werror(nt_status
);
2291 nt_status
= filename_convert(talloc_tos(),
2298 if (!NT_STATUS_IS_OK(nt_status
)) {
2299 werr
= ntstatus_to_werror(nt_status
);
2303 nt_status
= SMB_VFS_CREATE_FILE(
2306 0, /* root_dir_fid */
2307 smb_fname
, /* fname */
2308 FILE_READ_ATTRIBUTES
, /* access_mask */
2309 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2310 FILE_OPEN
, /* create_disposition*/
2311 0, /* create_options */
2312 0, /* file_attributes */
2313 INTERNAL_OPEN_ONLY
, /* oplock_request */
2314 0, /* allocation_size */
2315 0, /* private_flags */
2321 if (!NT_STATUS_IS_OK(nt_status
)) {
2322 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2323 smb_fname_str_dbg(smb_fname
)));
2324 werr
= ntstatus_to_werror(nt_status
);
2328 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2334 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2337 |SECINFO_DACL
), sd_buf
, &sd_buf
->sd
);
2339 if (!NT_STATUS_IS_OK(nt_status
)) {
2340 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2341 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2342 werr
= ntstatus_to_werror(nt_status
);
2343 TALLOC_FREE(sd_buf
);
2347 if (sd_buf
->sd
->dacl
) {
2348 sd_buf
->sd
->dacl
->revision
= NT4_ACL_REVISION
;
2351 sd_size
= ndr_size_security_descriptor(sd_buf
->sd
, 0);
2353 sd_buf
->sd_size
= sd_size
;
2355 *r
->out
.sd_buf
= sd_buf
;
2357 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2358 vfs_ChDir(conn
, oldcwd
);
2359 SMB_VFS_DISCONNECT(conn
);
2367 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2371 vfs_ChDir(conn
, oldcwd
);
2375 SMB_VFS_DISCONNECT(conn
);
2381 TALLOC_FREE(smb_fname
);
2386 /***********************************************************************************
2387 _srvsvc_NetSetFileSecurity
2388 Win9x NT tools set security descriptor.
2389 ***********************************************************************************/
2391 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2392 struct srvsvc_NetSetFileSecurity
*r
)
2394 struct smb_filename
*smb_fname
= NULL
;
2395 char *servicename
= NULL
;
2396 files_struct
*fsp
= NULL
;
2400 connection_struct
*conn
= NULL
;
2402 char *oldcwd
= NULL
;
2403 struct security_descriptor
*psd
= NULL
;
2404 uint32_t security_info_sent
= 0;
2409 werr
= WERR_NET_NAME_NOT_FOUND
;
2413 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2420 DEBUG(10, ("Could not find service %s\n", servicename
));
2421 werr
= WERR_NET_NAME_NOT_FOUND
;
2425 nt_status
= create_conn_struct_cwd(talloc_tos(),
2426 server_event_context(),
2427 server_messaging_context(),
2429 snum
, lp_path(talloc_tos(), snum
),
2430 p
->session_info
, &oldcwd
);
2431 if (!NT_STATUS_IS_OK(nt_status
)) {
2432 DEBUG(10, ("create_conn_struct failed: %s\n",
2433 nt_errstr(nt_status
)));
2434 werr
= ntstatus_to_werror(nt_status
);
2438 nt_status
= filename_convert(talloc_tos(),
2445 if (!NT_STATUS_IS_OK(nt_status
)) {
2446 werr
= ntstatus_to_werror(nt_status
);
2450 nt_status
= SMB_VFS_CREATE_FILE(
2453 0, /* root_dir_fid */
2454 smb_fname
, /* fname */
2455 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2456 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2457 FILE_OPEN
, /* create_disposition*/
2458 0, /* create_options */
2459 0, /* file_attributes */
2460 INTERNAL_OPEN_ONLY
, /* oplock_request */
2461 0, /* allocation_size */
2462 0, /* private_flags */
2468 if (!NT_STATUS_IS_OK(nt_status
)) {
2469 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2470 smb_fname_str_dbg(smb_fname
)));
2471 werr
= ntstatus_to_werror(nt_status
);
2475 psd
= r
->in
.sd_buf
->sd
;
2476 security_info_sent
= r
->in
.securityinformation
;
2478 nt_status
= set_sd(fsp
, psd
, security_info_sent
);
2480 if (!NT_STATUS_IS_OK(nt_status
) ) {
2481 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2482 "on file %s\n", r
->in
.share
));
2483 werr
= WERR_ACCESS_DENIED
;
2487 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2488 vfs_ChDir(conn
, oldcwd
);
2489 SMB_VFS_DISCONNECT(conn
);
2497 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2501 vfs_ChDir(conn
, oldcwd
);
2505 SMB_VFS_DISCONNECT(conn
);
2510 TALLOC_FREE(smb_fname
);
2515 /***********************************************************************************
2516 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2517 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2518 These disks would the disks listed by this function.
2519 Users could then create shares relative to these disks. Watch out for moving these disks around.
2520 "Nigel Williams" <nigel@veritas.com>.
2521 ***********************************************************************************/
2523 static const char *server_disks
[] = {"C:"};
2525 static uint32
get_server_disk_count(void)
2527 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2530 static uint32
init_server_disk_enum(uint32
*resume
)
2532 uint32 server_disk_count
= get_server_disk_count();
2534 /*resume can be an offset into the list for now*/
2536 if(*resume
& 0x80000000)
2539 if(*resume
> server_disk_count
)
2540 *resume
= server_disk_count
;
2542 return server_disk_count
- *resume
;
2545 static const char *next_server_disk_enum(uint32
*resume
)
2549 if(init_server_disk_enum(resume
) == 0)
2552 disk
= server_disks
[*resume
];
2556 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2561 /********************************************************************
2563 ********************************************************************/
2565 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2566 struct srvsvc_NetDiskEnum
*r
)
2569 const char *disk_name
;
2570 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2572 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2576 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2578 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2579 MAX_SERVER_DISK_ENTRIES
);
2580 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2582 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2584 r
->out
.info
->count
= 0;
2586 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2588 r
->out
.info
->count
++;
2590 /*copy disk name into a unicode string*/
2592 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2593 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2596 /* add a terminating null string. Is this there if there is more data to come? */
2598 r
->out
.info
->count
++;
2600 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2601 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2603 if (r
->out
.resume_handle
) {
2604 *r
->out
.resume_handle
= resume
;
2610 /********************************************************************
2611 _srvsvc_NetNameValidate
2612 ********************************************************************/
2614 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2615 struct srvsvc_NetNameValidate
*r
)
2617 switch (r
->in
.name_type
) {
2619 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2620 strlen_m(r
->in
.name
)))
2622 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2624 return WERR_INVALID_NAME
;
2629 return WERR_UNKNOWN_LEVEL
;
2635 /*******************************************************************
2636 ********************************************************************/
2638 struct enum_file_close_state
{
2639 struct srvsvc_NetFileClose
*r
;
2640 struct messaging_context
*msg_ctx
;
2643 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2644 const char *sharepath
, const char *fname
,
2645 void *private_data
)
2647 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2648 struct enum_file_close_state
*state
=
2649 (struct enum_file_close_state
*)private_data
;
2650 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2652 if (fid
!= state
->r
->in
.fid
) {
2653 return; /* Not this file. */
2656 if (!process_exists(e
->pid
) ) {
2660 /* Ok - send the close message. */
2661 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2663 share_mode_str(talloc_tos(), 0, e
) ));
2665 share_mode_entry_to_message(msg
, e
);
2667 state
->r
->out
.result
= ntstatus_to_werror(
2668 messaging_send_buf(state
->msg_ctx
,
2669 e
->pid
, MSG_SMB_CLOSE_FILE
,
2670 (uint8
*)msg
, sizeof(msg
)));
2673 /********************************************************************
2674 Close a file given a 32-bit file id.
2675 ********************************************************************/
2677 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2678 struct srvsvc_NetFileClose
*r
)
2680 struct enum_file_close_state state
;
2683 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2685 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2687 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2688 return WERR_ACCESS_DENIED
;
2691 /* enum_file_close_fn sends the close message to
2692 * the relevant smbd process. */
2694 r
->out
.result
= WERR_BADFILE
;
2696 state
.msg_ctx
= p
->msg_ctx
;
2697 share_mode_forall(enum_file_close_fn
, &state
);
2698 return r
->out
.result
;
2701 /********************************************************************
2702 ********************************************************************/
2704 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2705 struct srvsvc_NetCharDevEnum
*r
)
2707 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2708 return WERR_NOT_SUPPORTED
;
2711 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2712 struct srvsvc_NetCharDevGetInfo
*r
)
2714 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2715 return WERR_NOT_SUPPORTED
;
2718 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2719 struct srvsvc_NetCharDevControl
*r
)
2721 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2722 return WERR_NOT_SUPPORTED
;
2725 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2726 struct srvsvc_NetCharDevQEnum
*r
)
2728 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2729 return WERR_NOT_SUPPORTED
;
2732 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2733 struct srvsvc_NetCharDevQGetInfo
*r
)
2735 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2736 return WERR_NOT_SUPPORTED
;
2739 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2740 struct srvsvc_NetCharDevQSetInfo
*r
)
2742 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2743 return WERR_NOT_SUPPORTED
;
2746 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2747 struct srvsvc_NetCharDevQPurge
*r
)
2749 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2750 return WERR_NOT_SUPPORTED
;
2753 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2754 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2756 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2757 return WERR_NOT_SUPPORTED
;
2760 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2761 struct srvsvc_NetFileGetInfo
*r
)
2763 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2764 return WERR_NOT_SUPPORTED
;
2767 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2768 struct srvsvc_NetShareCheck
*r
)
2770 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2771 return WERR_NOT_SUPPORTED
;
2774 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2775 struct srvsvc_NetServerStatisticsGet
*r
)
2777 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2778 return WERR_NOT_SUPPORTED
;
2781 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2782 struct srvsvc_NetTransportAdd
*r
)
2784 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2785 return WERR_NOT_SUPPORTED
;
2788 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2789 struct srvsvc_NetTransportEnum
*r
)
2791 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2792 return WERR_NOT_SUPPORTED
;
2795 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2796 struct srvsvc_NetTransportDel
*r
)
2798 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2799 return WERR_NOT_SUPPORTED
;
2802 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2803 struct srvsvc_NetSetServiceBits
*r
)
2805 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2806 return WERR_NOT_SUPPORTED
;
2809 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2810 struct srvsvc_NetPathType
*r
)
2812 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2813 return WERR_NOT_SUPPORTED
;
2816 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2817 struct srvsvc_NetPathCanonicalize
*r
)
2819 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2820 return WERR_NOT_SUPPORTED
;
2823 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2824 struct srvsvc_NetPathCompare
*r
)
2826 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2827 return WERR_NOT_SUPPORTED
;
2830 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2831 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2833 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2834 return WERR_NOT_SUPPORTED
;
2837 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2838 struct srvsvc_NetPRNameCompare
*r
)
2840 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2841 return WERR_NOT_SUPPORTED
;
2844 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2845 struct srvsvc_NetShareDelStart
*r
)
2847 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2848 return WERR_NOT_SUPPORTED
;
2851 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2852 struct srvsvc_NetShareDelCommit
*r
)
2854 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2855 return WERR_NOT_SUPPORTED
;
2858 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2859 struct srvsvc_NetServerTransportAddEx
*r
)
2861 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2862 return WERR_NOT_SUPPORTED
;
2865 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2866 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2868 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2869 return WERR_NOT_SUPPORTED
;
2872 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2873 struct srvsvc_NETRDFSGETVERSION
*r
)
2875 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2876 return WERR_NOT_SUPPORTED
;
2879 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2880 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2882 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2883 return WERR_NOT_SUPPORTED
;
2886 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2887 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2889 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2890 return WERR_NOT_SUPPORTED
;
2893 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2894 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2896 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2897 return WERR_NOT_SUPPORTED
;
2900 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2901 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2903 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2904 return WERR_NOT_SUPPORTED
;
2907 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2908 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2910 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2911 return WERR_NOT_SUPPORTED
;
2914 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2915 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2917 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2918 return WERR_NOT_SUPPORTED
;
2921 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2922 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2924 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2925 return WERR_NOT_SUPPORTED
;
2928 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2929 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2931 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2932 return WERR_NOT_SUPPORTED
;
2935 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2936 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2938 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2939 return WERR_NOT_SUPPORTED
;
2942 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2943 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2945 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2946 return WERR_NOT_SUPPORTED
;