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 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2191 |SECINFO_DACL
), &psd
);
2193 if (!NT_STATUS_IS_OK(nt_status
)) {
2194 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2195 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2196 werr
= ntstatus_to_werror(nt_status
);
2200 sd_size
= ndr_size_security_descriptor(psd
, 0);
2202 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2208 sd_buf
->sd_size
= sd_size
;
2211 *r
->out
.sd_buf
= sd_buf
;
2213 psd
->dacl
->revision
= NT4_ACL_REVISION
;
2215 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2216 vfs_ChDir(conn
, oldcwd
);
2217 SMB_VFS_DISCONNECT(conn
);
2225 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2229 vfs_ChDir(conn
, oldcwd
);
2233 SMB_VFS_DISCONNECT(conn
);
2238 TALLOC_FREE(smb_fname
);
2243 /***********************************************************************************
2244 _srvsvc_NetSetFileSecurity
2245 Win9x NT tools set security descriptor.
2246 ***********************************************************************************/
2248 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2249 struct srvsvc_NetSetFileSecurity
*r
)
2251 struct smb_filename
*smb_fname
= NULL
;
2252 char *servicename
= NULL
;
2253 files_struct
*fsp
= NULL
;
2257 connection_struct
*conn
= NULL
;
2259 char *oldcwd
= NULL
;
2260 struct security_descriptor
*psd
= NULL
;
2261 uint32_t security_info_sent
= 0;
2266 werr
= WERR_NET_NAME_NOT_FOUND
;
2270 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2277 DEBUG(10, ("Could not find service %s\n", servicename
));
2278 werr
= WERR_NET_NAME_NOT_FOUND
;
2282 nt_status
= create_conn_struct(talloc_tos(),
2283 server_event_context(),
2284 server_messaging_context(),
2286 snum
, lp_pathname(talloc_tos(), snum
),
2287 p
->session_info
, &oldcwd
);
2288 if (!NT_STATUS_IS_OK(nt_status
)) {
2289 DEBUG(10, ("create_conn_struct failed: %s\n",
2290 nt_errstr(nt_status
)));
2291 werr
= ntstatus_to_werror(nt_status
);
2295 nt_status
= filename_convert(talloc_tos(),
2302 if (!NT_STATUS_IS_OK(nt_status
)) {
2303 werr
= ntstatus_to_werror(nt_status
);
2307 nt_status
= SMB_VFS_CREATE_FILE(
2310 0, /* root_dir_fid */
2311 smb_fname
, /* fname */
2312 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2313 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2314 FILE_OPEN
, /* create_disposition*/
2315 0, /* create_options */
2316 0, /* file_attributes */
2317 INTERNAL_OPEN_ONLY
, /* oplock_request */
2318 0, /* allocation_size */
2319 0, /* private_flags */
2325 if (!NT_STATUS_IS_OK(nt_status
)) {
2326 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2327 smb_fname_str_dbg(smb_fname
)));
2328 werr
= ntstatus_to_werror(nt_status
);
2332 psd
= r
->in
.sd_buf
->sd
;
2333 security_info_sent
= r
->in
.securityinformation
;
2335 if (psd
->owner_sid
==0) {
2336 security_info_sent
&= ~SECINFO_OWNER
;
2338 if (psd
->group_sid
==0) {
2339 security_info_sent
&= ~SECINFO_GROUP
;
2342 security_info_sent
&= ~SECINFO_SACL
;
2345 security_info_sent
&= ~SECINFO_DACL
;
2348 /* Convert all the generic bits. */
2349 security_acl_map_generic(psd
->dacl
, &file_generic_mapping
);
2350 security_acl_map_generic(psd
->sacl
, &file_generic_mapping
);
2352 nt_status
= SMB_VFS_FSET_NT_ACL(fsp
,
2356 if (!NT_STATUS_IS_OK(nt_status
) ) {
2357 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2358 "on file %s\n", r
->in
.share
));
2359 werr
= WERR_ACCESS_DENIED
;
2363 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2364 vfs_ChDir(conn
, oldcwd
);
2365 SMB_VFS_DISCONNECT(conn
);
2373 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2377 vfs_ChDir(conn
, oldcwd
);
2381 SMB_VFS_DISCONNECT(conn
);
2386 TALLOC_FREE(smb_fname
);
2391 /***********************************************************************************
2392 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2393 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2394 These disks would the disks listed by this function.
2395 Users could then create shares relative to these disks. Watch out for moving these disks around.
2396 "Nigel Williams" <nigel@veritas.com>.
2397 ***********************************************************************************/
2399 static const char *server_disks
[] = {"C:"};
2401 static uint32
get_server_disk_count(void)
2403 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2406 static uint32
init_server_disk_enum(uint32
*resume
)
2408 uint32 server_disk_count
= get_server_disk_count();
2410 /*resume can be an offset into the list for now*/
2412 if(*resume
& 0x80000000)
2415 if(*resume
> server_disk_count
)
2416 *resume
= server_disk_count
;
2418 return server_disk_count
- *resume
;
2421 static const char *next_server_disk_enum(uint32
*resume
)
2425 if(init_server_disk_enum(resume
) == 0)
2428 disk
= server_disks
[*resume
];
2432 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2437 /********************************************************************
2439 ********************************************************************/
2441 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2442 struct srvsvc_NetDiskEnum
*r
)
2445 const char *disk_name
;
2446 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2448 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2452 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2454 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2455 MAX_SERVER_DISK_ENTRIES
);
2456 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2458 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2460 r
->out
.info
->count
= 0;
2462 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2464 r
->out
.info
->count
++;
2466 /*copy disk name into a unicode string*/
2468 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2469 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2472 /* add a terminating null string. Is this there if there is more data to come? */
2474 r
->out
.info
->count
++;
2476 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2477 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2479 if (r
->out
.resume_handle
) {
2480 *r
->out
.resume_handle
= resume
;
2486 /********************************************************************
2487 _srvsvc_NetNameValidate
2488 ********************************************************************/
2490 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2491 struct srvsvc_NetNameValidate
*r
)
2493 switch (r
->in
.name_type
) {
2495 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2496 strlen_m(r
->in
.name
)))
2498 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2500 return WERR_INVALID_NAME
;
2505 return WERR_UNKNOWN_LEVEL
;
2511 /*******************************************************************
2512 ********************************************************************/
2514 struct enum_file_close_state
{
2515 struct srvsvc_NetFileClose
*r
;
2516 struct messaging_context
*msg_ctx
;
2519 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2520 const char *sharepath
, const char *fname
,
2521 void *private_data
)
2523 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2524 struct enum_file_close_state
*state
=
2525 (struct enum_file_close_state
*)private_data
;
2526 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2528 if (fid
!= state
->r
->in
.fid
) {
2529 return; /* Not this file. */
2532 if (!process_exists(e
->pid
) ) {
2536 /* Ok - send the close message. */
2537 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2539 share_mode_str(talloc_tos(), 0, e
) ));
2541 share_mode_entry_to_message(msg
, e
);
2543 state
->r
->out
.result
= ntstatus_to_werror(
2544 messaging_send_buf(state
->msg_ctx
,
2545 e
->pid
, MSG_SMB_CLOSE_FILE
,
2547 MSG_SMB_SHARE_MODE_ENTRY_SIZE
));
2550 /********************************************************************
2551 Close a file given a 32-bit file id.
2552 ********************************************************************/
2554 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2555 struct srvsvc_NetFileClose
*r
)
2557 struct enum_file_close_state state
;
2560 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2562 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2564 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2565 return WERR_ACCESS_DENIED
;
2568 /* enum_file_close_fn sends the close message to
2569 * the relevent smbd process. */
2571 r
->out
.result
= WERR_BADFILE
;
2573 state
.msg_ctx
= p
->msg_ctx
;
2574 share_mode_forall(enum_file_close_fn
, &state
);
2575 return r
->out
.result
;
2578 /********************************************************************
2579 ********************************************************************/
2581 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2582 struct srvsvc_NetCharDevEnum
*r
)
2584 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2585 return WERR_NOT_SUPPORTED
;
2588 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2589 struct srvsvc_NetCharDevGetInfo
*r
)
2591 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2592 return WERR_NOT_SUPPORTED
;
2595 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2596 struct srvsvc_NetCharDevControl
*r
)
2598 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2599 return WERR_NOT_SUPPORTED
;
2602 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2603 struct srvsvc_NetCharDevQEnum
*r
)
2605 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2606 return WERR_NOT_SUPPORTED
;
2609 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2610 struct srvsvc_NetCharDevQGetInfo
*r
)
2612 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2613 return WERR_NOT_SUPPORTED
;
2616 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2617 struct srvsvc_NetCharDevQSetInfo
*r
)
2619 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2620 return WERR_NOT_SUPPORTED
;
2623 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2624 struct srvsvc_NetCharDevQPurge
*r
)
2626 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2627 return WERR_NOT_SUPPORTED
;
2630 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2631 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2633 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2634 return WERR_NOT_SUPPORTED
;
2637 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2638 struct srvsvc_NetFileGetInfo
*r
)
2640 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2641 return WERR_NOT_SUPPORTED
;
2644 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2645 struct srvsvc_NetShareCheck
*r
)
2647 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2648 return WERR_NOT_SUPPORTED
;
2651 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2652 struct srvsvc_NetServerStatisticsGet
*r
)
2654 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2655 return WERR_NOT_SUPPORTED
;
2658 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2659 struct srvsvc_NetTransportAdd
*r
)
2661 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2662 return WERR_NOT_SUPPORTED
;
2665 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2666 struct srvsvc_NetTransportEnum
*r
)
2668 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2669 return WERR_NOT_SUPPORTED
;
2672 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2673 struct srvsvc_NetTransportDel
*r
)
2675 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2676 return WERR_NOT_SUPPORTED
;
2679 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2680 struct srvsvc_NetSetServiceBits
*r
)
2682 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2683 return WERR_NOT_SUPPORTED
;
2686 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2687 struct srvsvc_NetPathType
*r
)
2689 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2690 return WERR_NOT_SUPPORTED
;
2693 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2694 struct srvsvc_NetPathCanonicalize
*r
)
2696 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2697 return WERR_NOT_SUPPORTED
;
2700 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2701 struct srvsvc_NetPathCompare
*r
)
2703 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2704 return WERR_NOT_SUPPORTED
;
2707 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2708 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2710 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2711 return WERR_NOT_SUPPORTED
;
2714 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2715 struct srvsvc_NetPRNameCompare
*r
)
2717 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2718 return WERR_NOT_SUPPORTED
;
2721 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2722 struct srvsvc_NetShareDelStart
*r
)
2724 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2725 return WERR_NOT_SUPPORTED
;
2728 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2729 struct srvsvc_NetShareDelCommit
*r
)
2731 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2732 return WERR_NOT_SUPPORTED
;
2735 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2736 struct srvsvc_NetServerTransportAddEx
*r
)
2738 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2739 return WERR_NOT_SUPPORTED
;
2742 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2743 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2745 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2746 return WERR_NOT_SUPPORTED
;
2749 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2750 struct srvsvc_NETRDFSGETVERSION
*r
)
2752 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2753 return WERR_NOT_SUPPORTED
;
2756 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2757 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2759 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2760 return WERR_NOT_SUPPORTED
;
2763 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2764 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2766 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2767 return WERR_NOT_SUPPORTED
;
2770 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2771 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2773 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2774 return WERR_NOT_SUPPORTED
;
2777 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2778 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2780 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2781 return WERR_NOT_SUPPORTED
;
2784 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2785 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2787 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2788 return WERR_NOT_SUPPORTED
;
2791 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2792 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2794 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2795 return WERR_NOT_SUPPORTED
;
2798 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2799 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2801 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2802 return WERR_NOT_SUPPORTED
;
2805 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2806 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2808 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2809 return WERR_NOT_SUPPORTED
;
2812 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2813 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2815 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2816 return WERR_NOT_SUPPORTED
;
2819 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2820 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2822 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
2823 return WERR_NOT_SUPPORTED
;