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"
41 extern const struct generic_mapping file_generic_mapping
;
44 #define DBGC_CLASS DBGC_RPC_SRV
46 #define MAX_SERVER_DISK_ENTRIES 15
48 /* Use for enumerating connections, pipes, & files */
50 struct file_enum_count
{
53 struct srvsvc_NetFileCtr3
*ctr3
;
56 struct sess_file_count
{
62 /* Used to store pipe open records for NetFileEnum() */
64 struct pipe_open_rec
{
71 /****************************************************************************
72 Count the entries belonging to a service in the connection db.
73 ****************************************************************************/
75 static int pipe_enum_fn( struct db_record
*rec
, void *p
)
77 struct pipe_open_rec prec
;
78 struct file_enum_count
*fenum
= (struct file_enum_count
*)p
;
79 struct srvsvc_NetFileInfo3
*f
;
80 int i
= fenum
->ctr3
->count
;
81 char *fullpath
= NULL
;
85 value
= dbwrap_record_get_value(rec
);
87 if (value
.dsize
!= sizeof(struct pipe_open_rec
))
90 memcpy(&prec
, value
.dptr
, sizeof(struct pipe_open_rec
));
92 if ( !process_exists(prec
.pid
) ) {
96 username
= uidtoname(prec
.uid
);
98 if ((fenum
->username
!= NULL
)
99 && !strequal(username
, fenum
->username
)) {
103 fullpath
= talloc_asprintf(fenum
->ctx
, "\\PIPE\\%s", prec
.name
);
108 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
109 struct srvsvc_NetFileInfo3
, i
+1);
111 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
114 fenum
->ctr3
->array
= f
;
116 fenum
->ctr3
->array
[i
].fid
=
117 (((uint32_t)(procid_to_pid(&prec
.pid
))<<16) | prec
.pnum
);
118 fenum
->ctr3
->array
[i
].permissions
=
119 (FILE_READ_DATA
|FILE_WRITE_DATA
);
120 fenum
->ctr3
->array
[i
].num_locks
= 0;
121 fenum
->ctr3
->array
[i
].path
= fullpath
;
122 fenum
->ctr3
->array
[i
].user
= username
;
124 fenum
->ctr3
->count
++;
129 /*******************************************************************
130 ********************************************************************/
132 static WERROR
net_enum_pipes(TALLOC_CTX
*ctx
,
133 const char *username
,
134 struct srvsvc_NetFileCtr3
**ctr3
,
137 struct file_enum_count fenum
;
140 fenum
.username
= username
;
143 if (connections_traverse(pipe_enum_fn
, &fenum
) < 0) {
144 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
154 /*******************************************************************
155 ********************************************************************/
157 static void enum_file_fn( const struct share_mode_entry
*e
,
158 const char *sharepath
, const char *fname
,
161 struct file_enum_count
*fenum
=
162 (struct file_enum_count
*)private_data
;
164 struct srvsvc_NetFileInfo3
*f
;
165 int i
= fenum
->ctr3
->count
;
167 struct byte_range_lock
*brl
;
169 char *fullpath
= NULL
;
171 const char *username
;
173 /* If the pid was not found delete the entry from connections.tdb */
175 if ( !process_exists(e
->pid
) ) {
179 username
= uidtoname(e
->uid
);
181 if ((fenum
->username
!= NULL
)
182 && !strequal(username
, fenum
->username
)) {
186 f
= talloc_realloc(fenum
->ctx
, fenum
->ctr3
->array
,
187 struct srvsvc_NetFileInfo3
, i
+1);
189 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
192 fenum
->ctr3
->array
= f
;
194 /* need to count the number of locks on a file */
199 if ( (brl
= brl_get_locks(talloc_tos(), &fsp
)) != NULL
) {
200 num_locks
= brl
->num_locks
;
204 if ( strcmp( fname
, "." ) == 0 ) {
205 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s", sharepath
);
207 fullpath
= talloc_asprintf(fenum
->ctx
, "C:%s/%s",
213 string_replace( fullpath
, '/', '\\' );
215 /* mask out create (what ever that is) */
216 permissions
= e
->access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
218 /* now fill in the srvsvc_NetFileInfo3 struct */
220 fenum
->ctr3
->array
[i
].fid
=
221 (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
222 fenum
->ctr3
->array
[i
].permissions
= permissions
;
223 fenum
->ctr3
->array
[i
].num_locks
= num_locks
;
224 fenum
->ctr3
->array
[i
].path
= fullpath
;
225 fenum
->ctr3
->array
[i
].user
= username
;
227 fenum
->ctr3
->count
++;
230 /*******************************************************************
231 ********************************************************************/
233 static WERROR
net_enum_files(TALLOC_CTX
*ctx
,
234 const char *username
,
235 struct srvsvc_NetFileCtr3
**ctr3
,
238 struct file_enum_count f_enum_cnt
;
240 f_enum_cnt
.ctx
= ctx
;
241 f_enum_cnt
.username
= username
;
242 f_enum_cnt
.ctr3
= *ctr3
;
244 share_mode_forall( enum_file_fn
, (void *)&f_enum_cnt
);
246 *ctr3
= f_enum_cnt
.ctr3
;
251 /*******************************************************************
252 Utility function to get the 'type' of a share from an snum.
253 ********************************************************************/
254 static enum srvsvc_ShareType
get_share_type(int snum
)
256 /* work out the share type */
257 enum srvsvc_ShareType type
= STYPE_DISKTREE
;
259 if (lp_print_ok(snum
)) {
260 type
= lp_administrative_share(snum
)
261 ? STYPE_PRINTQ_HIDDEN
: STYPE_PRINTQ
;
263 if (strequal(lp_fstype(snum
), "IPC")) {
264 type
= lp_administrative_share(snum
)
265 ? STYPE_IPC_HIDDEN
: STYPE_IPC
;
270 /*******************************************************************
271 Fill in a share info level 0 structure.
272 ********************************************************************/
274 static void init_srv_share_info_0(struct pipes_struct
*p
,
275 struct srvsvc_NetShareInfo0
*r
, int snum
)
277 r
->name
= lp_servicename(snum
);
280 /*******************************************************************
281 Fill in a share info level 1 structure.
282 ********************************************************************/
284 static void init_srv_share_info_1(struct pipes_struct
*p
,
285 struct srvsvc_NetShareInfo1
*r
,
288 char *net_name
= lp_servicename(snum
);
289 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
292 remark
= talloc_sub_advanced(
293 p
->mem_ctx
, lp_servicename(snum
),
294 get_current_username(), lp_pathname(snum
),
295 p
->session_info
->unix_token
->uid
, get_current_username(),
300 r
->type
= get_share_type(snum
);
301 r
->comment
= remark
? remark
: "";
304 /*******************************************************************
305 Fill in a share info level 2 structure.
306 ********************************************************************/
308 static void init_srv_share_info_2(struct pipes_struct
*p
,
309 struct srvsvc_NetShareInfo2
*r
,
314 int max_connections
= lp_max_connections(snum
);
315 uint32_t max_uses
= max_connections
!=0 ? max_connections
: (uint32_t)-1;
316 char *net_name
= lp_servicename(snum
);
318 remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
320 remark
= talloc_sub_advanced(
321 p
->mem_ctx
, lp_servicename(snum
),
322 get_current_username(), lp_pathname(snum
),
323 p
->session_info
->unix_token
->uid
, get_current_username(),
326 path
= talloc_asprintf(p
->mem_ctx
,
327 "C:%s", lp_pathname(snum
));
331 * Change / to \\ so that win2k will see it as a valid path.
332 * This was added to enable use of browsing in win2k add
336 string_replace(path
, '/', '\\');
340 r
->type
= get_share_type(snum
);
341 r
->comment
= remark
? remark
: "";
343 r
->max_users
= max_uses
;
344 r
->current_users
= count_current_connections(net_name
, false);
345 r
->path
= path
? path
: "";
349 /*******************************************************************
350 Map any generic bits to file specific bits.
351 ********************************************************************/
353 static void map_generic_share_sd_bits(struct security_descriptor
*psd
)
356 struct security_acl
*ps_dacl
= NULL
;
365 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
366 struct security_ace
*psa
= &ps_dacl
->aces
[i
];
367 uint32 orig_mask
= psa
->access_mask
;
369 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
370 psa
->access_mask
|= orig_mask
;
374 /*******************************************************************
375 Fill in a share info level 501 structure.
376 ********************************************************************/
378 static void init_srv_share_info_501(struct pipes_struct
*p
,
379 struct srvsvc_NetShareInfo501
*r
, int snum
)
381 const char *net_name
= lp_servicename(snum
);
382 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
385 remark
= talloc_sub_advanced(
386 p
->mem_ctx
, lp_servicename(snum
),
387 get_current_username(), lp_pathname(snum
),
388 p
->session_info
->unix_token
->uid
, get_current_username(),
393 r
->type
= get_share_type(snum
);
394 r
->comment
= remark
? remark
: "";
395 r
->csc_policy
= (lp_csc_policy(snum
) << 4);
398 /*******************************************************************
399 Fill in a share info level 502 structure.
400 ********************************************************************/
402 static void init_srv_share_info_502(struct pipes_struct
*p
,
403 struct srvsvc_NetShareInfo502
*r
, int snum
)
405 const char *net_name
= lp_servicename(snum
);
407 struct security_descriptor
*sd
= NULL
;
408 struct sec_desc_buf
*sd_buf
= NULL
;
410 TALLOC_CTX
*ctx
= p
->mem_ctx
;
411 char *remark
= talloc_strdup(ctx
, lp_comment(snum
));
414 remark
= talloc_sub_advanced(
415 p
->mem_ctx
, lp_servicename(snum
),
416 get_current_username(), lp_pathname(snum
),
417 p
->session_info
->unix_token
->uid
, get_current_username(),
420 path
= talloc_asprintf(ctx
, "C:%s", lp_pathname(snum
));
423 * Change / to \\ so that win2k will see it as a valid path. This was added to
424 * enable use of browsing in win2k add share dialog.
426 string_replace(path
, '/', '\\');
429 sd
= get_share_security(ctx
, lp_servicename(snum
), &sd_size
);
431 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
434 r
->type
= get_share_type(snum
);
435 r
->comment
= remark
? remark
: "";
437 r
->max_users
= (uint32_t)-1;
438 r
->current_users
= 1; /* ??? */
439 r
->path
= path
? path
: "";
444 /***************************************************************************
445 Fill in a share info level 1004 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1004(struct pipes_struct
*p
,
449 struct srvsvc_NetShareInfo1004
*r
,
452 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
455 remark
= talloc_sub_advanced(
456 p
->mem_ctx
, lp_servicename(snum
),
457 get_current_username(), lp_pathname(snum
),
458 p
->session_info
->unix_token
->uid
, get_current_username(),
462 r
->comment
= remark
? remark
: "";
465 /***************************************************************************
466 Fill in a share info level 1005 structure.
467 ***************************************************************************/
469 static void init_srv_share_info_1005(struct pipes_struct
*p
,
470 struct srvsvc_NetShareInfo1005
*r
,
473 uint32_t dfs_flags
= 0;
475 if (lp_host_msdfs() && lp_msdfs_root(snum
)) {
476 dfs_flags
|= SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
479 dfs_flags
|= lp_csc_policy(snum
) << SHARE_1005_CSC_POLICY_SHIFT
;
481 r
->dfs_flags
= dfs_flags
;
484 /***************************************************************************
485 Fill in a share info level 1006 structure.
486 ***************************************************************************/
488 static void init_srv_share_info_1006(struct pipes_struct
*p
,
489 struct srvsvc_NetShareInfo1006
*r
,
492 r
->max_users
= (uint32_t)-1;
495 /***************************************************************************
496 Fill in a share info level 1007 structure.
497 ***************************************************************************/
499 static void init_srv_share_info_1007(struct pipes_struct
*p
,
500 struct srvsvc_NetShareInfo1007
*r
,
504 r
->alternate_directory_name
= "";
507 /*******************************************************************
508 Fill in a share info level 1501 structure.
509 ********************************************************************/
511 static void init_srv_share_info_1501(struct pipes_struct
*p
,
512 struct sec_desc_buf
**r
,
515 struct security_descriptor
*sd
;
516 struct sec_desc_buf
*sd_buf
= NULL
;
518 TALLOC_CTX
*ctx
= p
->mem_ctx
;
520 sd
= get_share_security(ctx
, lp_servicename(snum
), &sd_size
);
522 sd_buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, sd
);
528 /*******************************************************************
529 True if it ends in '$'.
530 ********************************************************************/
532 static bool is_hidden_share(int snum
)
534 const char *net_name
= lp_servicename(snum
);
536 return (net_name
[strlen(net_name
) - 1] == '$') ? True
: False
;
539 /*******************************************************************
540 Verify user is allowed to view share, access based enumeration
541 ********************************************************************/
542 static bool is_enumeration_allowed(struct pipes_struct
*p
,
545 if (!lp_access_based_share_enum(snum
))
548 return share_access_check(p
->session_info
->security_token
,
549 lp_servicename(snum
), FILE_READ_DATA
, NULL
);
552 /*******************************************************************
553 Fill in a share info structure.
554 ********************************************************************/
556 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
557 struct srvsvc_NetShareInfoCtr
*info_ctr
,
558 uint32_t *resume_handle_p
,
559 uint32_t *total_entries
,
563 int alloc_entries
= 0;
564 int num_services
= 0;
566 TALLOC_CTX
*ctx
= p
->mem_ctx
;
568 int valid_share_count
= 0;
570 union srvsvc_NetShareCtr ctr
;
571 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
573 DEBUG(5,("init_srv_share_info_ctr\n"));
575 /* Ensure all the usershares are loaded. */
577 load_usershare_shares(NULL
, connections_snum_used
);
578 load_registry_shares();
579 num_services
= lp_numservices();
582 allowed
= talloc_zero_array(ctx
, bool, num_services
);
583 W_ERROR_HAVE_NO_MEMORY(allowed
);
585 /* Count the number of entries. */
586 for (snum
= 0; snum
< num_services
; snum
++) {
587 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
588 is_enumeration_allowed(p
, snum
) &&
589 (all_shares
|| !is_hidden_share(snum
)) ) {
590 DEBUG(10, ("counting service %s\n",
591 lp_servicename(snum
) ? lp_servicename(snum
) : "(null)"));
592 allowed
[snum
] = true;
595 DEBUG(10, ("NOT counting service %s\n",
596 lp_servicename(snum
) ? lp_servicename(snum
) : "(null)"));
600 if (!num_entries
|| (resume_handle
>= num_entries
)) {
604 /* Calculate alloc entries. */
605 alloc_entries
= num_entries
- resume_handle
;
606 switch (info_ctr
->level
) {
608 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
609 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
611 ctr
.ctr0
->count
= alloc_entries
;
612 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
613 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
615 for (snum
= 0; snum
< num_services
; snum
++) {
617 (resume_handle
<= (i
+ valid_share_count
++)) ) {
618 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
625 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
626 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
628 ctr
.ctr1
->count
= alloc_entries
;
629 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
630 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
632 for (snum
= 0; snum
< num_services
; snum
++) {
634 (resume_handle
<= (i
+ valid_share_count
++)) ) {
635 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
642 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
643 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
645 ctr
.ctr2
->count
= alloc_entries
;
646 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
647 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
649 for (snum
= 0; snum
< num_services
; snum
++) {
651 (resume_handle
<= (i
+ valid_share_count
++)) ) {
652 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
659 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
660 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
662 ctr
.ctr501
->count
= alloc_entries
;
663 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
664 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
666 for (snum
= 0; snum
< num_services
; snum
++) {
668 (resume_handle
<= (i
+ valid_share_count
++)) ) {
669 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
676 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
677 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
679 ctr
.ctr502
->count
= alloc_entries
;
680 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
681 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
683 for (snum
= 0; snum
< num_services
; snum
++) {
685 (resume_handle
<= (i
+ valid_share_count
++)) ) {
686 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
693 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
694 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
696 ctr
.ctr1004
->count
= alloc_entries
;
697 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
698 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
700 for (snum
= 0; snum
< num_services
; snum
++) {
702 (resume_handle
<= (i
+ valid_share_count
++)) ) {
703 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
710 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
711 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
713 ctr
.ctr1005
->count
= alloc_entries
;
714 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
715 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
717 for (snum
= 0; snum
< num_services
; snum
++) {
719 (resume_handle
<= (i
+ valid_share_count
++)) ) {
720 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
727 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
728 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
730 ctr
.ctr1006
->count
= alloc_entries
;
731 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
732 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
734 for (snum
= 0; snum
< num_services
; snum
++) {
736 (resume_handle
<= (i
+ valid_share_count
++)) ) {
737 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
744 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
745 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
747 ctr
.ctr1007
->count
= alloc_entries
;
748 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
749 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
751 for (snum
= 0; snum
< num_services
; snum
++) {
753 (resume_handle
<= (i
+ valid_share_count
++)) ) {
754 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
761 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
762 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
764 ctr
.ctr1501
->count
= alloc_entries
;
765 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
766 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
768 for (snum
= 0; snum
< num_services
; snum
++) {
770 (resume_handle
<= (i
+ valid_share_count
++)) ) {
771 struct sec_desc_buf
*sd_buf
= NULL
;
772 init_srv_share_info_1501(p
, &sd_buf
, snum
);
773 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
780 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
782 return WERR_UNKNOWN_LEVEL
;
785 *total_entries
= alloc_entries
;
786 if (resume_handle_p
) {
788 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
790 *resume_handle_p
= num_entries
;
799 /*******************************************************************
800 fill in a sess info level 0 structure.
801 ********************************************************************/
803 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
804 struct srvsvc_NetSessCtr0
*ctr0
,
805 uint32_t *resume_handle_p
,
806 uint32_t *total_entries
)
808 struct sessionid
*session_list
;
809 uint32_t num_entries
= 0;
810 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
811 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
813 DEBUG(5,("init_srv_sess_info_0\n"));
816 if (resume_handle_p
) {
817 *resume_handle_p
= 0;
822 for (; resume_handle
< *total_entries
; resume_handle
++) {
824 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
826 struct srvsvc_NetSessInfo0
,
828 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
830 ctr0
->array
[num_entries
].client
=
831 session_list
[resume_handle
].remote_machine
;
836 ctr0
->count
= num_entries
;
838 if (resume_handle_p
) {
839 if (*resume_handle_p
>= *total_entries
) {
840 *resume_handle_p
= 0;
842 *resume_handle_p
= resume_handle
;
849 /*******************************************************************
850 ********************************************************************/
852 static void sess_file_fn( const struct share_mode_entry
*e
,
853 const char *sharepath
, const char *fname
,
856 struct sess_file_count
*sess
= (struct sess_file_count
*)data
;
858 if ( procid_equal(&e
->pid
, &sess
->pid
) && (sess
->uid
== e
->uid
) ) {
865 /*******************************************************************
866 ********************************************************************/
868 static int net_count_files( uid_t uid
, struct server_id pid
)
870 struct sess_file_count s_file_cnt
;
872 s_file_cnt
.count
= 0;
873 s_file_cnt
.uid
= uid
;
874 s_file_cnt
.pid
= pid
;
876 share_mode_forall( sess_file_fn
, &s_file_cnt
);
878 return s_file_cnt
.count
;
881 /*******************************************************************
882 fill in a sess info level 1 structure.
883 ********************************************************************/
885 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
886 struct srvsvc_NetSessCtr1
*ctr1
,
887 uint32_t *resume_handle_p
,
888 uint32_t *total_entries
)
890 struct sessionid
*session_list
;
891 uint32_t num_entries
= 0;
892 time_t now
= time(NULL
);
893 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
898 if (resume_handle_p
) {
899 *resume_handle_p
= 0;
904 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
906 for (; resume_handle
< *total_entries
; resume_handle
++) {
909 struct passwd
*pw
= getpwnam(session_list
[resume_handle
].username
);
913 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
914 session_list
[resume_handle
].username
));
918 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
919 num_files
= net_count_files(pw
->pw_uid
, session_list
[resume_handle
].pid
);
920 guest
= strequal( session_list
[resume_handle
].username
, lp_guestaccount() );
922 ctr1
->array
= talloc_realloc(p
->mem_ctx
,
924 struct srvsvc_NetSessInfo1
,
926 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
928 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
929 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
930 ctr1
->array
[num_entries
].num_open
= num_files
;
931 ctr1
->array
[num_entries
].time
= connect_time
;
932 ctr1
->array
[num_entries
].idle_time
= 0;
933 ctr1
->array
[num_entries
].user_flags
= guest
;
938 ctr1
->count
= num_entries
;
940 if (resume_handle_p
) {
941 if (*resume_handle_p
>= *total_entries
) {
942 *resume_handle_p
= 0;
944 *resume_handle_p
= resume_handle
;
951 /*******************************************************************
952 fill in a conn info level 0 structure.
953 ********************************************************************/
955 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
956 uint32_t *resume_handle_p
,
957 uint32_t *total_entries
)
959 uint32_t num_entries
= 0;
960 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
962 DEBUG(5,("init_srv_conn_info_0\n"));
965 if (resume_handle_p
) {
966 *resume_handle_p
= 0;
975 for (; resume_handle
< *total_entries
; resume_handle
++) {
977 ctr0
->array
= talloc_realloc(talloc_tos(),
979 struct srvsvc_NetConnInfo0
,
985 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
987 /* move on to creating next connection */
991 ctr0
->count
= num_entries
;
992 *total_entries
= num_entries
;
994 if (resume_handle_p
) {
995 if (*resume_handle_p
>= *total_entries
) {
996 *resume_handle_p
= 0;
998 *resume_handle_p
= resume_handle
;
1005 /*******************************************************************
1006 fill in a conn info level 1 structure.
1007 ********************************************************************/
1009 static WERROR
init_srv_conn_info_1(struct srvsvc_NetConnCtr1
*ctr1
,
1010 uint32_t *resume_handle_p
,
1011 uint32_t *total_entries
)
1013 uint32_t num_entries
= 0;
1014 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1016 DEBUG(5,("init_srv_conn_info_1\n"));
1019 if (resume_handle_p
) {
1020 *resume_handle_p
= 0;
1029 for (; resume_handle
< *total_entries
; resume_handle
++) {
1031 ctr1
->array
= talloc_realloc(talloc_tos(),
1033 struct srvsvc_NetConnInfo1
,
1039 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1040 ctr1
->array
[num_entries
].conn_type
= 0x3;
1041 ctr1
->array
[num_entries
].num_open
= 1;
1042 ctr1
->array
[num_entries
].num_users
= 1;
1043 ctr1
->array
[num_entries
].conn_time
= 3;
1044 ctr1
->array
[num_entries
].user
= "dummy_user";
1045 ctr1
->array
[num_entries
].share
= "IPC$";
1047 /* move on to creating next connection */
1051 ctr1
->count
= num_entries
;
1052 *total_entries
= num_entries
;
1054 if (resume_handle_p
) {
1055 if (*resume_handle_p
>= *total_entries
) {
1056 *resume_handle_p
= 0;
1058 *resume_handle_p
= resume_handle
;
1065 /*******************************************************************
1067 *******************************************************************/
1069 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1070 struct srvsvc_NetFileEnum
*r
)
1072 TALLOC_CTX
*ctx
= NULL
;
1073 struct srvsvc_NetFileCtr3
*ctr3
;
1074 uint32_t resume_hnd
= 0;
1077 switch (r
->in
.info_ctr
->level
) {
1081 return WERR_UNKNOWN_LEVEL
;
1084 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1085 p
->session_info
->security_token
)) {
1086 DEBUG(1, ("Enumerating files only allowed for "
1087 "administrators\n"));
1088 return WERR_ACCESS_DENIED
;
1092 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1094 werr
= WERR_INVALID_PARAM
;
1098 /* TODO -- Windows enumerates
1100 (c) open directories and files */
1102 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1103 if (!W_ERROR_IS_OK(werr
)) {
1107 werr
= net_enum_pipes(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1108 if (!W_ERROR_IS_OK(werr
)) {
1112 *r
->out
.totalentries
= ctr3
->count
;
1113 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1114 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1122 /*******************************************************************
1123 _srvsvc_NetSrvGetInfo
1124 ********************************************************************/
1126 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1127 struct srvsvc_NetSrvGetInfo
*r
)
1129 WERROR status
= WERR_OK
;
1131 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1133 if (!pipe_access_check(p
)) {
1134 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1135 return WERR_ACCESS_DENIED
;
1138 switch (r
->in
.level
) {
1140 /* Technically level 102 should only be available to
1141 Administrators but there isn't anything super-secret
1142 here, as most of it is made up. */
1145 struct srvsvc_NetSrvInfo102
*info102
;
1147 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1152 info102
->platform_id
= PLATFORM_ID_NT
;
1153 info102
->server_name
= lp_netbios_name();
1154 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1155 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1156 info102
->server_type
= lp_default_server_announce();
1157 info102
->comment
= string_truncate(lp_serverstring(),
1158 MAX_SERVER_STRING_LENGTH
);
1159 info102
->users
= 0xffffffff;
1160 info102
->disc
= 0xf;
1161 info102
->hidden
= 0;
1162 info102
->announce
= 240;
1163 info102
->anndelta
= 3000;
1164 info102
->licenses
= 100000;
1165 info102
->userpath
= "C:\\";
1167 r
->out
.info
->info102
= info102
;
1171 struct srvsvc_NetSrvInfo101
*info101
;
1173 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1178 info101
->platform_id
= PLATFORM_ID_NT
;
1179 info101
->server_name
= lp_netbios_name();
1180 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1181 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1182 info101
->server_type
= lp_default_server_announce();
1183 info101
->comment
= string_truncate(lp_serverstring(),
1184 MAX_SERVER_STRING_LENGTH
);
1186 r
->out
.info
->info101
= info101
;
1190 struct srvsvc_NetSrvInfo100
*info100
;
1192 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1197 info100
->platform_id
= PLATFORM_ID_NT
;
1198 info100
->server_name
= lp_netbios_name();
1200 r
->out
.info
->info100
= info100
;
1205 status
= WERR_UNKNOWN_LEVEL
;
1209 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1214 /*******************************************************************
1215 _srvsvc_NetSrvSetInfo
1216 ********************************************************************/
1218 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1219 struct srvsvc_NetSrvSetInfo
*r
)
1221 WERROR status
= WERR_OK
;
1223 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1225 /* Set up the net server set info structure. */
1227 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1232 /*******************************************************************
1234 ********************************************************************/
1236 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1237 struct srvsvc_NetConnEnum
*r
)
1241 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1243 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1244 p
->session_info
->security_token
)) {
1245 DEBUG(1, ("Enumerating connections only allowed for "
1246 "administrators\n"));
1247 return WERR_ACCESS_DENIED
;
1250 switch (r
->in
.info_ctr
->level
) {
1252 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1253 r
->in
.resume_handle
,
1254 r
->out
.totalentries
);
1257 werr
= init_srv_conn_info_1(r
->in
.info_ctr
->ctr
.ctr1
,
1258 r
->in
.resume_handle
,
1259 r
->out
.totalentries
);
1262 return WERR_UNKNOWN_LEVEL
;
1265 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1270 /*******************************************************************
1272 ********************************************************************/
1274 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1275 struct srvsvc_NetSessEnum
*r
)
1279 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1281 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1282 p
->session_info
->security_token
)) {
1283 DEBUG(1, ("Enumerating sessions only allowed for "
1284 "administrators\n"));
1285 return WERR_ACCESS_DENIED
;
1288 switch (r
->in
.info_ctr
->level
) {
1290 werr
= init_srv_sess_info_0(p
,
1291 r
->in
.info_ctr
->ctr
.ctr0
,
1292 r
->in
.resume_handle
,
1293 r
->out
.totalentries
);
1296 werr
= init_srv_sess_info_1(p
,
1297 r
->in
.info_ctr
->ctr
.ctr1
,
1298 r
->in
.resume_handle
,
1299 r
->out
.totalentries
);
1302 return WERR_UNKNOWN_LEVEL
;
1305 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1310 /*******************************************************************
1312 ********************************************************************/
1314 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1315 struct srvsvc_NetSessDel
*r
)
1317 struct sessionid
*session_list
;
1318 int num_sessions
, snum
;
1319 const char *username
;
1320 const char *machine
;
1321 bool not_root
= False
;
1324 username
= r
->in
.user
;
1325 machine
= r
->in
.client
;
1327 /* strip leading backslashes if any */
1328 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1332 num_sessions
= list_sessions(p
->mem_ctx
, &session_list
);
1334 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1336 werr
= WERR_ACCESS_DENIED
;
1338 /* fail out now if you are not root or not a domain admin */
1340 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1341 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1342 DOMAIN_RID_ADMINS
))) {
1347 for (snum
= 0; snum
< num_sessions
; snum
++) {
1349 if ((strequal(session_list
[snum
].username
, username
) || username
[0] == '\0' ) &&
1350 strequal(session_list
[snum
].remote_machine
, machine
)) {
1354 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1359 ntstat
= messaging_send(p
->msg_ctx
,
1360 session_list
[snum
].pid
,
1361 MSG_SHUTDOWN
, &data_blob_null
);
1363 if (NT_STATUS_IS_OK(ntstat
))
1371 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1378 /*******************************************************************
1379 _srvsvc_NetShareEnumAll
1380 ********************************************************************/
1382 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1383 struct srvsvc_NetShareEnumAll
*r
)
1387 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1389 if (!pipe_access_check(p
)) {
1390 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1391 return WERR_ACCESS_DENIED
;
1394 /* Create the list of shares for the response. */
1395 werr
= init_srv_share_info_ctr(p
,
1397 r
->in
.resume_handle
,
1398 r
->out
.totalentries
,
1401 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1406 /*******************************************************************
1407 _srvsvc_NetShareEnum
1408 ********************************************************************/
1410 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1411 struct srvsvc_NetShareEnum
*r
)
1415 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1417 if (!pipe_access_check(p
)) {
1418 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1419 return WERR_ACCESS_DENIED
;
1422 /* Create the list of shares for the response. */
1423 werr
= init_srv_share_info_ctr(p
,
1425 r
->in
.resume_handle
,
1426 r
->out
.totalentries
,
1429 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1434 /*******************************************************************
1435 _srvsvc_NetShareGetInfo
1436 ********************************************************************/
1438 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1439 struct srvsvc_NetShareGetInfo
*r
)
1441 WERROR status
= WERR_OK
;
1442 char *share_name
= NULL
;
1444 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1446 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1448 if (!r
->in
.share_name
) {
1449 return WERR_INVALID_NAME
;
1452 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1457 return WERR_INVALID_NAME
;
1460 switch (r
->in
.level
) {
1462 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1463 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1464 init_srv_share_info_0(p
, info
->info0
, snum
);
1467 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1468 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1469 init_srv_share_info_1(p
, info
->info1
, snum
);
1472 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1473 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1474 init_srv_share_info_2(p
, info
->info2
, snum
);
1477 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1478 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1479 init_srv_share_info_501(p
, info
->info501
, snum
);
1482 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1483 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1484 init_srv_share_info_502(p
, info
->info502
, snum
);
1487 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1488 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1489 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1492 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1493 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1494 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1497 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1498 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1499 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1502 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1503 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1504 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1507 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1510 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1512 status
= WERR_UNKNOWN_LEVEL
;
1516 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1521 /*******************************************************************
1522 _srvsvc_NetShareSetInfo. Modify share details.
1523 ********************************************************************/
1525 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1526 struct srvsvc_NetShareSetInfo
*r
)
1528 char *command
= NULL
;
1529 char *share_name
= NULL
;
1530 char *comment
= NULL
;
1531 const char *pathname
= NULL
;
1536 struct security_descriptor
*psd
= NULL
;
1537 bool is_disk_op
= False
;
1538 int max_connections
= 0;
1539 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1540 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1542 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1544 if (!r
->in
.share_name
) {
1545 return WERR_INVALID_NAME
;
1548 if (r
->out
.parm_error
) {
1549 *r
->out
.parm_error
= 0;
1552 if ( strequal(r
->in
.share_name
,"IPC$")
1553 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1554 || strequal(r
->in
.share_name
,"global") )
1556 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1557 "modified by a remote user.\n",
1558 r
->in
.share_name
));
1559 return WERR_ACCESS_DENIED
;
1562 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1567 /* Does this share exist ? */
1569 return WERR_NET_NAME_NOT_FOUND
;
1571 /* No change to printer shares. */
1572 if (lp_print_ok(snum
))
1573 return WERR_ACCESS_DENIED
;
1575 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1577 /* fail out now if you are not root and not a disk op */
1579 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1580 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1581 "SeDiskOperatorPrivilege privilege needed to modify "
1583 (unsigned int)p
->session_info
->unix_token
->uid
,
1585 return WERR_ACCESS_DENIED
;
1588 switch (r
->in
.level
) {
1590 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1591 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1592 type
= info
->info1
->type
;
1596 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1597 pathname
= info
->info2
->path
;
1598 type
= info
->info2
->type
;
1599 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1600 0 : info
->info2
->max_users
;
1604 /* not supported on set but here for completeness */
1606 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1607 type
= info
->info501
->type
;
1612 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1613 pathname
= info
->info502
->path
;
1614 type
= info
->info502
->type
;
1615 psd
= info
->info502
->sd_buf
.sd
;
1616 map_generic_share_sd_bits(psd
);
1619 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1620 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1621 type
= STYPE_DISKTREE
;
1624 /* XP re-sets the csc policy even if it wasn't changed by the
1625 user, so we must compare it to see if it's what is set in
1626 smb.conf, so that we can contine other ops like setting
1628 if (((info
->info1005
->dfs_flags
&
1629 SHARE_1005_CSC_POLICY_MASK
) >>
1630 SHARE_1005_CSC_POLICY_SHIFT
) == lp_csc_policy(snum
))
1633 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1634 return WERR_ACCESS_DENIED
;
1638 return WERR_ACCESS_DENIED
;
1640 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1641 comment
= talloc_strdup(ctx
, lp_comment(snum
));
1642 psd
= info
->info1501
->sd
;
1643 map_generic_share_sd_bits(psd
);
1644 type
= STYPE_DISKTREE
;
1647 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1649 return WERR_UNKNOWN_LEVEL
;
1652 /* We can only modify disk shares. */
1653 if (type
!= STYPE_DISKTREE
) {
1654 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1657 return WERR_ACCESS_DENIED
;
1660 if (comment
== NULL
) {
1664 /* Check if the pathname is valid. */
1665 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1666 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1668 return WERR_OBJECT_PATH_INVALID
;
1671 /* Ensure share name, pathname and comment don't contain '"' characters. */
1672 string_replace(share_name
, '"', ' ');
1673 string_replace(path
, '"', ' ');
1674 string_replace(comment
, '"', ' ');
1676 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1677 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1679 /* Only call modify function if something changed. */
1681 if (strcmp(path
, lp_pathname(snum
)) || strcmp(comment
, lp_comment(snum
))
1682 || (lp_max_connections(snum
) != max_connections
)) {
1683 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1684 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1685 return WERR_ACCESS_DENIED
;
1688 command
= talloc_asprintf(p
->mem_ctx
,
1689 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1690 lp_change_share_cmd(),
1691 get_dyn_CONFIGFILE(),
1694 comment
? comment
: "",
1700 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1702 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1707 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1708 /* Tell everyone we updated smb.conf. */
1709 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1716 /********* END SeDiskOperatorPrivilege BLOCK *********/
1718 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1721 TALLOC_FREE(command
);
1724 return WERR_ACCESS_DENIED
;
1726 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1730 /* Replace SD if changed. */
1732 struct security_descriptor
*old_sd
;
1735 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(snum
), &sd_size
);
1737 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1738 if (!set_share_security(share_name
, psd
))
1739 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1744 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1749 /*******************************************************************
1750 _srvsvc_NetShareAdd.
1751 Call 'add_share_command "sharename" "pathname"
1752 "comment" "max connections = "
1753 ********************************************************************/
1755 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1756 struct srvsvc_NetShareAdd
*r
)
1758 char *command
= NULL
;
1759 char *share_name_in
= NULL
;
1760 char *share_name
= NULL
;
1761 char *comment
= NULL
;
1762 char *pathname
= NULL
;
1767 struct security_descriptor
*psd
= NULL
;
1769 int max_connections
= 0;
1770 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1772 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1774 if (r
->out
.parm_error
) {
1775 *r
->out
.parm_error
= 0;
1778 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1780 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1781 return WERR_ACCESS_DENIED
;
1783 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1784 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1785 return WERR_ACCESS_DENIED
;
1788 switch (r
->in
.level
) {
1790 /* No path. Not enough info in a level 0 to do anything. */
1791 return WERR_ACCESS_DENIED
;
1793 /* Not enough info in a level 1 to do anything. */
1794 return WERR_ACCESS_DENIED
;
1796 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1797 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1798 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1799 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1800 0 : r
->in
.info
->info2
->max_users
;
1801 type
= r
->in
.info
->info2
->type
;
1804 /* No path. Not enough info in a level 501 to do anything. */
1805 return WERR_ACCESS_DENIED
;
1807 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1808 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1809 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1810 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1811 0 : r
->in
.info
->info502
->max_users
;
1812 type
= r
->in
.info
->info502
->type
;
1813 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1814 map_generic_share_sd_bits(psd
);
1817 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1823 return WERR_ACCESS_DENIED
;
1825 /* DFS only level. */
1826 return WERR_ACCESS_DENIED
;
1828 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1830 return WERR_UNKNOWN_LEVEL
;
1833 /* check for invalid share names */
1835 if (!share_name_in
|| !validate_net_name(share_name_in
,
1836 INVALID_SHARENAME_CHARS
,
1837 strlen(share_name_in
))) {
1838 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1839 share_name_in
? share_name_in
: ""));
1840 return WERR_INVALID_NAME
;
1843 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
1844 || (lp_enable_asu_support() &&
1845 strequal(share_name_in
,"ADMIN$"))) {
1846 return WERR_ACCESS_DENIED
;
1849 snum
= find_service(ctx
, share_name_in
, &share_name
);
1854 /* Share already exists. */
1856 return WERR_FILE_EXISTS
;
1859 /* We can only add disk shares. */
1860 if (type
!= STYPE_DISKTREE
) {
1861 return WERR_ACCESS_DENIED
;
1864 /* Check if the pathname is valid. */
1865 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1866 return WERR_OBJECT_PATH_INVALID
;
1869 /* Ensure share name, pathname and comment don't contain '"' characters. */
1870 string_replace(share_name_in
, '"', ' ');
1871 string_replace(share_name
, '"', ' ');
1872 string_replace(path
, '"', ' ');
1874 string_replace(comment
, '"', ' ');
1877 command
= talloc_asprintf(ctx
,
1878 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1880 get_dyn_CONFIGFILE(),
1883 comment
? comment
: "",
1889 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
1891 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1896 /* FIXME: use libnetconf here - gd */
1898 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1899 /* Tell everyone we updated smb.conf. */
1900 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
1907 /********* END SeDiskOperatorPrivilege BLOCK *********/
1909 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1912 TALLOC_FREE(command
);
1915 return WERR_ACCESS_DENIED
;
1918 /* Note we use share_name here, not share_name_in as
1919 we need a canonicalized name for setting security. */
1920 if (!set_share_security(share_name
, psd
)) {
1921 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1927 * We don't call reload_services() here, the message will
1928 * cause this to be done before the next packet is read
1929 * from the client. JRA.
1932 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1937 /*******************************************************************
1939 Call "delete share command" with the share name as
1941 ********************************************************************/
1943 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
1944 struct srvsvc_NetShareDel
*r
)
1946 char *command
= NULL
;
1947 char *share_name
= NULL
;
1951 struct share_params
*params
;
1952 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1954 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
1956 if (!r
->in
.share_name
) {
1957 return WERR_NET_NAME_NOT_FOUND
;
1960 if ( strequal(r
->in
.share_name
,"IPC$")
1961 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1962 || strequal(r
->in
.share_name
,"global") )
1964 return WERR_ACCESS_DENIED
;
1967 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1973 return WERR_NO_SUCH_SHARE
;
1976 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
1977 return WERR_NO_SUCH_SHARE
;
1980 /* No change to printer shares. */
1981 if (lp_print_ok(snum
))
1982 return WERR_ACCESS_DENIED
;
1984 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1986 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1987 return WERR_ACCESS_DENIED
;
1989 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1990 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1991 return WERR_ACCESS_DENIED
;
1994 command
= talloc_asprintf(ctx
,
1996 lp_delete_share_cmd(),
1997 get_dyn_CONFIGFILE(),
1998 lp_servicename(snum
));
2003 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
2005 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2010 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2011 /* Tell everyone we updated smb.conf. */
2012 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2019 /********* END SeDiskOperatorPrivilege BLOCK *********/
2021 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2024 return WERR_ACCESS_DENIED
;
2026 /* Delete the SD in the database. */
2027 delete_share_security(lp_servicename(params
->service
));
2029 lp_killservice(params
->service
);
2034 /*******************************************************************
2035 _srvsvc_NetShareDelSticky
2036 ********************************************************************/
2038 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2039 struct srvsvc_NetShareDelSticky
*r
)
2041 struct srvsvc_NetShareDel q
;
2043 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2045 q
.in
.server_unc
= r
->in
.server_unc
;
2046 q
.in
.share_name
= r
->in
.share_name
;
2047 q
.in
.reserved
= r
->in
.reserved
;
2049 return _srvsvc_NetShareDel(p
, &q
);
2052 /*******************************************************************
2053 _srvsvc_NetRemoteTOD
2054 ********************************************************************/
2056 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2057 struct srvsvc_NetRemoteTOD
*r
)
2059 struct srvsvc_NetRemoteTODInfo
*tod
;
2061 time_t unixdate
= time(NULL
);
2063 /* We do this call first as if we do it *after* the gmtime call
2064 it overwrites the pointed-to values. JRA */
2066 uint32 zone
= get_time_zone(unixdate
)/60;
2068 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2070 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2075 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2077 t
= gmtime(&unixdate
);
2080 tod
->elapsed
= unixdate
;
2082 tod
->hours
= t
->tm_hour
;
2083 tod
->mins
= t
->tm_min
;
2084 tod
->secs
= t
->tm_sec
;
2086 tod
->timezone
= zone
;
2087 tod
->tinterval
= 10000;
2088 tod
->day
= t
->tm_mday
;
2089 tod
->month
= t
->tm_mon
+ 1;
2090 tod
->year
= 1900+t
->tm_year
;
2091 tod
->weekday
= t
->tm_wday
;
2093 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2098 /***********************************************************************************
2099 _srvsvc_NetGetFileSecurity
2100 Win9x NT tools get security descriptor.
2101 ***********************************************************************************/
2103 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2104 struct srvsvc_NetGetFileSecurity
*r
)
2106 struct smb_filename
*smb_fname
= NULL
;
2107 struct security_descriptor
*psd
= NULL
;
2109 char *servicename
= NULL
;
2113 connection_struct
*conn
= NULL
;
2114 struct sec_desc_buf
*sd_buf
= NULL
;
2115 files_struct
*fsp
= NULL
;
2117 char *oldcwd
= NULL
;
2122 werr
= WERR_NET_NAME_NOT_FOUND
;
2125 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2131 DEBUG(10, ("Could not find service %s\n", servicename
));
2132 werr
= WERR_NET_NAME_NOT_FOUND
;
2136 nt_status
= create_conn_struct(talloc_tos(),
2137 server_event_context(),
2138 server_messaging_context(),
2140 snum
, lp_pathname(snum
),
2141 p
->session_info
, &oldcwd
);
2142 if (!NT_STATUS_IS_OK(nt_status
)) {
2143 DEBUG(10, ("create_conn_struct failed: %s\n",
2144 nt_errstr(nt_status
)));
2145 werr
= ntstatus_to_werror(nt_status
);
2149 nt_status
= filename_convert(talloc_tos(),
2156 if (!NT_STATUS_IS_OK(nt_status
)) {
2157 werr
= ntstatus_to_werror(nt_status
);
2161 nt_status
= SMB_VFS_CREATE_FILE(
2164 0, /* root_dir_fid */
2165 smb_fname
, /* fname */
2166 FILE_READ_ATTRIBUTES
, /* access_mask */
2167 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2168 FILE_OPEN
, /* create_disposition*/
2169 0, /* create_options */
2170 0, /* file_attributes */
2171 INTERNAL_OPEN_ONLY
, /* oplock_request */
2172 0, /* allocation_size */
2173 0, /* private_flags */
2179 if (!NT_STATUS_IS_OK(nt_status
)) {
2180 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2181 smb_fname_str_dbg(smb_fname
)));
2182 werr
= ntstatus_to_werror(nt_status
);
2186 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2189 |SECINFO_DACL
), &psd
);
2191 if (!NT_STATUS_IS_OK(nt_status
)) {
2192 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2193 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2194 werr
= ntstatus_to_werror(nt_status
);
2198 sd_size
= ndr_size_security_descriptor(psd
, 0);
2200 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2206 sd_buf
->sd_size
= sd_size
;
2209 *r
->out
.sd_buf
= sd_buf
;
2211 psd
->dacl
->revision
= NT4_ACL_REVISION
;
2213 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2214 vfs_ChDir(conn
, oldcwd
);
2215 SMB_VFS_DISCONNECT(conn
);
2223 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2227 vfs_ChDir(conn
, oldcwd
);
2231 SMB_VFS_DISCONNECT(conn
);
2236 TALLOC_FREE(smb_fname
);
2241 /***********************************************************************************
2242 _srvsvc_NetSetFileSecurity
2243 Win9x NT tools set security descriptor.
2244 ***********************************************************************************/
2246 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2247 struct srvsvc_NetSetFileSecurity
*r
)
2249 struct smb_filename
*smb_fname
= NULL
;
2250 char *servicename
= NULL
;
2251 files_struct
*fsp
= NULL
;
2255 connection_struct
*conn
= NULL
;
2257 char *oldcwd
= NULL
;
2258 struct security_descriptor
*psd
= NULL
;
2259 uint32_t security_info_sent
= 0;
2264 werr
= WERR_NET_NAME_NOT_FOUND
;
2268 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2275 DEBUG(10, ("Could not find service %s\n", servicename
));
2276 werr
= WERR_NET_NAME_NOT_FOUND
;
2280 nt_status
= create_conn_struct(talloc_tos(),
2281 server_event_context(),
2282 server_messaging_context(),
2284 snum
, lp_pathname(snum
),
2285 p
->session_info
, &oldcwd
);
2286 if (!NT_STATUS_IS_OK(nt_status
)) {
2287 DEBUG(10, ("create_conn_struct failed: %s\n",
2288 nt_errstr(nt_status
)));
2289 werr
= ntstatus_to_werror(nt_status
);
2293 nt_status
= filename_convert(talloc_tos(),
2300 if (!NT_STATUS_IS_OK(nt_status
)) {
2301 werr
= ntstatus_to_werror(nt_status
);
2305 nt_status
= SMB_VFS_CREATE_FILE(
2308 0, /* root_dir_fid */
2309 smb_fname
, /* fname */
2310 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2311 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2312 FILE_OPEN
, /* create_disposition*/
2313 0, /* create_options */
2314 0, /* file_attributes */
2315 INTERNAL_OPEN_ONLY
, /* oplock_request */
2316 0, /* allocation_size */
2317 0, /* private_flags */
2323 if (!NT_STATUS_IS_OK(nt_status
)) {
2324 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2325 smb_fname_str_dbg(smb_fname
)));
2326 werr
= ntstatus_to_werror(nt_status
);
2330 psd
= r
->in
.sd_buf
->sd
;
2331 security_info_sent
= r
->in
.securityinformation
;
2333 if (psd
->owner_sid
==0) {
2334 security_info_sent
&= ~SECINFO_OWNER
;
2336 if (psd
->group_sid
==0) {
2337 security_info_sent
&= ~SECINFO_GROUP
;
2340 security_info_sent
&= ~SECINFO_SACL
;
2343 security_info_sent
&= ~SECINFO_DACL
;
2346 /* Convert all the generic bits. */
2347 security_acl_map_generic(psd
->dacl
, &file_generic_mapping
);
2348 security_acl_map_generic(psd
->sacl
, &file_generic_mapping
);
2350 nt_status
= SMB_VFS_FSET_NT_ACL(fsp
,
2354 if (!NT_STATUS_IS_OK(nt_status
) ) {
2355 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2356 "on file %s\n", r
->in
.share
));
2357 werr
= WERR_ACCESS_DENIED
;
2361 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2362 vfs_ChDir(conn
, oldcwd
);
2363 SMB_VFS_DISCONNECT(conn
);
2371 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2375 vfs_ChDir(conn
, oldcwd
);
2379 SMB_VFS_DISCONNECT(conn
);
2384 TALLOC_FREE(smb_fname
);
2389 /***********************************************************************************
2390 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2391 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2392 These disks would the disks listed by this function.
2393 Users could then create shares relative to these disks. Watch out for moving these disks around.
2394 "Nigel Williams" <nigel@veritas.com>.
2395 ***********************************************************************************/
2397 static const char *server_disks
[] = {"C:"};
2399 static uint32
get_server_disk_count(void)
2401 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2404 static uint32
init_server_disk_enum(uint32
*resume
)
2406 uint32 server_disk_count
= get_server_disk_count();
2408 /*resume can be an offset into the list for now*/
2410 if(*resume
& 0x80000000)
2413 if(*resume
> server_disk_count
)
2414 *resume
= server_disk_count
;
2416 return server_disk_count
- *resume
;
2419 static const char *next_server_disk_enum(uint32
*resume
)
2423 if(init_server_disk_enum(resume
) == 0)
2426 disk
= server_disks
[*resume
];
2430 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2435 /********************************************************************
2437 ********************************************************************/
2439 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2440 struct srvsvc_NetDiskEnum
*r
)
2443 const char *disk_name
;
2444 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2446 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2450 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2452 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2453 MAX_SERVER_DISK_ENTRIES
);
2454 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2456 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2458 r
->out
.info
->count
= 0;
2460 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2462 r
->out
.info
->count
++;
2464 /*copy disk name into a unicode string*/
2466 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2467 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2470 /* add a terminating null string. Is this there if there is more data to come? */
2472 r
->out
.info
->count
++;
2474 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2475 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2477 if (r
->out
.resume_handle
) {
2478 *r
->out
.resume_handle
= resume
;
2484 /********************************************************************
2485 _srvsvc_NetNameValidate
2486 ********************************************************************/
2488 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2489 struct srvsvc_NetNameValidate
*r
)
2491 switch (r
->in
.name_type
) {
2493 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2494 strlen_m(r
->in
.name
)))
2496 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2498 return WERR_INVALID_NAME
;
2503 return WERR_UNKNOWN_LEVEL
;
2509 /*******************************************************************
2510 ********************************************************************/
2512 struct enum_file_close_state
{
2513 struct srvsvc_NetFileClose
*r
;
2514 struct messaging_context
*msg_ctx
;
2517 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2518 const char *sharepath
, const char *fname
,
2519 void *private_data
)
2521 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2522 struct enum_file_close_state
*state
=
2523 (struct enum_file_close_state
*)private_data
;
2524 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2526 if (fid
!= state
->r
->in
.fid
) {
2527 return; /* Not this file. */
2530 if (!process_exists(e
->pid
) ) {
2534 /* Ok - send the close message. */
2535 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2537 share_mode_str(talloc_tos(), 0, e
) ));
2539 share_mode_entry_to_message(msg
, e
);
2541 state
->r
->out
.result
= ntstatus_to_werror(
2542 messaging_send_buf(state
->msg_ctx
,
2543 e
->pid
, MSG_SMB_CLOSE_FILE
,
2545 MSG_SMB_SHARE_MODE_ENTRY_SIZE
));
2548 /********************************************************************
2549 Close a file given a 32-bit file id.
2550 ********************************************************************/
2552 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2553 struct srvsvc_NetFileClose
*r
)
2555 struct enum_file_close_state state
;
2558 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2560 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2562 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2563 return WERR_ACCESS_DENIED
;
2566 /* enum_file_close_fn sends the close message to
2567 * the relevent smbd process. */
2569 r
->out
.result
= WERR_BADFILE
;
2571 state
.msg_ctx
= p
->msg_ctx
;
2572 share_mode_forall(enum_file_close_fn
, &state
);
2573 return r
->out
.result
;
2576 /********************************************************************
2577 ********************************************************************/
2579 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2580 struct srvsvc_NetCharDevEnum
*r
)
2582 p
->rng_fault_state
= True
;
2583 return WERR_NOT_SUPPORTED
;
2586 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2587 struct srvsvc_NetCharDevGetInfo
*r
)
2589 p
->rng_fault_state
= True
;
2590 return WERR_NOT_SUPPORTED
;
2593 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2594 struct srvsvc_NetCharDevControl
*r
)
2596 p
->rng_fault_state
= True
;
2597 return WERR_NOT_SUPPORTED
;
2600 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2601 struct srvsvc_NetCharDevQEnum
*r
)
2603 p
->rng_fault_state
= True
;
2604 return WERR_NOT_SUPPORTED
;
2607 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2608 struct srvsvc_NetCharDevQGetInfo
*r
)
2610 p
->rng_fault_state
= True
;
2611 return WERR_NOT_SUPPORTED
;
2614 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2615 struct srvsvc_NetCharDevQSetInfo
*r
)
2617 p
->rng_fault_state
= True
;
2618 return WERR_NOT_SUPPORTED
;
2621 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2622 struct srvsvc_NetCharDevQPurge
*r
)
2624 p
->rng_fault_state
= True
;
2625 return WERR_NOT_SUPPORTED
;
2628 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2629 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2631 p
->rng_fault_state
= True
;
2632 return WERR_NOT_SUPPORTED
;
2635 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2636 struct srvsvc_NetFileGetInfo
*r
)
2638 p
->rng_fault_state
= True
;
2639 return WERR_NOT_SUPPORTED
;
2642 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2643 struct srvsvc_NetShareCheck
*r
)
2645 p
->rng_fault_state
= True
;
2646 return WERR_NOT_SUPPORTED
;
2649 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2650 struct srvsvc_NetServerStatisticsGet
*r
)
2652 p
->rng_fault_state
= True
;
2653 return WERR_NOT_SUPPORTED
;
2656 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2657 struct srvsvc_NetTransportAdd
*r
)
2659 p
->rng_fault_state
= True
;
2660 return WERR_NOT_SUPPORTED
;
2663 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2664 struct srvsvc_NetTransportEnum
*r
)
2666 p
->rng_fault_state
= True
;
2667 return WERR_NOT_SUPPORTED
;
2670 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2671 struct srvsvc_NetTransportDel
*r
)
2673 p
->rng_fault_state
= True
;
2674 return WERR_NOT_SUPPORTED
;
2677 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2678 struct srvsvc_NetSetServiceBits
*r
)
2680 p
->rng_fault_state
= True
;
2681 return WERR_NOT_SUPPORTED
;
2684 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2685 struct srvsvc_NetPathType
*r
)
2687 p
->rng_fault_state
= True
;
2688 return WERR_NOT_SUPPORTED
;
2691 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2692 struct srvsvc_NetPathCanonicalize
*r
)
2694 p
->rng_fault_state
= True
;
2695 return WERR_NOT_SUPPORTED
;
2698 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2699 struct srvsvc_NetPathCompare
*r
)
2701 p
->rng_fault_state
= True
;
2702 return WERR_NOT_SUPPORTED
;
2705 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2706 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2708 p
->rng_fault_state
= True
;
2709 return WERR_NOT_SUPPORTED
;
2712 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2713 struct srvsvc_NetPRNameCompare
*r
)
2715 p
->rng_fault_state
= True
;
2716 return WERR_NOT_SUPPORTED
;
2719 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2720 struct srvsvc_NetShareDelStart
*r
)
2722 p
->rng_fault_state
= True
;
2723 return WERR_NOT_SUPPORTED
;
2726 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2727 struct srvsvc_NetShareDelCommit
*r
)
2729 p
->rng_fault_state
= True
;
2730 return WERR_NOT_SUPPORTED
;
2733 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2734 struct srvsvc_NetServerTransportAddEx
*r
)
2736 p
->rng_fault_state
= True
;
2737 return WERR_NOT_SUPPORTED
;
2740 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2741 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2743 p
->rng_fault_state
= True
;
2744 return WERR_NOT_SUPPORTED
;
2747 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2748 struct srvsvc_NETRDFSGETVERSION
*r
)
2750 p
->rng_fault_state
= True
;
2751 return WERR_NOT_SUPPORTED
;
2754 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2755 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2757 p
->rng_fault_state
= True
;
2758 return WERR_NOT_SUPPORTED
;
2761 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2762 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2764 p
->rng_fault_state
= True
;
2765 return WERR_NOT_SUPPORTED
;
2768 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2769 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2771 p
->rng_fault_state
= True
;
2772 return WERR_NOT_SUPPORTED
;
2775 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2776 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2778 p
->rng_fault_state
= True
;
2779 return WERR_NOT_SUPPORTED
;
2782 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2783 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2785 p
->rng_fault_state
= True
;
2786 return WERR_NOT_SUPPORTED
;
2789 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2790 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2792 p
->rng_fault_state
= True
;
2793 return WERR_NOT_SUPPORTED
;
2796 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2797 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2799 p
->rng_fault_state
= True
;
2800 return WERR_NOT_SUPPORTED
;
2803 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2804 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2806 p
->rng_fault_state
= True
;
2807 return WERR_NOT_SUPPORTED
;
2810 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2811 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2813 p
->rng_fault_state
= True
;
2814 return WERR_NOT_SUPPORTED
;
2817 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2818 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2820 p
->rng_fault_state
= True
;
2821 return WERR_NOT_SUPPORTED
;