2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Guenther Deschner 2008.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
27 #include "system/passwd.h"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping
;
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count
{
54 struct srvsvc_NetFileCtr3
*ctr3
;
57 struct sess_file_count
{
63 /* Used to store pipe open records for NetFileEnum() */
65 struct pipe_open_rec
{
72 /****************************************************************************
73 Count the entries belonging to a service in the connection db.
74 ****************************************************************************/
76 static int pipe_enum_fn( struct db_record
*rec
, void *p
)
78 struct pipe_open_rec prec
;
79 struct file_enum_count
*fenum
= (struct file_enum_count
*)p
;
80 struct srvsvc_NetFileInfo3
*f
;
81 int i
= fenum
->ctr3
->count
;
82 char *fullpath
= NULL
;
86 value
= dbwrap_record_get_value(rec
);
88 if (value
.dsize
!= sizeof(struct pipe_open_rec
))
91 memcpy(&prec
, value
.dptr
, sizeof(struct pipe_open_rec
));
93 if ( !process_exists(prec
.pid
) ) {
97 username
= uidtoname(prec
.uid
);
99 if ((fenum
->username
!= NULL
)
100 && !strequal(username
, fenum
->username
)) {
104 fullpath
= talloc_asprintf(fenum
->ctx
, "\\PIPE\\%s", prec
.name
);
109 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
110 struct srvsvc_NetFileInfo3
, i
+1);
112 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
115 fenum
->ctr3
->array
= f
;
117 fenum
->ctr3
->array
[i
].fid
=
118 (((uint32_t)(procid_to_pid(&prec
.pid
))<<16) | prec
.pnum
);
119 fenum
->ctr3
->array
[i
].permissions
=
120 (FILE_READ_DATA
|FILE_WRITE_DATA
);
121 fenum
->ctr3
->array
[i
].num_locks
= 0;
122 fenum
->ctr3
->array
[i
].path
= fullpath
;
123 fenum
->ctr3
->array
[i
].user
= username
;
125 fenum
->ctr3
->count
++;
130 /*******************************************************************
131 ********************************************************************/
133 static WERROR
net_enum_pipes(TALLOC_CTX
*ctx
,
134 const char *username
,
135 struct srvsvc_NetFileCtr3
**ctr3
,
138 struct file_enum_count fenum
;
141 fenum
.username
= username
;
144 if (connections_traverse(pipe_enum_fn
, &fenum
) < 0) {
145 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
155 /*******************************************************************
156 ********************************************************************/
158 static void enum_file_fn( const struct share_mode_entry
*e
,
159 const char *sharepath
, const char *fname
,
162 struct file_enum_count
*fenum
=
163 (struct file_enum_count
*)private_data
;
165 struct srvsvc_NetFileInfo3
*f
;
166 int i
= fenum
->ctr3
->count
;
168 struct byte_range_lock
*brl
;
170 char *fullpath
= NULL
;
172 const char *username
;
174 /* If the pid was not found delete the entry from connections.tdb */
176 if ( !process_exists(e
->pid
) ) {
180 username
= uidtoname(e
->uid
);
182 if ((fenum
->username
!= NULL
)
183 && !strequal(username
, fenum
->username
)) {
187 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
188 struct srvsvc_NetFileInfo3
, i
+1);
190 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
193 fenum
->ctr3
->array
= f
;
195 /* need to count the number of locks on a file */
200 if ( (brl
= brl_get_locks(talloc_tos(), &fsp
)) != NULL
) {
201 num_locks
= brl
->num_locks
;
205 if ( strcmp( fname
, "." ) == 0 ) {
206 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s", sharepath
);
208 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s/%s",
214 string_replace( fullpath
, '/', '\\' );
216 /* mask out create (what ever that is) */
217 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
219 /* now fill in the srvsvc_NetFileInfo3 struct */
221 fenum
->ctr3
->array
[i
].fid
=
222 (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
223 fenum
->ctr3
->array
[i
].permissions
= permissions
;
224 fenum
->ctr3
->array
[i
].num_locks
= num_locks
;
225 fenum
->ctr3
->array
[i
].path
= fullpath
;
226 fenum
->ctr3
->array
[i
].user
= username
;
228 fenum
->ctr3
->count
++;
231 /*******************************************************************
232 ********************************************************************/
234 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
235 const char *username
,
236 struct srvsvc_NetFileCtr3
**ctr3
,
239 struct file_enum_count f_enum_cnt
;
241 f_enum_cnt
.ctx
= ctx
;
242 f_enum_cnt
.username
= username
;
243 f_enum_cnt
.ctr3
= *ctr3
;
245 share_mode_forall( enum_file_fn
, (void *)&f_enum_cnt
);
247 *ctr3
= f_enum_cnt
.ctr3
;
252 /*******************************************************************
253 Utility function to get the 'type' of a share from an snum.
254 ********************************************************************/
255 static enum srvsvc_ShareType
get_share_type(int snum
)
257 /* work out the share type */
258 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
260 if (lp_print_ok(snum
)) {
261 type
= lp_administrative_share(snum
)
262 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
264 if (strequal(lp_fstype(talloc_tos(), snum
), "IPC")) {
265 type
= lp_administrative_share(snum
)
266 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
271 /*******************************************************************
272 Fill in a share info level 0 structure.
273 ********************************************************************/
275 static void init_srv_share_info_0(struct pipes_struct
*p
,
276 struct srvsvc_NetShareInfo0
*r
, int snum
)
278 r
->name
= lp_servicename(talloc_tos(), snum
);
281 /*******************************************************************
282 Fill in a share info level 1 structure.
283 ********************************************************************/
285 static void init_srv_share_info_1(struct pipes_struct
*p
,
286 struct srvsvc_NetShareInfo1
*r
,
289 char *net_name
= lp_servicename(talloc_tos(), snum
);
290 char *remark
= lp_comment(p
->mem_ctx
, snum
);
293 remark
= talloc_sub_advanced(
294 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
295 get_current_username(), lp_pathname(talloc_tos(), snum
),
296 p
->session_info
->unix_token
->uid
, get_current_username(),
301 r
->type
= get_share_type(snum
);
302 r
->comment
= remark
? remark
: "";
305 /*******************************************************************
306 Fill in a share info level 2 structure.
307 ********************************************************************/
309 static void init_srv_share_info_2(struct pipes_struct
*p
,
310 struct srvsvc_NetShareInfo2
*r
,
315 int max_connections
= lp_max_connections(snum
);
316 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
317 char *net_name
= lp_servicename(talloc_tos(), snum
);
319 remark
= lp_comment(p
->mem_ctx
, snum
);
321 remark
= talloc_sub_advanced(
322 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
323 get_current_username(), lp_pathname(talloc_tos(), snum
),
324 p
->session_info
->unix_token
->uid
, get_current_username(),
327 path
= talloc_asprintf(p
->mem_ctx
,
328 "C:%s", lp_pathname(talloc_tos(), snum
));
332 * Change / to \\ so that win2k will see it as a valid path.
333 * This was added to enable use of browsing in win2k add
337 string_replace(path
, '/', '\\');
341 r
->type
= get_share_type(snum
);
342 r
->comment
= remark
? remark
: "";
344 r
->max_users
= max_uses
;
345 r
->current_users
= count_current_connections(net_name
, false);
346 r
->path
= path
? path
: "";
350 /*******************************************************************
351 Map any generic bits to file specific bits.
352 ********************************************************************/
354 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
357 struct security_acl
*ps_dacl
= NULL
;
366 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
367 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
368 uint32 orig_mask
= psa
->access_mask
;
370 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
371 psa
->access_mask
|= orig_mask
;
375 /*******************************************************************
376 Fill in a share info level 501 structure.
377 ********************************************************************/
379 static void init_srv_share_info_501(struct pipes_struct
*p
,
380 struct srvsvc_NetShareInfo501
*r
, int snum
)
382 const char *net_name
= lp_servicename(talloc_tos(), snum
);
383 char *remark
= lp_comment(p
->mem_ctx
, snum
);
386 remark
= talloc_sub_advanced(
387 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
388 get_current_username(), lp_pathname(talloc_tos(), snum
),
389 p
->session_info
->unix_token
->uid
, get_current_username(),
394 r
->type
= get_share_type(snum
);
395 r
->comment
= remark
? remark
: "";
396 r
->csc_policy
= (lp_csc_policy(snum
) << 4);
399 /*******************************************************************
400 Fill in a share info level 502 structure.
401 ********************************************************************/
403 static void init_srv_share_info_502(struct pipes_struct
*p
,
404 struct srvsvc_NetShareInfo502
*r
, int snum
)
406 const char *net_name
= lp_servicename(talloc_tos(), snum
);
408 struct security_descriptor
*sd
= NULL
;
409 struct sec_desc_buf
*sd_buf
= NULL
;
411 TALLOC_CTX
*ctx
= p
->mem_ctx
;
412 char *remark
= lp_comment(ctx
, snum
);
415 remark
= talloc_sub_advanced(
416 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
417 get_current_username(), lp_pathname(talloc_tos(), snum
),
418 p
->session_info
->unix_token
->uid
, get_current_username(),
421 path
= talloc_asprintf(ctx
, "C:%s", lp_pathname(talloc_tos(), snum
));
424 * Change / to \\ so that win2k will see it as a valid path. This was added to
425 * enable use of browsing in win2k add share dialog.
427 string_replace(path
, '/', '\\');
430 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
432 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
435 r
->type
= get_share_type(snum
);
436 r
->comment
= remark
? remark
: "";
438 r
->max_users
= (uint32_t)-1;
439 r
->current_users
= 1; /* ??? */
440 r
->path
= path
? path
: "";
445 /***************************************************************************
446 Fill in a share info level 1004 structure.
447 ***************************************************************************/
449 static void init_srv_share_info_1004(struct pipes_struct
*p
,
450 struct srvsvc_NetShareInfo1004
*r
,
453 char *remark
= lp_comment(p
->mem_ctx
, snum
);
456 remark
= talloc_sub_advanced(
457 p
->mem_ctx
, lp_servicename(talloc_tos(), snum
),
458 get_current_username(), lp_pathname(talloc_tos(), snum
),
459 p
->session_info
->unix_token
->uid
, get_current_username(),
463 r
->comment
= remark
? remark
: "";
466 /***************************************************************************
467 Fill in a share info level 1005 structure.
468 ***************************************************************************/
470 static void init_srv_share_info_1005(struct pipes_struct
*p
,
471 struct srvsvc_NetShareInfo1005
*r
,
474 uint32_t dfs_flags
= 0;
476 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
477 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
480 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
482 r
->dfs_flags
= dfs_flags
;
485 /***************************************************************************
486 Fill in a share info level 1006 structure.
487 ***************************************************************************/
489 static void init_srv_share_info_1006(struct pipes_struct
*p
,
490 struct srvsvc_NetShareInfo1006
*r
,
493 r
->max_users
= (uint32_t)-1;
496 /***************************************************************************
497 Fill in a share info level 1007 structure.
498 ***************************************************************************/
500 static void init_srv_share_info_1007(struct pipes_struct
*p
,
501 struct srvsvc_NetShareInfo1007
*r
,
505 r
->alternate_directory_name
= "";
508 /*******************************************************************
509 Fill in a share info level 1501 structure.
510 ********************************************************************/
512 static void init_srv_share_info_1501(struct pipes_struct
*p
,
513 struct sec_desc_buf
**r
,
516 struct security_descriptor
*sd
;
517 struct sec_desc_buf
*sd_buf
= NULL
;
519 TALLOC_CTX
*ctx
= p
->mem_ctx
;
521 sd
= get_share_security(ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
523 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
529 /*******************************************************************
530 True if it ends in '$'.
531 ********************************************************************/
533 static bool is_hidden_share(int snum
)
535 const char *net_name
= lp_servicename(talloc_tos(), snum
);
537 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
540 /*******************************************************************
541 Verify user is allowed to view share, access based enumeration
542 ********************************************************************/
543 static bool is_enumeration_allowed(struct pipes_struct
*p
,
546 if (!lp_access_based_share_enum(snum
))
549 return share_access_check(p
->session_info
->security_token
,
550 lp_servicename(talloc_tos(), snum
),
551 FILE_READ_DATA
, NULL
);
554 /*******************************************************************
555 Fill in a share info structure.
556 ********************************************************************/
558 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
559 struct srvsvc_NetShareInfoCtr
*info_ctr
,
560 uint32_t *resume_handle_p
,
561 uint32_t *total_entries
,
565 int alloc_entries
= 0;
566 int num_services
= 0;
568 TALLOC_CTX
*ctx
= p
->mem_ctx
;
570 int valid_share_count
= 0;
572 union srvsvc_NetShareCtr ctr
;
573 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
575 DEBUG(5,("init_srv_share_info_ctr\n"));
577 /* Ensure all the usershares are loaded. */
579 load_usershare_shares(NULL
, connections_snum_used
);
580 load_registry_shares();
581 num_services
= lp_numservices();
584 allowed
= talloc_zero_array(ctx
, bool, num_services
);
585 W_ERROR_HAVE_NO_MEMORY(allowed
);
587 /* Count the number of entries. */
588 for (snum
= 0; snum
< num_services
; snum
++) {
589 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
590 is_enumeration_allowed(p
, snum
) &&
591 (all_shares
|| !is_hidden_share(snum
)) ) {
592 DEBUG(10, ("counting service %s\n",
593 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
594 allowed
[snum
] = true;
597 DEBUG(10, ("NOT counting service %s\n",
598 lp_servicename(talloc_tos(), snum
) ? lp_servicename(talloc_tos(), snum
) : "(null)"));
602 if (!num_entries
|| (resume_handle
>= num_entries
)) {
606 /* Calculate alloc entries. */
607 alloc_entries
= num_entries
- resume_handle
;
608 switch (info_ctr
->level
) {
610 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
611 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
613 ctr
.ctr0
->count
= alloc_entries
;
614 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
615 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
617 for (snum
= 0; snum
< num_services
; snum
++) {
619 (resume_handle
<= (i
+ valid_share_count
++)) ) {
620 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
627 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
628 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
630 ctr
.ctr1
->count
= alloc_entries
;
631 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
632 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
634 for (snum
= 0; snum
< num_services
; snum
++) {
636 (resume_handle
<= (i
+ valid_share_count
++)) ) {
637 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
644 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
645 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
647 ctr
.ctr2
->count
= alloc_entries
;
648 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
649 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
651 for (snum
= 0; snum
< num_services
; snum
++) {
653 (resume_handle
<= (i
+ valid_share_count
++)) ) {
654 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
661 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
662 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
664 ctr
.ctr501
->count
= alloc_entries
;
665 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
666 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
668 for (snum
= 0; snum
< num_services
; snum
++) {
670 (resume_handle
<= (i
+ valid_share_count
++)) ) {
671 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
678 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
679 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
681 ctr
.ctr502
->count
= alloc_entries
;
682 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
683 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
685 for (snum
= 0; snum
< num_services
; snum
++) {
687 (resume_handle
<= (i
+ valid_share_count
++)) ) {
688 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
695 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
696 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
698 ctr
.ctr1004
->count
= alloc_entries
;
699 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
700 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
702 for (snum
= 0; snum
< num_services
; snum
++) {
704 (resume_handle
<= (i
+ valid_share_count
++)) ) {
705 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
712 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
713 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
715 ctr
.ctr1005
->count
= alloc_entries
;
716 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
717 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
719 for (snum
= 0; snum
< num_services
; snum
++) {
721 (resume_handle
<= (i
+ valid_share_count
++)) ) {
722 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
729 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
730 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
732 ctr
.ctr1006
->count
= alloc_entries
;
733 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
734 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
736 for (snum
= 0; snum
< num_services
; snum
++) {
738 (resume_handle
<= (i
+ valid_share_count
++)) ) {
739 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
746 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
747 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
749 ctr
.ctr1007
->count
= alloc_entries
;
750 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
751 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
753 for (snum
= 0; snum
< num_services
; snum
++) {
755 (resume_handle
<= (i
+ valid_share_count
++)) ) {
756 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
763 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
764 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
766 ctr
.ctr1501
->count
= alloc_entries
;
767 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
768 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
770 for (snum
= 0; snum
< num_services
; snum
++) {
772 (resume_handle
<= (i
+ valid_share_count
++)) ) {
773 struct sec_desc_buf
*sd_buf
= NULL
;
774 init_srv_share_info_1501(p
, &sd_buf
, snum
);
775 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
782 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
784 return WERR_UNKNOWN_LEVEL
;
787 *total_entries
= alloc_entries
;
788 if (resume_handle_p
) {
790 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
792 *resume_handle_p
= num_entries
;
801 /*******************************************************************
802 fill in a sess info level 0 structure.
803 ********************************************************************/
805 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
806 struct srvsvc_NetSessCtr0
*ctr0
,
807 uint32_t *resume_handle_p
,
808 uint32_t *total_entries
)
810 struct sessionid
*session_list
;
811 uint32_t num_entries
= 0;
812 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
813 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
815 DEBUG(5,("init_srv_sess_info_0\n"));
818 if (resume_handle_p
) {
819 *resume_handle_p
= 0;
824 for (; resume_handle
< *total_entries
; resume_handle
++) {
826 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
828 struct srvsvc_NetSessInfo0
,
830 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
832 ctr0
->array
[num_entries
].client
=
833 session_list
[resume_handle
].remote_machine
;
838 ctr0
->count
= num_entries
;
840 if (resume_handle_p
) {
841 if (*resume_handle_p
>= *total_entries
) {
842 *resume_handle_p
= 0;
844 *resume_handle_p
= resume_handle
;
851 /*******************************************************************
852 ********************************************************************/
854 static void sess_file_fn( const struct share_mode_entry
*e
,
855 const char *sharepath
, const char *fname
,
858 struct sess_file_count
*sess
= (struct sess_file_count
*)data
;
860 if (serverid_equal(&e
->pid
, &sess
->pid
) && (sess
->uid
== e
->uid
)) {
867 /*******************************************************************
868 ********************************************************************/
870 static int net_count_files( uid_t uid
, struct server_id pid
)
872 struct sess_file_count s_file_cnt
;
874 s_file_cnt
.count
= 0;
875 s_file_cnt
.uid
= uid
;
876 s_file_cnt
.pid
= pid
;
878 share_mode_forall( sess_file_fn
, &s_file_cnt
);
880 return s_file_cnt
.count
;
883 /*******************************************************************
884 fill in a sess info level 1 structure.
885 ********************************************************************/
887 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
888 struct srvsvc_NetSessCtr1
*ctr1
,
889 uint32_t *resume_handle_p
,
890 uint32_t *total_entries
)
892 struct sessionid
*session_list
;
893 uint32_t num_entries
= 0;
894 time_t now
= time(NULL
);
895 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
900 if (resume_handle_p
) {
901 *resume_handle_p
= 0;
906 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
908 for (; resume_handle
< *total_entries
; resume_handle
++) {
911 struct passwd
*pw
= getpwnam(session_list
[resume_handle
].username
);
915 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
916 session_list
[resume_handle
].username
));
920 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
921 num_files
= net_count_files(pw
->pw_uid
, session_list
[resume_handle
].pid
);
922 guest
= strequal( session_list
[resume_handle
].username
, lp_guestaccount() );
924 ctr1
->array
= talloc_realloc(p
->mem_ctx
,
926 struct srvsvc_NetSessInfo1
,
928 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
930 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
931 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
932 ctr1
->array
[num_entries
].num_open
= num_files
;
933 ctr1
->array
[num_entries
].time
= connect_time
;
934 ctr1
->array
[num_entries
].idle_time
= 0;
935 ctr1
->array
[num_entries
].user_flags
= guest
;
940 ctr1
->count
= num_entries
;
942 if (resume_handle_p
) {
943 if (*resume_handle_p
>= *total_entries
) {
944 *resume_handle_p
= 0;
946 *resume_handle_p
= resume_handle
;
953 /*******************************************************************
954 fill in a conn info level 0 structure.
955 ********************************************************************/
957 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
958 uint32_t *resume_handle_p
,
959 uint32_t *total_entries
)
961 uint32_t num_entries
= 0;
962 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
964 DEBUG(5,("init_srv_conn_info_0\n"));
967 if (resume_handle_p
) {
968 *resume_handle_p
= 0;
977 for (; resume_handle
< *total_entries
; resume_handle
++) {
979 ctr0
->array
= talloc_realloc(talloc_tos(),
981 struct srvsvc_NetConnInfo0
,
987 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
989 /* move on to creating next connection */
993 ctr0
->count
= num_entries
;
994 *total_entries
= num_entries
;
996 if (resume_handle_p
) {
997 if (*resume_handle_p
>= *total_entries
) {
998 *resume_handle_p
= 0;
1000 *resume_handle_p
= resume_handle
;
1007 /*******************************************************************
1008 fill in a conn info level 1 structure.
1009 ********************************************************************/
1011 static WERROR
init_srv_conn_info_1(struct srvsvc_NetConnCtr1
*ctr1
,
1012 uint32_t *resume_handle_p
,
1013 uint32_t *total_entries
)
1015 uint32_t num_entries
= 0;
1016 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1018 DEBUG(5,("init_srv_conn_info_1\n"));
1021 if (resume_handle_p
) {
1022 *resume_handle_p
= 0;
1031 for (; resume_handle
< *total_entries
; resume_handle
++) {
1033 ctr1
->array
= talloc_realloc(talloc_tos(),
1035 struct srvsvc_NetConnInfo1
,
1041 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1042 ctr1
->array
[num_entries
].conn_type
= 0x3;
1043 ctr1
->array
[num_entries
].num_open
= 1;
1044 ctr1
->array
[num_entries
].num_users
= 1;
1045 ctr1
->array
[num_entries
].conn_time
= 3;
1046 ctr1
->array
[num_entries
].user
= "dummy_user";
1047 ctr1
->array
[num_entries
].share
= "IPC$";
1049 /* move on to creating next connection */
1053 ctr1
->count
= num_entries
;
1054 *total_entries
= num_entries
;
1056 if (resume_handle_p
) {
1057 if (*resume_handle_p
>= *total_entries
) {
1058 *resume_handle_p
= 0;
1060 *resume_handle_p
= resume_handle
;
1067 /*******************************************************************
1069 *******************************************************************/
1071 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1072 struct srvsvc_NetFileEnum
*r
)
1074 TALLOC_CTX
*ctx
= NULL
;
1075 struct srvsvc_NetFileCtr3
*ctr3
;
1076 uint32_t resume_hnd
= 0;
1079 switch (r
->in
.info_ctr
->level
) {
1083 return WERR_UNKNOWN_LEVEL
;
1086 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1087 p
->session_info
->security_token
)) {
1088 DEBUG(1, ("Enumerating files only allowed for "
1089 "administrators\n"));
1090 return WERR_ACCESS_DENIED
;
1094 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1096 werr
= WERR_INVALID_PARAM
;
1100 /* TODO -- Windows enumerates
1102 (c) open directories and files */
1104 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1105 if (!W_ERROR_IS_OK(werr
)) {
1109 werr
= net_enum_pipes(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1110 if (!W_ERROR_IS_OK(werr
)) {
1114 *r
->out
.totalentries
= ctr3
->count
;
1115 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1116 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1124 /*******************************************************************
1125 _srvsvc_NetSrvGetInfo
1126 ********************************************************************/
1128 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1129 struct srvsvc_NetSrvGetInfo
*r
)
1131 WERROR status
= WERR_OK
;
1133 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1135 if (!pipe_access_check(p
)) {
1136 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1137 return WERR_ACCESS_DENIED
;
1140 switch (r
->in
.level
) {
1142 /* Technically level 102 should only be available to
1143 Administrators but there isn't anything super-secret
1144 here, as most of it is made up. */
1147 struct srvsvc_NetSrvInfo102
*info102
;
1149 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1154 info102
->platform_id
= PLATFORM_ID_NT
;
1155 info102
->server_name
= lp_netbios_name();
1156 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1157 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1158 info102
->server_type
= lp_default_server_announce();
1159 info102
->comment
= string_truncate(lp_serverstring(talloc_tos()),
1160 MAX_SERVER_STRING_LENGTH
);
1161 info102
->users
= 0xffffffff;
1162 info102
->disc
= 0xf;
1163 info102
->hidden
= 0;
1164 info102
->announce
= 240;
1165 info102
->anndelta
= 3000;
1166 info102
->licenses
= 100000;
1167 info102
->userpath
= "C:\\";
1169 r
->out
.info
->info102
= info102
;
1173 struct srvsvc_NetSrvInfo101
*info101
;
1175 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1180 info101
->platform_id
= PLATFORM_ID_NT
;
1181 info101
->server_name
= lp_netbios_name();
1182 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1183 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1184 info101
->server_type
= lp_default_server_announce();
1185 info101
->comment
= string_truncate(lp_serverstring(talloc_tos()),
1186 MAX_SERVER_STRING_LENGTH
);
1188 r
->out
.info
->info101
= info101
;
1192 struct srvsvc_NetSrvInfo100
*info100
;
1194 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1199 info100
->platform_id
= PLATFORM_ID_NT
;
1200 info100
->server_name
= lp_netbios_name();
1202 r
->out
.info
->info100
= info100
;
1207 status
= WERR_UNKNOWN_LEVEL
;
1211 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1216 /*******************************************************************
1217 _srvsvc_NetSrvSetInfo
1218 ********************************************************************/
1220 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1221 struct srvsvc_NetSrvSetInfo
*r
)
1223 WERROR status
= WERR_OK
;
1225 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1227 /* Set up the net server set info structure. */
1229 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1234 /*******************************************************************
1236 ********************************************************************/
1238 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1239 struct srvsvc_NetConnEnum
*r
)
1243 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1245 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1246 p
->session_info
->security_token
)) {
1247 DEBUG(1, ("Enumerating connections only allowed for "
1248 "administrators\n"));
1249 return WERR_ACCESS_DENIED
;
1252 switch (r
->in
.info_ctr
->level
) {
1254 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1255 r
->in
.resume_handle
,
1256 r
->out
.totalentries
);
1259 werr
= init_srv_conn_info_1(r
->in
.info_ctr
->ctr
.ctr1
,
1260 r
->in
.resume_handle
,
1261 r
->out
.totalentries
);
1264 return WERR_UNKNOWN_LEVEL
;
1267 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1272 /*******************************************************************
1274 ********************************************************************/
1276 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1277 struct srvsvc_NetSessEnum
*r
)
1281 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1283 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1284 p
->session_info
->security_token
)) {
1285 DEBUG(1, ("Enumerating sessions only allowed for "
1286 "administrators\n"));
1287 return WERR_ACCESS_DENIED
;
1290 switch (r
->in
.info_ctr
->level
) {
1292 werr
= init_srv_sess_info_0(p
,
1293 r
->in
.info_ctr
->ctr
.ctr0
,
1294 r
->in
.resume_handle
,
1295 r
->out
.totalentries
);
1298 werr
= init_srv_sess_info_1(p
,
1299 r
->in
.info_ctr
->ctr
.ctr1
,
1300 r
->in
.resume_handle
,
1301 r
->out
.totalentries
);
1304 return WERR_UNKNOWN_LEVEL
;
1307 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1312 /*******************************************************************
1314 ********************************************************************/
1316 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1317 struct srvsvc_NetSessDel
*r
)
1319 struct sessionid
*session_list
;
1320 int num_sessions
, snum
;
1321 const char *username
;
1322 const char *machine
;
1323 bool not_root
= False
;
1326 username
= r
->in
.user
;
1327 machine
= r
->in
.client
;
1329 /* strip leading backslashes if any */
1330 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1334 num_sessions
= list_sessions(p
->mem_ctx
, &session_list
);
1336 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1338 werr
= WERR_ACCESS_DENIED
;
1340 /* fail out now if you are not root or not a domain admin */
1342 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1343 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1344 DOMAIN_RID_ADMINS
))) {
1349 for (snum
= 0; snum
< num_sessions
; snum
++) {
1351 if ((strequal(session_list
[snum
].username
, username
) || username
[0] == '\0' ) &&
1352 strequal(session_list
[snum
].remote_machine
, machine
)) {
1356 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1361 ntstat
= messaging_send(p
->msg_ctx
,
1362 session_list
[snum
].pid
,
1363 MSG_SHUTDOWN
, &data_blob_null
);
1365 if (NT_STATUS_IS_OK(ntstat
))
1373 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1380 /*******************************************************************
1381 _srvsvc_NetShareEnumAll
1382 ********************************************************************/
1384 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1385 struct srvsvc_NetShareEnumAll
*r
)
1389 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1391 if (!pipe_access_check(p
)) {
1392 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\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_NetShareEnumAll: %d\n", __LINE__
));
1408 /*******************************************************************
1409 _srvsvc_NetShareEnum
1410 ********************************************************************/
1412 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1413 struct srvsvc_NetShareEnum
*r
)
1417 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1419 if (!pipe_access_check(p
)) {
1420 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1421 return WERR_ACCESS_DENIED
;
1424 /* Create the list of shares for the response. */
1425 werr
= init_srv_share_info_ctr(p
,
1427 r
->in
.resume_handle
,
1428 r
->out
.totalentries
,
1431 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1436 /*******************************************************************
1437 _srvsvc_NetShareGetInfo
1438 ********************************************************************/
1440 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1441 struct srvsvc_NetShareGetInfo
*r
)
1443 WERROR status
= WERR_OK
;
1444 char *share_name
= NULL
;
1446 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1448 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1450 if (!r
->in
.share_name
) {
1451 return WERR_INVALID_NAME
;
1454 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1459 return WERR_INVALID_NAME
;
1462 switch (r
->in
.level
) {
1464 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1465 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1466 init_srv_share_info_0(p
, info
->info0
, snum
);
1469 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1470 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1471 init_srv_share_info_1(p
, info
->info1
, snum
);
1474 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1475 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1476 init_srv_share_info_2(p
, info
->info2
, snum
);
1479 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1480 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1481 init_srv_share_info_501(p
, info
->info501
, snum
);
1484 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1485 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1486 init_srv_share_info_502(p
, info
->info502
, snum
);
1489 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1490 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1491 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1494 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1495 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1496 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1499 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1500 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1501 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1504 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1505 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1506 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1509 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1512 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1514 status
= WERR_UNKNOWN_LEVEL
;
1518 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1523 /*******************************************************************
1524 _srvsvc_NetShareSetInfo. Modify share details.
1525 ********************************************************************/
1527 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1528 struct srvsvc_NetShareSetInfo
*r
)
1530 char *command
= NULL
;
1531 char *share_name
= NULL
;
1532 char *comment
= NULL
;
1533 const char *pathname
= NULL
;
1538 struct security_descriptor
*psd
= NULL
;
1539 bool is_disk_op
= False
;
1540 int max_connections
= 0;
1541 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1542 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1544 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1546 if (!r
->in
.share_name
) {
1547 return WERR_INVALID_NAME
;
1550 if (r
->out
.parm_error
) {
1551 *r
->out
.parm_error
= 0;
1554 if ( strequal(r
->in
.share_name
,"IPC$")
1555 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1556 || strequal(r
->in
.share_name
,"global") )
1558 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1559 "modified by a remote user.\n",
1560 r
->in
.share_name
));
1561 return WERR_ACCESS_DENIED
;
1564 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1569 /* Does this share exist ? */
1571 return WERR_NET_NAME_NOT_FOUND
;
1573 /* No change to printer shares. */
1574 if (lp_print_ok(snum
))
1575 return WERR_ACCESS_DENIED
;
1577 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1579 /* fail out now if you are not root and not a disk op */
1581 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1582 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1583 "SeDiskOperatorPrivilege privilege needed to modify "
1585 (unsigned int)p
->session_info
->unix_token
->uid
,
1587 return WERR_ACCESS_DENIED
;
1590 switch (r
->in
.level
) {
1592 pathname
= lp_pathname(ctx
, snum
);
1593 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1594 type
= info
->info1
->type
;
1598 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1599 pathname
= info
->info2
->path
;
1600 type
= info
->info2
->type
;
1601 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1602 0 : info
->info2
->max_users
;
1606 /* not supported on set but here for completeness */
1608 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1609 type
= info
->info501
->type
;
1614 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1615 pathname
= info
->info502
->path
;
1616 type
= info
->info502
->type
;
1617 psd
= info
->info502
->sd_buf
.sd
;
1618 map_generic_share_sd_bits(psd
);
1621 pathname
= lp_pathname(ctx
, snum
);
1622 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1623 type
= STYPE_DISKTREE
;
1626 /* XP re-sets the csc policy even if it wasn't changed by the
1627 user, so we must compare it to see if it's what is set in
1628 smb.conf, so that we can contine other ops like setting
1630 if (((info
->info1005
->dfs_flags
&
1631 SHARE_1005_CSC_POLICY_MASK
) >>
1632 SHARE_1005_CSC_POLICY_SHIFT
) == lp_csc_policy(snum
))
1635 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1636 return WERR_ACCESS_DENIED
;
1640 return WERR_ACCESS_DENIED
;
1642 pathname
= lp_pathname(ctx
, snum
);
1643 comment
= lp_comment(ctx
, snum
);
1644 psd
= info
->info1501
->sd
;
1645 map_generic_share_sd_bits(psd
);
1646 type
= STYPE_DISKTREE
;
1649 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1651 return WERR_UNKNOWN_LEVEL
;
1654 /* We can only modify disk shares. */
1655 if (type
!= STYPE_DISKTREE
) {
1656 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1659 return WERR_ACCESS_DENIED
;
1662 if (comment
== NULL
) {
1666 /* Check if the pathname is valid. */
1667 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1668 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1670 return WERR_OBJECT_PATH_INVALID
;
1673 /* Ensure share name, pathname and comment don't contain '"' characters. */
1674 string_replace(share_name
, '"', ' ');
1675 string_replace(path
, '"', ' ');
1676 string_replace(comment
, '"', ' ');
1678 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1679 lp_change_share_cmd(talloc_tos()) ? lp_change_share_cmd(talloc_tos()) : "NULL" ));
1681 /* Only call modify function if something changed. */
1683 if (strcmp(path
, lp_pathname(talloc_tos(), snum
)) || strcmp(comment
, lp_comment(talloc_tos(), snum
))
1684 || (lp_max_connections(snum
) != max_connections
)) {
1685 if (!lp_change_share_cmd(talloc_tos()) || !*lp_change_share_cmd(talloc_tos())) {
1686 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1687 return WERR_ACCESS_DENIED
;
1690 command
= talloc_asprintf(p
->mem_ctx
,
1691 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1692 lp_change_share_cmd(talloc_tos()),
1693 get_dyn_CONFIGFILE(),
1696 comment
? comment
: "",
1702 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1704 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1709 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1710 /* Tell everyone we updated smb.conf. */
1711 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1718 /********* END SeDiskOperatorPrivilege BLOCK *********/
1720 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1723 TALLOC_FREE(command
);
1726 return WERR_ACCESS_DENIED
;
1728 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1732 /* Replace SD if changed. */
1734 struct security_descriptor
*old_sd
;
1737 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(talloc_tos(), snum
), &sd_size
);
1739 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1740 if (!set_share_security(share_name
, psd
))
1741 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1746 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1751 /*******************************************************************
1752 _srvsvc_NetShareAdd.
1753 Call 'add_share_command "sharename" "pathname"
1754 "comment" "max connections = "
1755 ********************************************************************/
1757 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1758 struct srvsvc_NetShareAdd
*r
)
1760 char *command
= NULL
;
1761 char *share_name_in
= NULL
;
1762 char *share_name
= NULL
;
1763 char *comment
= NULL
;
1764 char *pathname
= NULL
;
1769 struct security_descriptor
*psd
= NULL
;
1771 int max_connections
= 0;
1772 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1774 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1776 if (r
->out
.parm_error
) {
1777 *r
->out
.parm_error
= 0;
1780 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1782 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1783 return WERR_ACCESS_DENIED
;
1785 if (!lp_add_share_cmd(talloc_tos()) || !*lp_add_share_cmd(talloc_tos())) {
1786 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1787 return WERR_ACCESS_DENIED
;
1790 switch (r
->in
.level
) {
1792 /* No path. Not enough info in a level 0 to do anything. */
1793 return WERR_ACCESS_DENIED
;
1795 /* Not enough info in a level 1 to do anything. */
1796 return WERR_ACCESS_DENIED
;
1798 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1799 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1800 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1801 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1802 0 : r
->in
.info
->info2
->max_users
;
1803 type
= r
->in
.info
->info2
->type
;
1806 /* No path. Not enough info in a level 501 to do anything. */
1807 return WERR_ACCESS_DENIED
;
1809 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1810 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1811 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1812 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1813 0 : r
->in
.info
->info502
->max_users
;
1814 type
= r
->in
.info
->info502
->type
;
1815 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1816 map_generic_share_sd_bits(psd
);
1819 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1825 return WERR_ACCESS_DENIED
;
1827 /* DFS only level. */
1828 return WERR_ACCESS_DENIED
;
1830 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1832 return WERR_UNKNOWN_LEVEL
;
1835 /* check for invalid share names */
1837 if (!share_name_in
|| !validate_net_name(share_name_in
,
1838 INVALID_SHARENAME_CHARS
,
1839 strlen(share_name_in
))) {
1840 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1841 share_name_in
? share_name_in
: ""));
1842 return WERR_INVALID_NAME
;
1845 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
1846 || (lp_enable_asu_support() &&
1847 strequal(share_name_in
,"ADMIN$"))) {
1848 return WERR_ACCESS_DENIED
;
1851 snum
= find_service(ctx
, share_name_in
, &share_name
);
1856 /* Share already exists. */
1858 return WERR_FILE_EXISTS
;
1861 /* We can only add disk shares. */
1862 if (type
!= STYPE_DISKTREE
) {
1863 return WERR_ACCESS_DENIED
;
1866 /* Check if the pathname is valid. */
1867 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1868 return WERR_OBJECT_PATH_INVALID
;
1871 /* Ensure share name, pathname and comment don't contain '"' characters. */
1872 string_replace(share_name_in
, '"', ' ');
1873 string_replace(share_name
, '"', ' ');
1874 string_replace(path
, '"', ' ');
1876 string_replace(comment
, '"', ' ');
1879 command
= talloc_asprintf(ctx
,
1880 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1881 lp_add_share_cmd(talloc_tos()),
1882 get_dyn_CONFIGFILE(),
1885 comment
? comment
: "",
1891 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
1893 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1898 /* FIXME: use libnetconf here - gd */
1900 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1901 /* Tell everyone we updated smb.conf. */
1902 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
1909 /********* END SeDiskOperatorPrivilege BLOCK *********/
1911 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1914 TALLOC_FREE(command
);
1917 return WERR_ACCESS_DENIED
;
1920 /* Note we use share_name here, not share_name_in as
1921 we need a canonicalized name for setting security. */
1922 if (!set_share_security(share_name
, psd
)) {
1923 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1929 * We don't call reload_services() here, the message will
1930 * cause this to be done before the next packet is read
1931 * from the client. JRA.
1934 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1939 /*******************************************************************
1941 Call "delete share command" with the share name as
1943 ********************************************************************/
1945 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
1946 struct srvsvc_NetShareDel
*r
)
1948 char *command
= NULL
;
1949 char *share_name
= NULL
;
1953 struct share_params
*params
;
1954 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1956 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
1958 if (!r
->in
.share_name
) {
1959 return WERR_NET_NAME_NOT_FOUND
;
1962 if ( strequal(r
->in
.share_name
,"IPC$")
1963 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1964 || strequal(r
->in
.share_name
,"global") )
1966 return WERR_ACCESS_DENIED
;
1969 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1975 return WERR_NO_SUCH_SHARE
;
1978 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
1979 return WERR_NO_SUCH_SHARE
;
1982 /* No change to printer shares. */
1983 if (lp_print_ok(snum
))
1984 return WERR_ACCESS_DENIED
;
1986 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1988 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1989 return WERR_ACCESS_DENIED
;
1991 if (!lp_delete_share_cmd(talloc_tos()) || !*lp_delete_share_cmd(talloc_tos())) {
1992 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1993 return WERR_ACCESS_DENIED
;
1996 command
= talloc_asprintf(ctx
,
1998 lp_delete_share_cmd(talloc_tos()),
1999 get_dyn_CONFIGFILE(),
2000 lp_servicename(talloc_tos(), snum
));
2005 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
2007 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2012 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2013 /* Tell everyone we updated smb.conf. */
2014 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2021 /********* END SeDiskOperatorPrivilege BLOCK *********/
2023 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2026 return WERR_ACCESS_DENIED
;
2028 /* Delete the SD in the database. */
2029 delete_share_security(lp_servicename(talloc_tos(), params
->service
));
2031 lp_killservice(params
->service
);
2036 /*******************************************************************
2037 _srvsvc_NetShareDelSticky
2038 ********************************************************************/
2040 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2041 struct srvsvc_NetShareDelSticky
*r
)
2043 struct srvsvc_NetShareDel q
;
2045 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2047 q
.in
.server_unc
= r
->in
.server_unc
;
2048 q
.in
.share_name
= r
->in
.share_name
;
2049 q
.in
.reserved
= r
->in
.reserved
;
2051 return _srvsvc_NetShareDel(p
, &q
);
2054 /*******************************************************************
2055 _srvsvc_NetRemoteTOD
2056 ********************************************************************/
2058 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2059 struct srvsvc_NetRemoteTOD
*r
)
2061 struct srvsvc_NetRemoteTODInfo
*tod
;
2063 time_t unixdate
= time(NULL
);
2065 /* We do this call first as if we do it *after* the gmtime call
2066 it overwrites the pointed-to values. JRA */
2068 uint32 zone
= get_time_zone(unixdate
)/60;
2070 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2072 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2077 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2079 t
= gmtime(&unixdate
);
2082 tod
->elapsed
= unixdate
;
2084 tod
->hours
= t
->tm_hour
;
2085 tod
->mins
= t
->tm_min
;
2086 tod
->secs
= t
->tm_sec
;
2088 tod
->timezone
= zone
;
2089 tod
->tinterval
= 10000;
2090 tod
->day
= t
->tm_mday
;
2091 tod
->month
= t
->tm_mon
+ 1;
2092 tod
->year
= 1900+t
->tm_year
;
2093 tod
->weekday
= t
->tm_wday
;
2095 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2100 /***********************************************************************************
2101 _srvsvc_NetGetFileSecurity
2102 Win9x NT tools get security descriptor.
2103 ***********************************************************************************/
2105 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2106 struct srvsvc_NetGetFileSecurity
*r
)
2108 struct smb_filename
*smb_fname
= NULL
;
2109 struct security_descriptor
*psd
= NULL
;
2111 char *servicename
= NULL
;
2115 connection_struct
*conn
= NULL
;
2116 struct sec_desc_buf
*sd_buf
= NULL
;
2117 files_struct
*fsp
= NULL
;
2119 char *oldcwd
= NULL
;
2124 werr
= WERR_NET_NAME_NOT_FOUND
;
2127 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2133 DEBUG(10, ("Could not find service %s\n", servicename
));
2134 werr
= WERR_NET_NAME_NOT_FOUND
;
2138 nt_status
= create_conn_struct(talloc_tos(),
2139 server_event_context(),
2140 server_messaging_context(),
2142 snum
, lp_pathname(talloc_tos(), snum
),
2143 p
->session_info
, &oldcwd
);
2144 if (!NT_STATUS_IS_OK(nt_status
)) {
2145 DEBUG(10, ("create_conn_struct failed: %s\n",
2146 nt_errstr(nt_status
)));
2147 werr
= ntstatus_to_werror(nt_status
);
2151 nt_status
= filename_convert(talloc_tos(),
2158 if (!NT_STATUS_IS_OK(nt_status
)) {
2159 werr
= ntstatus_to_werror(nt_status
);
2163 nt_status
= SMB_VFS_CREATE_FILE(
2166 0, /* root_dir_fid */
2167 smb_fname
, /* fname */
2168 FILE_READ_ATTRIBUTES
, /* access_mask */
2169 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2170 FILE_OPEN
, /* create_disposition*/
2171 0, /* create_options */
2172 0, /* file_attributes */
2173 INTERNAL_OPEN_ONLY
, /* oplock_request */
2174 0, /* allocation_size */
2175 0, /* private_flags */
2181 if (!NT_STATUS_IS_OK(nt_status
)) {
2182 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2183 smb_fname_str_dbg(smb_fname
)));
2184 werr
= ntstatus_to_werror(nt_status
);
2188 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2194 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2197 |SECINFO_DACL
), sd_buf
, &sd_buf
->sd
);
2199 if (!NT_STATUS_IS_OK(nt_status
)) {
2200 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2201 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2202 werr
= ntstatus_to_werror(nt_status
);
2203 TALLOC_FREE(sd_buf
);
2207 if (psd
&& psd
->dacl
) {
2208 psd
->dacl
->revision
= NT4_ACL_REVISION
;
2211 sd_size
= ndr_size_security_descriptor(psd
, 0);
2213 sd_buf
->sd_size
= sd_size
;
2215 *r
->out
.sd_buf
= sd_buf
;
2217 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2218 vfs_ChDir(conn
, oldcwd
);
2219 SMB_VFS_DISCONNECT(conn
);
2227 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2231 vfs_ChDir(conn
, oldcwd
);
2235 SMB_VFS_DISCONNECT(conn
);
2242 TALLOC_FREE(smb_fname
);
2247 /***********************************************************************************
2248 _srvsvc_NetSetFileSecurity
2249 Win9x NT tools set security descriptor.
2250 ***********************************************************************************/
2252 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2253 struct srvsvc_NetSetFileSecurity
*r
)
2255 struct smb_filename
*smb_fname
= NULL
;
2256 char *servicename
= NULL
;
2257 files_struct
*fsp
= NULL
;
2261 connection_struct
*conn
= NULL
;
2263 char *oldcwd
= NULL
;
2264 struct security_descriptor
*psd
= NULL
;
2265 uint32_t security_info_sent
= 0;
2270 werr
= WERR_NET_NAME_NOT_FOUND
;
2274 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2281 DEBUG(10, ("Could not find service %s\n", servicename
));
2282 werr
= WERR_NET_NAME_NOT_FOUND
;
2286 nt_status
= create_conn_struct(talloc_tos(),
2287 server_event_context(),
2288 server_messaging_context(),
2290 snum
, lp_pathname(talloc_tos(), snum
),
2291 p
->session_info
, &oldcwd
);
2292 if (!NT_STATUS_IS_OK(nt_status
)) {
2293 DEBUG(10, ("create_conn_struct failed: %s\n",
2294 nt_errstr(nt_status
)));
2295 werr
= ntstatus_to_werror(nt_status
);
2299 nt_status
= filename_convert(talloc_tos(),
2306 if (!NT_STATUS_IS_OK(nt_status
)) {
2307 werr
= ntstatus_to_werror(nt_status
);
2311 nt_status
= SMB_VFS_CREATE_FILE(
2314 0, /* root_dir_fid */
2315 smb_fname
, /* fname */
2316 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2317 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2318 FILE_OPEN
, /* create_disposition*/
2319 0, /* create_options */
2320 0, /* file_attributes */
2321 INTERNAL_OPEN_ONLY
, /* oplock_request */
2322 0, /* allocation_size */
2323 0, /* private_flags */
2329 if (!NT_STATUS_IS_OK(nt_status
)) {
2330 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2331 smb_fname_str_dbg(smb_fname
)));
2332 werr
= ntstatus_to_werror(nt_status
);
2336 psd
= r
->in
.sd_buf
->sd
;
2337 security_info_sent
= r
->in
.securityinformation
;
2339 nt_status
= set_sd(fsp
, psd
, security_info_sent
);
2341 if (!NT_STATUS_IS_OK(nt_status
) ) {
2342 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2343 "on file %s\n", r
->in
.share
));
2344 werr
= WERR_ACCESS_DENIED
;
2348 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2349 vfs_ChDir(conn
, oldcwd
);
2350 SMB_VFS_DISCONNECT(conn
);
2358 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2362 vfs_ChDir(conn
, oldcwd
);
2366 SMB_VFS_DISCONNECT(conn
);
2371 TALLOC_FREE(smb_fname
);
2376 /***********************************************************************************
2377 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2378 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2379 These disks would the disks listed by this function.
2380 Users could then create shares relative to these disks. Watch out for moving these disks around.
2381 "Nigel Williams" <nigel@veritas.com>.
2382 ***********************************************************************************/
2384 static const char *server_disks
[] = {"C:"};
2386 static uint32
get_server_disk_count(void)
2388 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2391 static uint32
init_server_disk_enum(uint32
*resume
)
2393 uint32 server_disk_count
= get_server_disk_count();
2395 /*resume can be an offset into the list for now*/
2397 if(*resume
& 0x80000000)
2400 if(*resume
> server_disk_count
)
2401 *resume
= server_disk_count
;
2403 return server_disk_count
- *resume
;
2406 static const char *next_server_disk_enum(uint32
*resume
)
2410 if(init_server_disk_enum(resume
) == 0)
2413 disk
= server_disks
[*resume
];
2417 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2422 /********************************************************************
2424 ********************************************************************/
2426 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2427 struct srvsvc_NetDiskEnum
*r
)
2430 const char *disk_name
;
2431 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2433 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2437 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2439 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2440 MAX_SERVER_DISK_ENTRIES
);
2441 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2443 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2445 r
->out
.info
->count
= 0;
2447 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2449 r
->out
.info
->count
++;
2451 /*copy disk name into a unicode string*/
2453 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2454 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2457 /* add a terminating null string. Is this there if there is more data to come? */
2459 r
->out
.info
->count
++;
2461 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2462 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2464 if (r
->out
.resume_handle
) {
2465 *r
->out
.resume_handle
= resume
;
2471 /********************************************************************
2472 _srvsvc_NetNameValidate
2473 ********************************************************************/
2475 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2476 struct srvsvc_NetNameValidate
*r
)
2478 switch (r
->in
.name_type
) {
2480 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2481 strlen_m(r
->in
.name
)))
2483 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2485 return WERR_INVALID_NAME
;
2490 return WERR_UNKNOWN_LEVEL
;
2496 /*******************************************************************
2497 ********************************************************************/
2499 struct enum_file_close_state
{
2500 struct srvsvc_NetFileClose
*r
;
2501 struct messaging_context
*msg_ctx
;
2504 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2505 const char *sharepath
, const char *fname
,
2506 void *private_data
)
2508 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2509 struct enum_file_close_state
*state
=
2510 (struct enum_file_close_state
*)private_data
;
2511 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2513 if (fid
!= state
->r
->in
.fid
) {
2514 return; /* Not this file. */
2517 if (!process_exists(e
->pid
) ) {
2521 /* Ok - send the close message. */
2522 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2524 share_mode_str(talloc_tos(), 0, e
) ));
2526 share_mode_entry_to_message(msg
, e
);
2528 state
->r
->out
.result
= ntstatus_to_werror(
2529 messaging_send_buf(state
->msg_ctx
,
2530 e
->pid
, MSG_SMB_CLOSE_FILE
,
2532 MSG_SMB_SHARE_MODE_ENTRY_SIZE
));
2535 /********************************************************************
2536 Close a file given a 32-bit file id.
2537 ********************************************************************/
2539 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2540 struct srvsvc_NetFileClose
*r
)
2542 struct enum_file_close_state state
;
2545 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2547 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2549 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2550 return WERR_ACCESS_DENIED
;
2553 /* enum_file_close_fn sends the close message to
2554 * the relevent smbd process. */
2556 r
->out
.result
= WERR_BADFILE
;
2558 state
.msg_ctx
= p
->msg_ctx
;
2559 share_mode_forall(enum_file_close_fn
, &state
);
2560 return r
->out
.result
;
2563 /********************************************************************
2564 ********************************************************************/
2566 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2567 struct srvsvc_NetCharDevEnum
*r
)
2569 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2570 return WERR_NOT_SUPPORTED
;
2573 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2574 struct srvsvc_NetCharDevGetInfo
*r
)
2576 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2577 return WERR_NOT_SUPPORTED
;
2580 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2581 struct srvsvc_NetCharDevControl
*r
)
2583 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2584 return WERR_NOT_SUPPORTED
;
2587 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2588 struct srvsvc_NetCharDevQEnum
*r
)
2590 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2591 return WERR_NOT_SUPPORTED
;
2594 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2595 struct srvsvc_NetCharDevQGetInfo
*r
)
2597 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2598 return WERR_NOT_SUPPORTED
;
2601 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2602 struct srvsvc_NetCharDevQSetInfo
*r
)
2604 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2605 return WERR_NOT_SUPPORTED
;
2608 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2609 struct srvsvc_NetCharDevQPurge
*r
)
2611 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2612 return WERR_NOT_SUPPORTED
;
2615 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2616 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2618 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2619 return WERR_NOT_SUPPORTED
;
2622 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2623 struct srvsvc_NetFileGetInfo
*r
)
2625 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2626 return WERR_NOT_SUPPORTED
;
2629 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2630 struct srvsvc_NetShareCheck
*r
)
2632 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2633 return WERR_NOT_SUPPORTED
;
2636 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2637 struct srvsvc_NetServerStatisticsGet
*r
)
2639 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2640 return WERR_NOT_SUPPORTED
;
2643 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2644 struct srvsvc_NetTransportAdd
*r
)
2646 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2647 return WERR_NOT_SUPPORTED
;
2650 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2651 struct srvsvc_NetTransportEnum
*r
)
2653 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2654 return WERR_NOT_SUPPORTED
;
2657 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2658 struct srvsvc_NetTransportDel
*r
)
2660 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2661 return WERR_NOT_SUPPORTED
;
2664 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2665 struct srvsvc_NetSetServiceBits
*r
)
2667 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2668 return WERR_NOT_SUPPORTED
;
2671 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2672 struct srvsvc_NetPathType
*r
)
2674 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2675 return WERR_NOT_SUPPORTED
;
2678 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2679 struct srvsvc_NetPathCanonicalize
*r
)
2681 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2682 return WERR_NOT_SUPPORTED
;
2685 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2686 struct srvsvc_NetPathCompare
*r
)
2688 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2689 return WERR_NOT_SUPPORTED
;
2692 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2693 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2695 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2696 return WERR_NOT_SUPPORTED
;
2699 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2700 struct srvsvc_NetPRNameCompare
*r
)
2702 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2703 return WERR_NOT_SUPPORTED
;
2706 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2707 struct srvsvc_NetShareDelStart
*r
)
2709 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2710 return WERR_NOT_SUPPORTED
;
2713 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2714 struct srvsvc_NetShareDelCommit
*r
)
2716 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2717 return WERR_NOT_SUPPORTED
;
2720 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2721 struct srvsvc_NetServerTransportAddEx
*r
)
2723 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2724 return WERR_NOT_SUPPORTED
;
2727 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2728 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2730 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2731 return WERR_NOT_SUPPORTED
;
2734 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2735 struct srvsvc_NETRDFSGETVERSION
*r
)
2737 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2738 return WERR_NOT_SUPPORTED
;
2741 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2742 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2744 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2745 return WERR_NOT_SUPPORTED
;
2748 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2749 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2751 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2752 return WERR_NOT_SUPPORTED
;
2755 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2756 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2758 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2759 return WERR_NOT_SUPPORTED
;
2762 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2763 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2765 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2766 return WERR_NOT_SUPPORTED
;
2769 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2770 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2772 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2773 return WERR_NOT_SUPPORTED
;
2776 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2777 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2779 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2780 return WERR_NOT_SUPPORTED
;
2783 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2784 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2786 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2787 return WERR_NOT_SUPPORTED
;
2790 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2791 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2793 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2794 return WERR_NOT_SUPPORTED
;
2797 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2798 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2800 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2801 return WERR_NOT_SUPPORTED
;
2804 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2805 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2807 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2808 return WERR_NOT_SUPPORTED
;