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 /*******************************************************************
65 ********************************************************************/
67 static void enum_file_fn( const struct share_mode_entry
*e
,
68 const char *sharepath
, const char *fname
,
71 struct file_enum_count
*fenum
=
72 (struct file_enum_count
*)private_data
;
74 struct srvsvc_NetFileInfo3
*f
;
75 int i
= fenum
->ctr3
->count
;
77 struct byte_range_lock
*brl
;
79 char *fullpath
= NULL
;
83 /* If the pid was not found delete the entry from connections.tdb */
85 if ( !process_exists(e
->pid
) ) {
89 username
= uidtoname(e
->uid
);
91 if ((fenum
->username
!= NULL
)
92 && !strequal(username
, fenum
->username
)) {
96 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
97 struct srvsvc_NetFileInfo3
, i
+1);
99 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
102 fenum
->ctr3
->array
= f
;
104 /* need to count the number of locks on a file */
109 if ( (brl
= brl_get_locks(talloc_tos(), &fsp
)) != NULL
) {
110 num_locks
= brl_num_locks(brl
);
114 if ( strcmp( fname
, "." ) == 0 ) {
115 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s", sharepath
);
117 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s/%s",
123 string_replace( fullpath
, '/', '\\' );
125 /* mask out create (what ever that is) */
126 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
128 /* now fill in the srvsvc_NetFileInfo3 struct */
130 fenum
->ctr3
->array
[i
].fid
=
131 (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
132 fenum
->ctr3
->array
[i
].permissions
= permissions
;
133 fenum
->ctr3
->array
[i
].num_locks
= num_locks
;
134 fenum
->ctr3
->array
[i
].path
= fullpath
;
135 fenum
->ctr3
->array
[i
].user
= username
;
137 fenum
->ctr3
->count
++;
140 /*******************************************************************
141 ********************************************************************/
143 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
144 const char *username
,
145 struct srvsvc_NetFileCtr3
**ctr3
,
148 struct file_enum_count f_enum_cnt
;
150 f_enum_cnt
.ctx
= ctx
;
151 f_enum_cnt
.username
= username
;
152 f_enum_cnt
.ctr3
= *ctr3
;
154 share_mode_forall( enum_file_fn
, (void *)&f_enum_cnt
);
156 *ctr3
= f_enum_cnt
.ctr3
;
161 /*******************************************************************
162 Utility function to get the 'type' of a share from an snum.
163 ********************************************************************/
164 static enum srvsvc_ShareType
get_share_type(int snum
)
166 /* work out the share type */
167 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
169 if (lp_printable(snum
)) {
170 type
= lp_administrative_share(snum
)
171 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
173 if (strequal(lp_fstype(snum
), "IPC")) {
174 type
= lp_administrative_share(snum
)
175 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
180 /*******************************************************************
181 Fill in a share info level 0 structure.
182 ********************************************************************/
184 static void init_srv_share_info_0(struct pipes_struct
*p
,
185 struct srvsvc_NetShareInfo0
*r
, int snum
)
187 r
->name
= lp_servicename(talloc_tos(), snum
);
190 /*******************************************************************
191 Fill in a share info level 1 structure.
192 ********************************************************************/
194 static void init_srv_share_info_1(struct pipes_struct
*p
,
195 struct srvsvc_NetShareInfo1
*r
,
198 char *net_name
= lp_servicename(talloc_tos(), snum
);
199 char *remark
= lp_comment(p
->mem_ctx
, snum
);
202 remark
= talloc_sub_advanced(
203 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
204 get_current_username(), lp_path(talloc_tos(), snum
),
205 p
->session_info
->unix_token
->uid
, get_current_username(),
210 r
->type
= get_share_type(snum
);
211 r
->comment
= remark
? remark
: "";
214 /*******************************************************************
215 Fill in a share info level 2 structure.
216 ********************************************************************/
218 static void init_srv_share_info_2(struct pipes_struct
*p
,
219 struct srvsvc_NetShareInfo2
*r
,
224 int max_connections
= lp_max_connections(snum
);
225 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
226 char *net_name
= lp_servicename(talloc_tos(), snum
);
228 remark
= lp_comment(p
->mem_ctx
, snum
);
230 remark
= talloc_sub_advanced(
231 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
232 get_current_username(), lp_path(talloc_tos(), snum
),
233 p
->session_info
->unix_token
->uid
, get_current_username(),
236 path
= talloc_asprintf(p
->mem_ctx
,
237 "C:%s", lp_path(talloc_tos(), snum
));
241 * Change / to \\ so that win2k will see it as a valid path.
242 * This was added to enable use of browsing in win2k add
246 string_replace(path
, '/', '\\');
250 r
->type
= get_share_type(snum
);
251 r
->comment
= remark
? remark
: "";
253 r
->max_users
= max_uses
;
254 r
->current_users
= 0; /* computed later */
255 r
->path
= path
? path
: "";
259 /*******************************************************************
260 Map any generic bits to file specific bits.
261 ********************************************************************/
263 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
266 struct security_acl
*ps_dacl
= NULL
;
275 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
276 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
277 uint32 orig_mask
= psa
->access_mask
;
279 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
280 psa
->access_mask
|= orig_mask
;
284 /*******************************************************************
285 Fill in a share info level 501 structure.
286 ********************************************************************/
288 static void init_srv_share_info_501(struct pipes_struct
*p
,
289 struct srvsvc_NetShareInfo501
*r
, int snum
)
291 const char *net_name
= lp_servicename(talloc_tos(), snum
);
292 char *remark
= lp_comment(p
->mem_ctx
, snum
);
295 remark
= talloc_sub_advanced(
296 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
297 get_current_username(), lp_path(talloc_tos(), snum
),
298 p
->session_info
->unix_token
->uid
, get_current_username(),
303 r
->type
= get_share_type(snum
);
304 r
->comment
= remark
? remark
: "";
307 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
310 r
->csc_policy
= (lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
);
313 /*******************************************************************
314 Fill in a share info level 502 structure.
315 ********************************************************************/
317 static void init_srv_share_info_502(struct pipes_struct
*p
,
318 struct srvsvc_NetShareInfo502
*r
, int snum
)
320 const char *net_name
= lp_servicename(talloc_tos(), snum
);
322 struct security_descriptor
*sd
= NULL
;
323 struct sec_desc_buf
*sd_buf
= NULL
;
325 TALLOC_CTX
*ctx
= p
->mem_ctx
;
326 char *remark
= lp_comment(ctx
, snum
);
329 remark
= talloc_sub_advanced(
330 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
331 get_current_username(), lp_path(talloc_tos(), snum
),
332 p
->session_info
->unix_token
->uid
, get_current_username(),
335 path
= talloc_asprintf(ctx
, "C:%s", lp_path(talloc_tos(), snum
));
338 * Change / to \\ so that win2k will see it as a valid path. This was added to
339 * enable use of browsing in win2k add share dialog.
341 string_replace(path
, '/', '\\');
344 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
346 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
349 r
->type
= get_share_type(snum
);
350 r
->comment
= remark
? remark
: "";
352 r
->max_users
= (uint32_t)-1;
353 r
->current_users
= 1; /* ??? */
354 r
->path
= path
? path
: "";
359 /***************************************************************************
360 Fill in a share info level 1004 structure.
361 ***************************************************************************/
363 static void init_srv_share_info_1004(struct pipes_struct
*p
,
364 struct srvsvc_NetShareInfo1004
*r
,
367 char *remark
= lp_comment(p
->mem_ctx
, snum
);
370 remark
= talloc_sub_advanced(
371 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
372 get_current_username(), lp_path(talloc_tos(), snum
),
373 p
->session_info
->unix_token
->uid
, get_current_username(),
377 r
->comment
= remark
? remark
: "";
380 /***************************************************************************
381 Fill in a share info level 1005 structure.
382 ***************************************************************************/
384 static void init_srv_share_info_1005(struct pipes_struct
*p
,
385 struct srvsvc_NetShareInfo1005
*r
,
388 uint32_t dfs_flags
= 0;
390 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
391 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
394 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
396 r
->dfs_flags
= dfs_flags
;
399 /***************************************************************************
400 Fill in a share info level 1006 structure.
401 ***************************************************************************/
403 static void init_srv_share_info_1006(struct pipes_struct
*p
,
404 struct srvsvc_NetShareInfo1006
*r
,
407 r
->max_users
= (uint32_t)-1;
410 /***************************************************************************
411 Fill in a share info level 1007 structure.
412 ***************************************************************************/
414 static void init_srv_share_info_1007(struct pipes_struct
*p
,
415 struct srvsvc_NetShareInfo1007
*r
,
419 r
->alternate_directory_name
= "";
422 /*******************************************************************
423 Fill in a share info level 1501 structure.
424 ********************************************************************/
426 static void init_srv_share_info_1501(struct pipes_struct
*p
,
427 struct sec_desc_buf
**r
,
430 struct security_descriptor
*sd
;
431 struct sec_desc_buf
*sd_buf
= NULL
;
433 TALLOC_CTX
*ctx
= p
->mem_ctx
;
435 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
437 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
443 /*******************************************************************
444 True if it ends in '$'.
445 ********************************************************************/
447 static bool is_hidden_share(int snum
)
449 const char *net_name
= lp_servicename(talloc_tos(), snum
);
451 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
454 /*******************************************************************
455 Verify user is allowed to view share, access based enumeration
456 ********************************************************************/
457 static bool is_enumeration_allowed(struct pipes_struct
*p
,
460 if (!lp_access_based_share_enum(snum
))
463 return share_access_check(p
->session_info
->security_token
,
464 lp_servicename(talloc_tos(), snum
),
465 FILE_READ_DATA
, NULL
);
468 /****************************************************************************
469 Count an entry against the respective service.
470 ****************************************************************************/
472 static int count_for_all_fn(struct smbXsrv_tcon_global0
*tcon
, void *udp
)
474 union srvsvc_NetShareCtr
*ctr
= NULL
;
475 struct srvsvc_NetShareInfo2
*info2
= NULL
;
476 int share_entries
= 0;
479 ctr
= (union srvsvc_NetShareCtr
*) udp
;
482 share_entries
= ctr
->ctr2
->count
;
483 info2
= &ctr
->ctr2
->array
[0];
485 for (i
= 0; i
< share_entries
; i
++, info2
++) {
486 if (strequal(tcon
->share_name
, info2
->name
)) {
487 info2
->current_users
++;
495 /****************************************************************************
496 Count the entries belonging to all services in the connection db.
497 ****************************************************************************/
499 static void count_connections_for_all_shares(union srvsvc_NetShareCtr
*ctr
)
502 status
= smbXsrv_tcon_global_traverse(count_for_all_fn
, ctr
);
504 if (!NT_STATUS_IS_OK(status
)) {
505 DEBUG(0,("count_connections_for_all_shares: traverse of "
506 "smbXsrv_tcon_global.tdb failed - %s\n",
511 /*******************************************************************
512 Fill in a share info structure.
513 ********************************************************************/
515 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
516 struct srvsvc_NetShareInfoCtr
*info_ctr
,
517 uint32_t *resume_handle_p
,
518 uint32_t *total_entries
,
522 int alloc_entries
= 0;
523 int num_services
= 0;
525 TALLOC_CTX
*ctx
= p
->mem_ctx
;
527 int valid_share_count
= 0;
529 union srvsvc_NetShareCtr ctr
;
530 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
532 DEBUG(5,("init_srv_share_info_ctr\n"));
534 /* Ensure all the usershares are loaded. */
536 load_usershare_shares(NULL
, connections_snum_used
);
537 load_registry_shares();
538 num_services
= lp_numservices();
541 allowed
= talloc_zero_array(ctx
, bool, num_services
);
542 W_ERROR_HAVE_NO_MEMORY(allowed
);
544 /* Count the number of entries. */
545 for (snum
= 0; snum
< num_services
; snum
++) {
546 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
547 is_enumeration_allowed(p
, snum
) &&
548 (all_shares
|| !is_hidden_share(snum
)) ) {
549 DEBUG(10, ("counting service %s\n",
550 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
551 allowed
[snum
] = true;
554 DEBUG(10, ("NOT counting service %s\n",
555 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
559 if (!num_entries
|| (resume_handle
>= num_entries
)) {
563 /* Calculate alloc entries. */
564 alloc_entries
= num_entries
- resume_handle
;
565 switch (info_ctr
->level
) {
567 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
568 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
570 ctr
.ctr0
->count
= alloc_entries
;
571 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
572 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
574 for (snum
= 0; snum
< num_services
; snum
++) {
576 (resume_handle
<= (i
+ valid_share_count
++)) ) {
577 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
584 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
585 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
587 ctr
.ctr1
->count
= alloc_entries
;
588 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
589 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
591 for (snum
= 0; snum
< num_services
; snum
++) {
593 (resume_handle
<= (i
+ valid_share_count
++)) ) {
594 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
601 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
602 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
604 ctr
.ctr2
->count
= alloc_entries
;
605 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
606 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
608 for (snum
= 0; snum
< num_services
; snum
++) {
610 (resume_handle
<= (i
+ valid_share_count
++)) ) {
611 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
615 count_connections_for_all_shares(&ctr
);
619 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
620 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
622 ctr
.ctr501
->count
= alloc_entries
;
623 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
624 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
626 for (snum
= 0; snum
< num_services
; snum
++) {
628 (resume_handle
<= (i
+ valid_share_count
++)) ) {
629 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
636 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
637 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
639 ctr
.ctr502
->count
= alloc_entries
;
640 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
641 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
643 for (snum
= 0; snum
< num_services
; snum
++) {
645 (resume_handle
<= (i
+ valid_share_count
++)) ) {
646 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
653 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
654 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
656 ctr
.ctr1004
->count
= alloc_entries
;
657 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
658 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
660 for (snum
= 0; snum
< num_services
; snum
++) {
662 (resume_handle
<= (i
+ valid_share_count
++)) ) {
663 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
670 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
671 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
673 ctr
.ctr1005
->count
= alloc_entries
;
674 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
675 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
677 for (snum
= 0; snum
< num_services
; snum
++) {
679 (resume_handle
<= (i
+ valid_share_count
++)) ) {
680 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
687 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
688 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
690 ctr
.ctr1006
->count
= alloc_entries
;
691 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
692 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
694 for (snum
= 0; snum
< num_services
; snum
++) {
696 (resume_handle
<= (i
+ valid_share_count
++)) ) {
697 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
704 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
705 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
707 ctr
.ctr1007
->count
= alloc_entries
;
708 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
709 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
711 for (snum
= 0; snum
< num_services
; snum
++) {
713 (resume_handle
<= (i
+ valid_share_count
++)) ) {
714 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
721 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
722 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
724 ctr
.ctr1501
->count
= alloc_entries
;
725 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
726 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
728 for (snum
= 0; snum
< num_services
; snum
++) {
730 (resume_handle
<= (i
+ valid_share_count
++)) ) {
731 struct sec_desc_buf
*sd_buf
= NULL
;
732 init_srv_share_info_1501(p
, &sd_buf
, snum
);
733 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
740 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
742 return WERR_UNKNOWN_LEVEL
;
745 *total_entries
= alloc_entries
;
746 if (resume_handle_p
) {
748 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
750 *resume_handle_p
= num_entries
;
759 /*******************************************************************
760 fill in a sess info level 0 structure.
761 ********************************************************************/
763 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
764 struct srvsvc_NetSessCtr0
*ctr0
,
765 uint32_t *resume_handle_p
,
766 uint32_t *total_entries
)
768 struct sessionid
*session_list
;
769 uint32_t num_entries
= 0;
770 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
771 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
773 DEBUG(5,("init_srv_sess_info_0\n"));
776 if (resume_handle_p
) {
777 *resume_handle_p
= 0;
782 for (; resume_handle
< *total_entries
; resume_handle
++) {
784 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
786 struct srvsvc_NetSessInfo0
,
788 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
790 ctr0
->array
[num_entries
].client
=
791 session_list
[resume_handle
].remote_machine
;
796 ctr0
->count
= num_entries
;
798 if (resume_handle_p
) {
799 if (*resume_handle_p
>= *total_entries
) {
800 *resume_handle_p
= 0;
802 *resume_handle_p
= resume_handle
;
809 /***********************************************************************
810 * find out the session on which this file is open and bump up its count
811 **********************************************************************/
813 static void count_sess_files_fn(const struct share_mode_entry
*e
,
814 const char *sharepath
, const char *fname
,
817 struct sess_file_info
*info
= data
;
818 uint32_t rh
= info
->resume_handle
;
821 for (i
=0; i
< info
->num_entries
; i
++) {
822 /* rh+info->num_entries is safe, as we've
824 *total_entries > resume_handle &&
825 info->num_entries = *total_entries - resume_handle;
826 inside init_srv_sess_info_1() below.
828 struct sessionid
*sess
= &info
->session_list
[rh
+ i
];
829 if ((e
->uid
== sess
->uid
) &&
830 serverid_equal(&e
->pid
, &sess
->pid
)) {
832 info
->ctr
->array
[i
].num_open
++;
838 /*******************************************************************
839 * count the num of open files on all sessions
840 *******************************************************************/
842 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1
*ctr1
,
843 struct sessionid
*session_list
,
844 uint32_t resume_handle
,
845 uint32_t num_entries
)
847 struct sess_file_info s_file_info
;
849 s_file_info
.ctr
= ctr1
;
850 s_file_info
.session_list
= session_list
;
851 s_file_info
.resume_handle
= resume_handle
;
852 s_file_info
.num_entries
= num_entries
;
854 share_mode_forall(count_sess_files_fn
, &s_file_info
);
857 /*******************************************************************
858 fill in a sess info level 1 structure.
859 ********************************************************************/
861 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
862 struct srvsvc_NetSessCtr1
*ctr1
,
863 uint32_t *resume_handle_p
,
864 uint32_t *total_entries
)
866 struct sessionid
*session_list
;
867 uint32_t num_entries
= 0;
868 time_t now
= time(NULL
);
869 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
874 if (resume_handle_p
) {
875 *resume_handle_p
= 0;
880 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
882 if (resume_handle
>= *total_entries
) {
883 if (resume_handle_p
) {
884 *resume_handle_p
= 0;
889 /* We know num_entries must be positive, due to
890 the check resume_handle >= *total_entries above. */
892 num_entries
= *total_entries
- resume_handle
;
894 ctr1
->array
= talloc_zero_array(p
->mem_ctx
,
895 struct srvsvc_NetSessInfo1
,
898 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
900 for (num_entries
= 0; resume_handle
< *total_entries
; num_entries
++, resume_handle
++) {
904 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
905 guest
= strequal( session_list
[resume_handle
].username
, lp_guest_account() );
907 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
908 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
909 ctr1
->array
[num_entries
].num_open
= 0;/* computed later */
910 ctr1
->array
[num_entries
].time
= connect_time
;
911 ctr1
->array
[num_entries
].idle_time
= 0;
912 ctr1
->array
[num_entries
].user_flags
= guest
;
915 ctr1
->count
= num_entries
;
917 /* count open files on all sessions in single tdb traversal */
918 net_count_files_for_all_sess(ctr1
, session_list
,
919 resume_handle_p
? *resume_handle_p
: 0,
922 if (resume_handle_p
) {
923 if (*resume_handle_p
>= *total_entries
) {
924 *resume_handle_p
= 0;
926 *resume_handle_p
= resume_handle
;
933 /*******************************************************************
934 fill in a conn info level 0 structure.
935 ********************************************************************/
937 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
938 uint32_t *resume_handle_p
,
939 uint32_t *total_entries
)
941 uint32_t num_entries
= 0;
942 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
944 DEBUG(5,("init_srv_conn_info_0\n"));
947 if (resume_handle_p
) {
948 *resume_handle_p
= 0;
957 for (; resume_handle
< *total_entries
; resume_handle
++) {
959 ctr0
->array
= talloc_realloc(talloc_tos(),
961 struct srvsvc_NetConnInfo0
,
967 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
969 /* move on to creating next connection */
973 ctr0
->count
= num_entries
;
974 *total_entries
= num_entries
;
976 if (resume_handle_p
) {
977 if (*resume_handle_p
>= *total_entries
) {
978 *resume_handle_p
= 0;
980 *resume_handle_p
= resume_handle
;
987 /*******************************************************************
988 fill in a conn info level 1 structure.
989 ********************************************************************/
991 static WERROR
init_srv_conn_info_1(struct srvsvc_NetConnCtr1
*ctr1
,
992 uint32_t *resume_handle_p
,
993 uint32_t *total_entries
)
995 uint32_t num_entries
= 0;
996 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
998 DEBUG(5,("init_srv_conn_info_1\n"));
1001 if (resume_handle_p
) {
1002 *resume_handle_p
= 0;
1011 for (; resume_handle
< *total_entries
; resume_handle
++) {
1013 ctr1
->array
= talloc_realloc(talloc_tos(),
1015 struct srvsvc_NetConnInfo1
,
1021 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1022 ctr1
->array
[num_entries
].conn_type
= 0x3;
1023 ctr1
->array
[num_entries
].num_open
= 1;
1024 ctr1
->array
[num_entries
].num_users
= 1;
1025 ctr1
->array
[num_entries
].conn_time
= 3;
1026 ctr1
->array
[num_entries
].user
= "dummy_user";
1027 ctr1
->array
[num_entries
].share
= "IPC$";
1029 /* move on to creating next connection */
1033 ctr1
->count
= num_entries
;
1034 *total_entries
= num_entries
;
1036 if (resume_handle_p
) {
1037 if (*resume_handle_p
>= *total_entries
) {
1038 *resume_handle_p
= 0;
1040 *resume_handle_p
= resume_handle
;
1047 /*******************************************************************
1049 *******************************************************************/
1051 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1052 struct srvsvc_NetFileEnum
*r
)
1054 TALLOC_CTX
*ctx
= NULL
;
1055 struct srvsvc_NetFileCtr3
*ctr3
;
1056 uint32_t resume_hnd
= 0;
1059 switch (r
->in
.info_ctr
->level
) {
1063 return WERR_UNKNOWN_LEVEL
;
1066 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1067 p
->session_info
->security_token
)) {
1068 DEBUG(1, ("Enumerating files only allowed for "
1069 "administrators\n"));
1070 return WERR_ACCESS_DENIED
;
1074 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1076 werr
= WERR_INVALID_PARAM
;
1080 /* TODO -- Windows enumerates
1082 (c) open directories and files */
1084 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1085 if (!W_ERROR_IS_OK(werr
)) {
1089 *r
->out
.totalentries
= ctr3
->count
;
1090 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1091 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1099 /*******************************************************************
1100 _srvsvc_NetSrvGetInfo
1101 ********************************************************************/
1103 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1104 struct srvsvc_NetSrvGetInfo
*r
)
1106 WERROR status
= WERR_OK
;
1108 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1110 if (!pipe_access_check(p
)) {
1111 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1112 return WERR_ACCESS_DENIED
;
1115 switch (r
->in
.level
) {
1117 /* Technically level 102 should only be available to
1118 Administrators but there isn't anything super-secret
1119 here, as most of it is made up. */
1122 struct srvsvc_NetSrvInfo102
*info102
;
1124 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1129 info102
->platform_id
= PLATFORM_ID_NT
;
1130 info102
->server_name
= lp_netbios_name();
1131 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1132 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1133 info102
->server_type
= lp_default_server_announce();
1134 info102
->comment
= string_truncate(lp_server_string(talloc_tos()),
1135 MAX_SERVER_STRING_LENGTH
);
1136 info102
->users
= 0xffffffff;
1137 info102
->disc
= 0xf;
1138 info102
->hidden
= 0;
1139 info102
->announce
= 240;
1140 info102
->anndelta
= 3000;
1141 info102
->licenses
= 100000;
1142 info102
->userpath
= "C:\\";
1144 r
->out
.info
->info102
= info102
;
1148 struct srvsvc_NetSrvInfo101
*info101
;
1150 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1155 info101
->platform_id
= PLATFORM_ID_NT
;
1156 info101
->server_name
= lp_netbios_name();
1157 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1158 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1159 info101
->server_type
= lp_default_server_announce();
1160 info101
->comment
= string_truncate(lp_server_string(talloc_tos()),
1161 MAX_SERVER_STRING_LENGTH
);
1163 r
->out
.info
->info101
= info101
;
1167 struct srvsvc_NetSrvInfo100
*info100
;
1169 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1174 info100
->platform_id
= PLATFORM_ID_NT
;
1175 info100
->server_name
= lp_netbios_name();
1177 r
->out
.info
->info100
= info100
;
1182 status
= WERR_UNKNOWN_LEVEL
;
1186 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1191 /*******************************************************************
1192 _srvsvc_NetSrvSetInfo
1193 ********************************************************************/
1195 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1196 struct srvsvc_NetSrvSetInfo
*r
)
1198 WERROR status
= WERR_OK
;
1200 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1202 /* Set up the net server set info structure. */
1204 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1209 /*******************************************************************
1211 ********************************************************************/
1213 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1214 struct srvsvc_NetConnEnum
*r
)
1218 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1220 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1221 p
->session_info
->security_token
)) {
1222 DEBUG(1, ("Enumerating connections only allowed for "
1223 "administrators\n"));
1224 return WERR_ACCESS_DENIED
;
1227 switch (r
->in
.info_ctr
->level
) {
1229 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1230 r
->in
.resume_handle
,
1231 r
->out
.totalentries
);
1234 werr
= init_srv_conn_info_1(r
->in
.info_ctr
->ctr
.ctr1
,
1235 r
->in
.resume_handle
,
1236 r
->out
.totalentries
);
1239 return WERR_UNKNOWN_LEVEL
;
1242 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1247 /*******************************************************************
1249 ********************************************************************/
1251 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1252 struct srvsvc_NetSessEnum
*r
)
1256 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1258 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1259 p
->session_info
->security_token
)) {
1260 DEBUG(1, ("Enumerating sessions only allowed for "
1261 "administrators\n"));
1262 return WERR_ACCESS_DENIED
;
1265 switch (r
->in
.info_ctr
->level
) {
1267 werr
= init_srv_sess_info_0(p
,
1268 r
->in
.info_ctr
->ctr
.ctr0
,
1269 r
->in
.resume_handle
,
1270 r
->out
.totalentries
);
1273 werr
= init_srv_sess_info_1(p
,
1274 r
->in
.info_ctr
->ctr
.ctr1
,
1275 r
->in
.resume_handle
,
1276 r
->out
.totalentries
);
1279 return WERR_UNKNOWN_LEVEL
;
1282 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1287 /*******************************************************************
1289 ********************************************************************/
1291 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1292 struct srvsvc_NetSessDel
*r
)
1294 struct sessionid
*session_list
;
1295 int num_sessions
, snum
;
1296 const char *username
;
1297 const char *machine
;
1298 bool not_root
= False
;
1301 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1303 werr
= WERR_ACCESS_DENIED
;
1305 /* fail out now if you are not root or not a domain admin */
1307 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1308 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1309 DOMAIN_RID_ADMINS
))) {
1314 username
= r
->in
.user
;
1315 machine
= r
->in
.client
;
1317 /* strip leading backslashes if any */
1318 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1322 num_sessions
= find_sessions(p
->mem_ctx
, username
, machine
,
1325 for (snum
= 0; snum
< num_sessions
; snum
++) {
1329 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1334 ntstat
= messaging_send(p
->msg_ctx
,
1335 session_list
[snum
].pid
,
1336 MSG_SHUTDOWN
, &data_blob_null
);
1338 if (NT_STATUS_IS_OK(ntstat
))
1345 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1352 /*******************************************************************
1353 _srvsvc_NetShareEnumAll
1354 ********************************************************************/
1356 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1357 struct srvsvc_NetShareEnumAll
*r
)
1361 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1363 if (!pipe_access_check(p
)) {
1364 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1365 return WERR_ACCESS_DENIED
;
1368 /* Create the list of shares for the response. */
1369 werr
= init_srv_share_info_ctr(p
,
1371 r
->in
.resume_handle
,
1372 r
->out
.totalentries
,
1375 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1380 /*******************************************************************
1381 _srvsvc_NetShareEnum
1382 ********************************************************************/
1384 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1385 struct srvsvc_NetShareEnum
*r
)
1389 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1391 if (!pipe_access_check(p
)) {
1392 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1393 return WERR_ACCESS_DENIED
;
1396 /* Create the list of shares for the response. */
1397 werr
= init_srv_share_info_ctr(p
,
1399 r
->in
.resume_handle
,
1400 r
->out
.totalentries
,
1403 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1408 /*******************************************************************
1409 _srvsvc_NetShareGetInfo
1410 ********************************************************************/
1412 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1413 struct srvsvc_NetShareGetInfo
*r
)
1415 WERROR status
= WERR_OK
;
1416 char *share_name
= NULL
;
1418 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1420 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1422 if (!r
->in
.share_name
) {
1423 return WERR_INVALID_NAME
;
1426 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1431 return WERR_INVALID_NAME
;
1434 switch (r
->in
.level
) {
1436 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1437 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1438 init_srv_share_info_0(p
, info
->info0
, snum
);
1441 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1442 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1443 init_srv_share_info_1(p
, info
->info1
, snum
);
1446 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1447 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1448 init_srv_share_info_2(p
, info
->info2
, snum
);
1449 info
->info2
->current_users
=
1450 count_current_connections(info
->info2
->name
, false);
1453 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1454 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1455 init_srv_share_info_501(p
, info
->info501
, snum
);
1458 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1459 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1460 init_srv_share_info_502(p
, info
->info502
, snum
);
1463 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1464 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1465 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1468 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1469 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1470 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1473 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1474 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1475 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1478 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1479 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1480 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1483 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1486 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1488 status
= WERR_UNKNOWN_LEVEL
;
1492 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1497 /*******************************************************************
1498 _srvsvc_NetShareSetInfo. Modify share details.
1499 ********************************************************************/
1501 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1502 struct srvsvc_NetShareSetInfo
*r
)
1504 char *command
= NULL
;
1505 char *share_name
= NULL
;
1506 char *comment
= NULL
;
1507 const char *pathname
= NULL
;
1512 struct security_descriptor
*psd
= NULL
;
1513 bool is_disk_op
= False
;
1514 const char *csc_policy
= NULL
;
1515 bool csc_policy_changed
= false;
1516 const char *csc_policies
[] = {"manual", "documents", "programs",
1518 uint32_t client_csc_policy
;
1519 int max_connections
= 0;
1520 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1521 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1523 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1525 if (!r
->in
.share_name
) {
1526 return WERR_INVALID_NAME
;
1529 if (r
->out
.parm_error
) {
1530 *r
->out
.parm_error
= 0;
1533 if ( strequal(r
->in
.share_name
,"IPC$")
1534 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1535 || strequal(r
->in
.share_name
,"global") )
1537 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1538 "modified by a remote user.\n",
1539 r
->in
.share_name
));
1540 return WERR_ACCESS_DENIED
;
1543 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1548 /* Does this share exist ? */
1550 return WERR_NET_NAME_NOT_FOUND
;
1552 /* No change to printer shares. */
1553 if (lp_printable(snum
))
1554 return WERR_ACCESS_DENIED
;
1556 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1558 /* fail out now if you are not root and not a disk op */
1560 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1561 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1562 "SeDiskOperatorPrivilege privilege needed to modify "
1564 (unsigned int)p
->session_info
->unix_token
->uid
,
1566 return WERR_ACCESS_DENIED
;
1569 max_connections
= lp_max_connections(snum
);
1570 csc_policy
= csc_policies
[lp_csc_policy(snum
)];
1572 switch (r
->in
.level
) {
1574 pathname
= lp_path(ctx
, snum
);
1575 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1576 type
= info
->info1
->type
;
1580 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1581 pathname
= info
->info2
->path
;
1582 type
= info
->info2
->type
;
1583 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1584 0 : info
->info2
->max_users
;
1588 /* not supported on set but here for completeness */
1590 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1591 type
= info
->info501
->type
;
1596 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1597 pathname
= info
->info502
->path
;
1598 type
= info
->info502
->type
;
1599 psd
= info
->info502
->sd_buf
.sd
;
1600 map_generic_share_sd_bits(psd
);
1603 pathname
= lp_path(ctx
, snum
);
1604 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1605 type
= STYPE_DISKTREE
;
1608 /* XP re-sets the csc policy even if it wasn't changed by the
1609 user, so we must compare it to see if it's what is set in
1610 smb.conf, so that we can contine other ops like setting
1612 client_csc_policy
= (info
->info1005
->dfs_flags
&
1613 SHARE_1005_CSC_POLICY_MASK
) >>
1614 SHARE_1005_CSC_POLICY_SHIFT
;
1616 if (client_csc_policy
== lp_csc_policy(snum
))
1619 csc_policy
= csc_policies
[client_csc_policy
];
1620 csc_policy_changed
= true;
1623 pathname
= lp_path(ctx
, snum
);
1624 comment
= lp_comment(ctx
, snum
);
1625 type
= STYPE_DISKTREE
;
1629 return WERR_ACCESS_DENIED
;
1631 pathname
= lp_path(ctx
, snum
);
1632 comment
= lp_comment(ctx
, snum
);
1633 psd
= info
->info1501
->sd
;
1634 map_generic_share_sd_bits(psd
);
1635 type
= STYPE_DISKTREE
;
1638 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1640 return WERR_UNKNOWN_LEVEL
;
1643 /* We can only modify disk shares. */
1644 if (type
!= STYPE_DISKTREE
) {
1645 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1648 return WERR_ACCESS_DENIED
;
1651 if (comment
== NULL
) {
1655 /* Check if the pathname is valid. */
1656 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1657 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1659 return WERR_OBJECT_PATH_INVALID
;
1662 /* Ensure share name, pathname and comment don't contain '"' characters. */
1663 string_replace(share_name
, '"', ' ');
1664 string_replace(path
, '"', ' ');
1665 string_replace(comment
, '"', ' ');
1667 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1668 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1670 /* Only call modify function if something changed. */
1672 if (strcmp(path
, lp_path(talloc_tos(), snum
)) || strcmp(comment
, lp_comment(talloc_tos(), snum
))
1673 || (lp_max_connections(snum
) != max_connections
)
1674 || csc_policy_changed
) {
1676 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1677 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1678 return WERR_ACCESS_DENIED
;
1681 command
= talloc_asprintf(p
->mem_ctx
,
1682 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1683 lp_change_share_command(talloc_tos()),
1684 get_dyn_CONFIGFILE(),
1687 comment
? comment
: "",
1694 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1696 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1701 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1702 /* Tell everyone we updated smb.conf. */
1703 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1710 /********* END SeDiskOperatorPrivilege BLOCK *********/
1712 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1715 TALLOC_FREE(command
);
1718 return WERR_ACCESS_DENIED
;
1720 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1724 /* Replace SD if changed. */
1726 struct security_descriptor
*old_sd
;
1729 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
1731 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1732 if (!set_share_security(share_name
, psd
))
1733 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1738 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1743 /*******************************************************************
1744 _srvsvc_NetShareAdd.
1745 Call 'add_share_command "sharename" "pathname"
1746 "comment" "max connections = "
1747 ********************************************************************/
1749 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1750 struct srvsvc_NetShareAdd
*r
)
1752 char *command
= NULL
;
1753 char *share_name_in
= NULL
;
1754 char *share_name
= NULL
;
1755 char *comment
= NULL
;
1756 char *pathname
= NULL
;
1761 struct security_descriptor
*psd
= NULL
;
1763 int max_connections
= 0;
1764 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1766 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1768 if (r
->out
.parm_error
) {
1769 *r
->out
.parm_error
= 0;
1772 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1774 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1775 return WERR_ACCESS_DENIED
;
1777 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1778 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1779 return WERR_ACCESS_DENIED
;
1782 switch (r
->in
.level
) {
1784 /* No path. Not enough info in a level 0 to do anything. */
1785 return WERR_ACCESS_DENIED
;
1787 /* Not enough info in a level 1 to do anything. */
1788 return WERR_ACCESS_DENIED
;
1790 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1791 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1792 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1793 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1794 0 : r
->in
.info
->info2
->max_users
;
1795 type
= r
->in
.info
->info2
->type
;
1798 /* No path. Not enough info in a level 501 to do anything. */
1799 return WERR_ACCESS_DENIED
;
1801 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1802 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1803 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1804 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1805 0 : r
->in
.info
->info502
->max_users
;
1806 type
= r
->in
.info
->info502
->type
;
1807 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1808 map_generic_share_sd_bits(psd
);
1811 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1817 return WERR_ACCESS_DENIED
;
1819 /* DFS only level. */
1820 return WERR_ACCESS_DENIED
;
1822 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1824 return WERR_UNKNOWN_LEVEL
;
1827 /* check for invalid share names */
1829 if (!share_name_in
|| !validate_net_name(share_name_in
,
1830 INVALID_SHARENAME_CHARS
,
1831 strlen(share_name_in
))) {
1832 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1833 share_name_in
? share_name_in
: ""));
1834 return WERR_INVALID_NAME
;
1837 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
1838 || (lp_enable_asu_support() &&
1839 strequal(share_name_in
,"ADMIN$"))) {
1840 return WERR_ACCESS_DENIED
;
1843 snum
= find_service(ctx
, share_name_in
, &share_name
);
1848 /* Share already exists. */
1850 return WERR_FILE_EXISTS
;
1853 /* We can only add disk shares. */
1854 if (type
!= STYPE_DISKTREE
) {
1855 return WERR_ACCESS_DENIED
;
1858 /* Check if the pathname is valid. */
1859 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1860 return WERR_OBJECT_PATH_INVALID
;
1863 /* Ensure share name, pathname and comment don't contain '"' characters. */
1864 string_replace(share_name_in
, '"', ' ');
1865 string_replace(share_name
, '"', ' ');
1866 string_replace(path
, '"', ' ');
1868 string_replace(comment
, '"', ' ');
1871 command
= talloc_asprintf(ctx
,
1872 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1873 lp_add_share_command(talloc_tos()),
1874 get_dyn_CONFIGFILE(),
1877 comment
? comment
: "",
1883 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
1885 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1890 /* FIXME: use libnetconf here - gd */
1892 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1893 /* Tell everyone we updated smb.conf. */
1894 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
1901 /********* END SeDiskOperatorPrivilege BLOCK *********/
1903 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1906 TALLOC_FREE(command
);
1909 return WERR_ACCESS_DENIED
;
1912 /* Note we use share_name here, not share_name_in as
1913 we need a canonicalized name for setting security. */
1914 if (!set_share_security(share_name
, psd
)) {
1915 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1921 * We don't call reload_services() here, the message will
1922 * cause this to be done before the next packet is read
1923 * from the client. JRA.
1926 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1931 /*******************************************************************
1933 Call "delete share command" with the share name as
1935 ********************************************************************/
1937 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
1938 struct srvsvc_NetShareDel
*r
)
1940 char *command
= NULL
;
1941 char *share_name
= NULL
;
1945 struct share_params
*params
;
1946 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1948 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
1950 if (!r
->in
.share_name
) {
1951 return WERR_NET_NAME_NOT_FOUND
;
1954 if ( strequal(r
->in
.share_name
,"IPC$")
1955 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1956 || strequal(r
->in
.share_name
,"global") )
1958 return WERR_ACCESS_DENIED
;
1961 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1967 return WERR_NO_SUCH_SHARE
;
1970 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
1971 return WERR_NO_SUCH_SHARE
;
1974 /* No change to printer shares. */
1975 if (lp_printable(snum
))
1976 return WERR_ACCESS_DENIED
;
1978 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1980 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1981 return WERR_ACCESS_DENIED
;
1983 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
1984 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1985 return WERR_ACCESS_DENIED
;
1988 command
= talloc_asprintf(ctx
,
1990 lp_delete_share_command(talloc_tos()),
1991 get_dyn_CONFIGFILE(),
1992 lp_servicename(talloc_tos(), snum
));
1997 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
1999 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2004 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2005 /* Tell everyone we updated smb.conf. */
2006 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2013 /********* END SeDiskOperatorPrivilege BLOCK *********/
2015 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2018 return WERR_ACCESS_DENIED
;
2020 /* Delete the SD in the database. */
2021 delete_share_security(lp_servicename(talloc_tos(), params
->service
));
2023 lp_killservice(params
->service
);
2028 /*******************************************************************
2029 _srvsvc_NetShareDelSticky
2030 ********************************************************************/
2032 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2033 struct srvsvc_NetShareDelSticky
*r
)
2035 struct srvsvc_NetShareDel q
;
2037 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2039 q
.in
.server_unc
= r
->in
.server_unc
;
2040 q
.in
.share_name
= r
->in
.share_name
;
2041 q
.in
.reserved
= r
->in
.reserved
;
2043 return _srvsvc_NetShareDel(p
, &q
);
2046 /*******************************************************************
2047 _srvsvc_NetRemoteTOD
2048 ********************************************************************/
2050 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2051 struct srvsvc_NetRemoteTOD
*r
)
2053 struct srvsvc_NetRemoteTODInfo
*tod
;
2055 time_t unixdate
= time(NULL
);
2057 /* We do this call first as if we do it *after* the gmtime call
2058 it overwrites the pointed-to values. JRA */
2060 uint32 zone
= get_time_zone(unixdate
)/60;
2062 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2064 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2069 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2071 t
= gmtime(&unixdate
);
2074 tod
->elapsed
= unixdate
;
2076 tod
->hours
= t
->tm_hour
;
2077 tod
->mins
= t
->tm_min
;
2078 tod
->secs
= t
->tm_sec
;
2080 tod
->timezone
= zone
;
2081 tod
->tinterval
= 10000;
2082 tod
->day
= t
->tm_mday
;
2083 tod
->month
= t
->tm_mon
+ 1;
2084 tod
->year
= 1900+t
->tm_year
;
2085 tod
->weekday
= t
->tm_wday
;
2087 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2092 /***********************************************************************************
2093 _srvsvc_NetGetFileSecurity
2094 Win9x NT tools get security descriptor.
2095 ***********************************************************************************/
2097 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2098 struct srvsvc_NetGetFileSecurity
*r
)
2100 struct smb_filename
*smb_fname
= NULL
;
2102 char *servicename
= NULL
;
2106 connection_struct
*conn
= NULL
;
2107 struct sec_desc_buf
*sd_buf
= NULL
;
2108 files_struct
*fsp
= NULL
;
2110 char *oldcwd
= NULL
;
2115 werr
= WERR_NET_NAME_NOT_FOUND
;
2118 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2124 DEBUG(10, ("Could not find service %s\n", servicename
));
2125 werr
= WERR_NET_NAME_NOT_FOUND
;
2129 nt_status
= create_conn_struct_cwd(talloc_tos(),
2130 server_event_context(),
2131 server_messaging_context(),
2133 snum
, lp_path(talloc_tos(), snum
),
2134 p
->session_info
, &oldcwd
);
2135 if (!NT_STATUS_IS_OK(nt_status
)) {
2136 DEBUG(10, ("create_conn_struct failed: %s\n",
2137 nt_errstr(nt_status
)));
2138 werr
= ntstatus_to_werror(nt_status
);
2142 nt_status
= filename_convert(talloc_tos(),
2149 if (!NT_STATUS_IS_OK(nt_status
)) {
2150 werr
= ntstatus_to_werror(nt_status
);
2154 nt_status
= SMB_VFS_CREATE_FILE(
2157 0, /* root_dir_fid */
2158 smb_fname
, /* fname */
2159 FILE_READ_ATTRIBUTES
, /* access_mask */
2160 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2161 FILE_OPEN
, /* create_disposition*/
2162 0, /* create_options */
2163 0, /* file_attributes */
2164 INTERNAL_OPEN_ONLY
, /* oplock_request */
2165 0, /* allocation_size */
2166 0, /* private_flags */
2172 if (!NT_STATUS_IS_OK(nt_status
)) {
2173 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2174 smb_fname_str_dbg(smb_fname
)));
2175 werr
= ntstatus_to_werror(nt_status
);
2179 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2185 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2188 |SECINFO_DACL
), sd_buf
, &sd_buf
->sd
);
2190 if (!NT_STATUS_IS_OK(nt_status
)) {
2191 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2192 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2193 werr
= ntstatus_to_werror(nt_status
);
2194 TALLOC_FREE(sd_buf
);
2198 if (sd_buf
->sd
->dacl
) {
2199 sd_buf
->sd
->dacl
->revision
= NT4_ACL_REVISION
;
2202 sd_size
= ndr_size_security_descriptor(sd_buf
->sd
, 0);
2204 sd_buf
->sd_size
= sd_size
;
2206 *r
->out
.sd_buf
= sd_buf
;
2208 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2209 vfs_ChDir(conn
, oldcwd
);
2210 SMB_VFS_DISCONNECT(conn
);
2218 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2222 vfs_ChDir(conn
, oldcwd
);
2226 SMB_VFS_DISCONNECT(conn
);
2232 TALLOC_FREE(smb_fname
);
2237 /***********************************************************************************
2238 _srvsvc_NetSetFileSecurity
2239 Win9x NT tools set security descriptor.
2240 ***********************************************************************************/
2242 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2243 struct srvsvc_NetSetFileSecurity
*r
)
2245 struct smb_filename
*smb_fname
= NULL
;
2246 char *servicename
= NULL
;
2247 files_struct
*fsp
= NULL
;
2251 connection_struct
*conn
= NULL
;
2253 char *oldcwd
= NULL
;
2254 struct security_descriptor
*psd
= NULL
;
2255 uint32_t security_info_sent
= 0;
2260 werr
= WERR_NET_NAME_NOT_FOUND
;
2264 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2271 DEBUG(10, ("Could not find service %s\n", servicename
));
2272 werr
= WERR_NET_NAME_NOT_FOUND
;
2276 nt_status
= create_conn_struct_cwd(talloc_tos(),
2277 server_event_context(),
2278 server_messaging_context(),
2280 snum
, lp_path(talloc_tos(), snum
),
2281 p
->session_info
, &oldcwd
);
2282 if (!NT_STATUS_IS_OK(nt_status
)) {
2283 DEBUG(10, ("create_conn_struct failed: %s\n",
2284 nt_errstr(nt_status
)));
2285 werr
= ntstatus_to_werror(nt_status
);
2289 nt_status
= filename_convert(talloc_tos(),
2296 if (!NT_STATUS_IS_OK(nt_status
)) {
2297 werr
= ntstatus_to_werror(nt_status
);
2301 nt_status
= SMB_VFS_CREATE_FILE(
2304 0, /* root_dir_fid */
2305 smb_fname
, /* fname */
2306 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2307 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2308 FILE_OPEN
, /* create_disposition*/
2309 0, /* create_options */
2310 0, /* file_attributes */
2311 INTERNAL_OPEN_ONLY
, /* oplock_request */
2312 0, /* allocation_size */
2313 0, /* private_flags */
2319 if (!NT_STATUS_IS_OK(nt_status
)) {
2320 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2321 smb_fname_str_dbg(smb_fname
)));
2322 werr
= ntstatus_to_werror(nt_status
);
2326 psd
= r
->in
.sd_buf
->sd
;
2327 security_info_sent
= r
->in
.securityinformation
;
2329 nt_status
= set_sd(fsp
, psd
, security_info_sent
);
2331 if (!NT_STATUS_IS_OK(nt_status
) ) {
2332 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2333 "on file %s\n", r
->in
.share
));
2334 werr
= WERR_ACCESS_DENIED
;
2338 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2339 vfs_ChDir(conn
, oldcwd
);
2340 SMB_VFS_DISCONNECT(conn
);
2348 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2352 vfs_ChDir(conn
, oldcwd
);
2356 SMB_VFS_DISCONNECT(conn
);
2361 TALLOC_FREE(smb_fname
);
2366 /***********************************************************************************
2367 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2368 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2369 These disks would the disks listed by this function.
2370 Users could then create shares relative to these disks. Watch out for moving these disks around.
2371 "Nigel Williams" <nigel@veritas.com>.
2372 ***********************************************************************************/
2374 static const char *server_disks
[] = {"C:"};
2376 static uint32
get_server_disk_count(void)
2378 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2381 static uint32
init_server_disk_enum(uint32
*resume
)
2383 uint32 server_disk_count
= get_server_disk_count();
2385 /*resume can be an offset into the list for now*/
2387 if(*resume
& 0x80000000)
2390 if(*resume
> server_disk_count
)
2391 *resume
= server_disk_count
;
2393 return server_disk_count
- *resume
;
2396 static const char *next_server_disk_enum(uint32
*resume
)
2400 if(init_server_disk_enum(resume
) == 0)
2403 disk
= server_disks
[*resume
];
2407 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2412 /********************************************************************
2414 ********************************************************************/
2416 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2417 struct srvsvc_NetDiskEnum
*r
)
2420 const char *disk_name
;
2421 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2423 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2427 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2429 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2430 MAX_SERVER_DISK_ENTRIES
);
2431 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2433 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2435 r
->out
.info
->count
= 0;
2437 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2439 r
->out
.info
->count
++;
2441 /*copy disk name into a unicode string*/
2443 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2444 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2447 /* add a terminating null string. Is this there if there is more data to come? */
2449 r
->out
.info
->count
++;
2451 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2452 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2454 if (r
->out
.resume_handle
) {
2455 *r
->out
.resume_handle
= resume
;
2461 /********************************************************************
2462 _srvsvc_NetNameValidate
2463 ********************************************************************/
2465 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2466 struct srvsvc_NetNameValidate
*r
)
2468 switch (r
->in
.name_type
) {
2470 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2471 strlen_m(r
->in
.name
)))
2473 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2475 return WERR_INVALID_NAME
;
2480 return WERR_UNKNOWN_LEVEL
;
2486 /*******************************************************************
2487 ********************************************************************/
2489 struct enum_file_close_state
{
2490 struct srvsvc_NetFileClose
*r
;
2491 struct messaging_context
*msg_ctx
;
2494 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2495 const char *sharepath
, const char *fname
,
2496 void *private_data
)
2498 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2499 struct enum_file_close_state
*state
=
2500 (struct enum_file_close_state
*)private_data
;
2501 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2503 if (fid
!= state
->r
->in
.fid
) {
2504 return; /* Not this file. */
2507 if (!process_exists(e
->pid
) ) {
2511 /* Ok - send the close message. */
2512 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2514 share_mode_str(talloc_tos(), 0, e
) ));
2516 share_mode_entry_to_message(msg
, e
);
2518 state
->r
->out
.result
= ntstatus_to_werror(
2519 messaging_send_buf(state
->msg_ctx
,
2520 e
->pid
, MSG_SMB_CLOSE_FILE
,
2521 (uint8
*)msg
, sizeof(msg
)));
2524 /********************************************************************
2525 Close a file given a 32-bit file id.
2526 ********************************************************************/
2528 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2529 struct srvsvc_NetFileClose
*r
)
2531 struct enum_file_close_state state
;
2534 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2536 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2538 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2539 return WERR_ACCESS_DENIED
;
2542 /* enum_file_close_fn sends the close message to
2543 * the relevant smbd process. */
2545 r
->out
.result
= WERR_BADFILE
;
2547 state
.msg_ctx
= p
->msg_ctx
;
2548 share_mode_forall(enum_file_close_fn
, &state
);
2549 return r
->out
.result
;
2552 /********************************************************************
2553 ********************************************************************/
2555 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2556 struct srvsvc_NetCharDevEnum
*r
)
2558 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2559 return WERR_NOT_SUPPORTED
;
2562 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2563 struct srvsvc_NetCharDevGetInfo
*r
)
2565 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2566 return WERR_NOT_SUPPORTED
;
2569 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2570 struct srvsvc_NetCharDevControl
*r
)
2572 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2573 return WERR_NOT_SUPPORTED
;
2576 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2577 struct srvsvc_NetCharDevQEnum
*r
)
2579 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2580 return WERR_NOT_SUPPORTED
;
2583 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2584 struct srvsvc_NetCharDevQGetInfo
*r
)
2586 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2587 return WERR_NOT_SUPPORTED
;
2590 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2591 struct srvsvc_NetCharDevQSetInfo
*r
)
2593 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2594 return WERR_NOT_SUPPORTED
;
2597 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2598 struct srvsvc_NetCharDevQPurge
*r
)
2600 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2601 return WERR_NOT_SUPPORTED
;
2604 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2605 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2607 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2608 return WERR_NOT_SUPPORTED
;
2611 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2612 struct srvsvc_NetFileGetInfo
*r
)
2614 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2615 return WERR_NOT_SUPPORTED
;
2618 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2619 struct srvsvc_NetShareCheck
*r
)
2621 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2622 return WERR_NOT_SUPPORTED
;
2625 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2626 struct srvsvc_NetServerStatisticsGet
*r
)
2628 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2629 return WERR_NOT_SUPPORTED
;
2632 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2633 struct srvsvc_NetTransportAdd
*r
)
2635 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2636 return WERR_NOT_SUPPORTED
;
2639 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2640 struct srvsvc_NetTransportEnum
*r
)
2642 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2643 return WERR_NOT_SUPPORTED
;
2646 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2647 struct srvsvc_NetTransportDel
*r
)
2649 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2650 return WERR_NOT_SUPPORTED
;
2653 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2654 struct srvsvc_NetSetServiceBits
*r
)
2656 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2657 return WERR_NOT_SUPPORTED
;
2660 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2661 struct srvsvc_NetPathType
*r
)
2663 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2664 return WERR_NOT_SUPPORTED
;
2667 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2668 struct srvsvc_NetPathCanonicalize
*r
)
2670 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2671 return WERR_NOT_SUPPORTED
;
2674 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2675 struct srvsvc_NetPathCompare
*r
)
2677 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2678 return WERR_NOT_SUPPORTED
;
2681 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2682 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2684 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2685 return WERR_NOT_SUPPORTED
;
2688 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2689 struct srvsvc_NetPRNameCompare
*r
)
2691 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2692 return WERR_NOT_SUPPORTED
;
2695 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2696 struct srvsvc_NetShareDelStart
*r
)
2698 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2699 return WERR_NOT_SUPPORTED
;
2702 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2703 struct srvsvc_NetShareDelCommit
*r
)
2705 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2706 return WERR_NOT_SUPPORTED
;
2709 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2710 struct srvsvc_NetServerTransportAddEx
*r
)
2712 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2713 return WERR_NOT_SUPPORTED
;
2716 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2717 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2719 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2720 return WERR_NOT_SUPPORTED
;
2723 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2724 struct srvsvc_NETRDFSGETVERSION
*r
)
2726 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2727 return WERR_NOT_SUPPORTED
;
2730 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2731 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2733 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2734 return WERR_NOT_SUPPORTED
;
2737 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2738 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2740 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2741 return WERR_NOT_SUPPORTED
;
2744 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2745 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2747 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2748 return WERR_NOT_SUPPORTED
;
2751 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2752 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2754 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2755 return WERR_NOT_SUPPORTED
;
2758 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2759 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2761 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2762 return WERR_NOT_SUPPORTED
;
2765 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2766 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2768 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2769 return WERR_NOT_SUPPORTED
;
2772 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2773 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2775 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2776 return WERR_NOT_SUPPORTED
;
2779 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2780 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2782 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2783 return WERR_NOT_SUPPORTED
;
2786 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2787 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2789 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2790 return WERR_NOT_SUPPORTED
;
2793 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2794 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2796 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2797 return WERR_NOT_SUPPORTED
;