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(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(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(snum
);
290 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
293 remark
= talloc_sub_advanced(
294 p
->mem_ctx
, lp_servicename(snum
),
295 get_current_username(), lp_pathname(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(snum
);
319 remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
321 remark
= talloc_sub_advanced(
322 p
->mem_ctx
, lp_servicename(snum
),
323 get_current_username(), lp_pathname(snum
),
324 p
->session_info
->unix_token
->uid
, get_current_username(),
327 path
= talloc_asprintf(p
->mem_ctx
,
328 "C:%s", lp_pathname(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(snum
);
383 char *remark
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
386 remark
= talloc_sub_advanced(
387 p
->mem_ctx
, lp_servicename(snum
),
388 get_current_username(), lp_pathname(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(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
= talloc_strdup(ctx
, lp_comment(snum
));
415 remark
= talloc_sub_advanced(
416 p
->mem_ctx
, lp_servicename(snum
),
417 get_current_username(), lp_pathname(snum
),
418 p
->session_info
->unix_token
->uid
, get_current_username(),
421 path
= talloc_asprintf(ctx
, "C:%s", lp_pathname(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(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
= talloc_strdup(p
->mem_ctx
, lp_comment(snum
));
456 remark
= talloc_sub_advanced(
457 p
->mem_ctx
, lp_servicename(snum
),
458 get_current_username(), lp_pathname(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(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(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(snum
), FILE_READ_DATA
, NULL
);
553 /*******************************************************************
554 Fill in a share info structure.
555 ********************************************************************/
557 static WERROR
init_srv_share_info_ctr(struct pipes_struct
*p
,
558 struct srvsvc_NetShareInfoCtr
*info_ctr
,
559 uint32_t *resume_handle_p
,
560 uint32_t *total_entries
,
564 int alloc_entries
= 0;
565 int num_services
= 0;
567 TALLOC_CTX
*ctx
= p
->mem_ctx
;
569 int valid_share_count
= 0;
571 union srvsvc_NetShareCtr ctr
;
572 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
574 DEBUG(5,("init_srv_share_info_ctr\n"));
576 /* Ensure all the usershares are loaded. */
578 load_usershare_shares(NULL
, connections_snum_used
);
579 load_registry_shares();
580 num_services
= lp_numservices();
583 allowed
= talloc_zero_array(ctx
, bool, num_services
);
584 W_ERROR_HAVE_NO_MEMORY(allowed
);
586 /* Count the number of entries. */
587 for (snum
= 0; snum
< num_services
; snum
++) {
588 if (lp_browseable(snum
) && lp_snum_ok(snum
) &&
589 is_enumeration_allowed(p
, snum
) &&
590 (all_shares
|| !is_hidden_share(snum
)) ) {
591 DEBUG(10, ("counting service %s\n",
592 lp_servicename(snum
) ? lp_servicename(snum
) : "(null)"));
593 allowed
[snum
] = true;
596 DEBUG(10, ("NOT counting service %s\n",
597 lp_servicename(snum
) ? lp_servicename(snum
) : "(null)"));
601 if (!num_entries
|| (resume_handle
>= num_entries
)) {
605 /* Calculate alloc entries. */
606 alloc_entries
= num_entries
- resume_handle
;
607 switch (info_ctr
->level
) {
609 ctr
.ctr0
= talloc_zero(ctx
, struct srvsvc_NetShareCtr0
);
610 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
);
612 ctr
.ctr0
->count
= alloc_entries
;
613 ctr
.ctr0
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo0
, alloc_entries
);
614 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr0
->array
);
616 for (snum
= 0; snum
< num_services
; snum
++) {
618 (resume_handle
<= (i
+ valid_share_count
++)) ) {
619 init_srv_share_info_0(p
, &ctr
.ctr0
->array
[i
++], snum
);
626 ctr
.ctr1
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1
);
627 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
);
629 ctr
.ctr1
->count
= alloc_entries
;
630 ctr
.ctr1
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1
, alloc_entries
);
631 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1
->array
);
633 for (snum
= 0; snum
< num_services
; snum
++) {
635 (resume_handle
<= (i
+ valid_share_count
++)) ) {
636 init_srv_share_info_1(p
, &ctr
.ctr1
->array
[i
++], snum
);
643 ctr
.ctr2
= talloc_zero(ctx
, struct srvsvc_NetShareCtr2
);
644 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
);
646 ctr
.ctr2
->count
= alloc_entries
;
647 ctr
.ctr2
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo2
, alloc_entries
);
648 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr2
->array
);
650 for (snum
= 0; snum
< num_services
; snum
++) {
652 (resume_handle
<= (i
+ valid_share_count
++)) ) {
653 init_srv_share_info_2(p
, &ctr
.ctr2
->array
[i
++], snum
);
660 ctr
.ctr501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr501
);
661 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
);
663 ctr
.ctr501
->count
= alloc_entries
;
664 ctr
.ctr501
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo501
, alloc_entries
);
665 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr501
->array
);
667 for (snum
= 0; snum
< num_services
; snum
++) {
669 (resume_handle
<= (i
+ valid_share_count
++)) ) {
670 init_srv_share_info_501(p
, &ctr
.ctr501
->array
[i
++], snum
);
677 ctr
.ctr502
= talloc_zero(ctx
, struct srvsvc_NetShareCtr502
);
678 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
);
680 ctr
.ctr502
->count
= alloc_entries
;
681 ctr
.ctr502
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo502
, alloc_entries
);
682 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr502
->array
);
684 for (snum
= 0; snum
< num_services
; snum
++) {
686 (resume_handle
<= (i
+ valid_share_count
++)) ) {
687 init_srv_share_info_502(p
, &ctr
.ctr502
->array
[i
++], snum
);
694 ctr
.ctr1004
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1004
);
695 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
);
697 ctr
.ctr1004
->count
= alloc_entries
;
698 ctr
.ctr1004
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1004
, alloc_entries
);
699 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1004
->array
);
701 for (snum
= 0; snum
< num_services
; snum
++) {
703 (resume_handle
<= (i
+ valid_share_count
++)) ) {
704 init_srv_share_info_1004(p
, &ctr
.ctr1004
->array
[i
++], snum
);
711 ctr
.ctr1005
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1005
);
712 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
);
714 ctr
.ctr1005
->count
= alloc_entries
;
715 ctr
.ctr1005
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1005
, alloc_entries
);
716 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1005
->array
);
718 for (snum
= 0; snum
< num_services
; snum
++) {
720 (resume_handle
<= (i
+ valid_share_count
++)) ) {
721 init_srv_share_info_1005(p
, &ctr
.ctr1005
->array
[i
++], snum
);
728 ctr
.ctr1006
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1006
);
729 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
);
731 ctr
.ctr1006
->count
= alloc_entries
;
732 ctr
.ctr1006
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1006
, alloc_entries
);
733 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1006
->array
);
735 for (snum
= 0; snum
< num_services
; snum
++) {
737 (resume_handle
<= (i
+ valid_share_count
++)) ) {
738 init_srv_share_info_1006(p
, &ctr
.ctr1006
->array
[i
++], snum
);
745 ctr
.ctr1007
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1007
);
746 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
);
748 ctr
.ctr1007
->count
= alloc_entries
;
749 ctr
.ctr1007
->array
= talloc_zero_array(ctx
, struct srvsvc_NetShareInfo1007
, alloc_entries
);
750 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1007
->array
);
752 for (snum
= 0; snum
< num_services
; snum
++) {
754 (resume_handle
<= (i
+ valid_share_count
++)) ) {
755 init_srv_share_info_1007(p
, &ctr
.ctr1007
->array
[i
++], snum
);
762 ctr
.ctr1501
= talloc_zero(ctx
, struct srvsvc_NetShareCtr1501
);
763 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
);
765 ctr
.ctr1501
->count
= alloc_entries
;
766 ctr
.ctr1501
->array
= talloc_zero_array(ctx
, struct sec_desc_buf
, alloc_entries
);
767 W_ERROR_HAVE_NO_MEMORY(ctr
.ctr1501
->array
);
769 for (snum
= 0; snum
< num_services
; snum
++) {
771 (resume_handle
<= (i
+ valid_share_count
++)) ) {
772 struct sec_desc_buf
*sd_buf
= NULL
;
773 init_srv_share_info_1501(p
, &sd_buf
, snum
);
774 ctr
.ctr1501
->array
[i
++] = *sd_buf
;
781 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
783 return WERR_UNKNOWN_LEVEL
;
786 *total_entries
= alloc_entries
;
787 if (resume_handle_p
) {
789 *resume_handle_p
= (num_entries
== 0) ? *resume_handle_p
: 0;
791 *resume_handle_p
= num_entries
;
800 /*******************************************************************
801 fill in a sess info level 0 structure.
802 ********************************************************************/
804 static WERROR
init_srv_sess_info_0(struct pipes_struct
*p
,
805 struct srvsvc_NetSessCtr0
*ctr0
,
806 uint32_t *resume_handle_p
,
807 uint32_t *total_entries
)
809 struct sessionid
*session_list
;
810 uint32_t num_entries
= 0;
811 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
812 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
814 DEBUG(5,("init_srv_sess_info_0\n"));
817 if (resume_handle_p
) {
818 *resume_handle_p
= 0;
823 for (; resume_handle
< *total_entries
; resume_handle
++) {
825 ctr0
->array
= talloc_realloc(p
->mem_ctx
,
827 struct srvsvc_NetSessInfo0
,
829 W_ERROR_HAVE_NO_MEMORY(ctr0
->array
);
831 ctr0
->array
[num_entries
].client
=
832 session_list
[resume_handle
].remote_machine
;
837 ctr0
->count
= num_entries
;
839 if (resume_handle_p
) {
840 if (*resume_handle_p
>= *total_entries
) {
841 *resume_handle_p
= 0;
843 *resume_handle_p
= resume_handle
;
850 /*******************************************************************
851 ********************************************************************/
853 static void sess_file_fn( const struct share_mode_entry
*e
,
854 const char *sharepath
, const char *fname
,
857 struct sess_file_count
*sess
= (struct sess_file_count
*)data
;
859 if (serverid_equal(&e
->pid
, &sess
->pid
) && (sess
->uid
== e
->uid
)) {
866 /*******************************************************************
867 ********************************************************************/
869 static int net_count_files( uid_t uid
, struct server_id pid
)
871 struct sess_file_count s_file_cnt
;
873 s_file_cnt
.count
= 0;
874 s_file_cnt
.uid
= uid
;
875 s_file_cnt
.pid
= pid
;
877 share_mode_forall( sess_file_fn
, &s_file_cnt
);
879 return s_file_cnt
.count
;
882 /*******************************************************************
883 fill in a sess info level 1 structure.
884 ********************************************************************/
886 static WERROR
init_srv_sess_info_1(struct pipes_struct
*p
,
887 struct srvsvc_NetSessCtr1
*ctr1
,
888 uint32_t *resume_handle_p
,
889 uint32_t *total_entries
)
891 struct sessionid
*session_list
;
892 uint32_t num_entries
= 0;
893 time_t now
= time(NULL
);
894 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
899 if (resume_handle_p
) {
900 *resume_handle_p
= 0;
905 *total_entries
= list_sessions(p
->mem_ctx
, &session_list
);
907 for (; resume_handle
< *total_entries
; resume_handle
++) {
910 struct passwd
*pw
= getpwnam(session_list
[resume_handle
].username
);
914 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
915 session_list
[resume_handle
].username
));
919 connect_time
= (uint32_t)(now
- session_list
[resume_handle
].connect_start
);
920 num_files
= net_count_files(pw
->pw_uid
, session_list
[resume_handle
].pid
);
921 guest
= strequal( session_list
[resume_handle
].username
, lp_guestaccount() );
923 ctr1
->array
= talloc_realloc(p
->mem_ctx
,
925 struct srvsvc_NetSessInfo1
,
927 W_ERROR_HAVE_NO_MEMORY(ctr1
->array
);
929 ctr1
->array
[num_entries
].client
= session_list
[resume_handle
].remote_machine
;
930 ctr1
->array
[num_entries
].user
= session_list
[resume_handle
].username
;
931 ctr1
->array
[num_entries
].num_open
= num_files
;
932 ctr1
->array
[num_entries
].time
= connect_time
;
933 ctr1
->array
[num_entries
].idle_time
= 0;
934 ctr1
->array
[num_entries
].user_flags
= guest
;
939 ctr1
->count
= num_entries
;
941 if (resume_handle_p
) {
942 if (*resume_handle_p
>= *total_entries
) {
943 *resume_handle_p
= 0;
945 *resume_handle_p
= resume_handle
;
952 /*******************************************************************
953 fill in a conn info level 0 structure.
954 ********************************************************************/
956 static WERROR
init_srv_conn_info_0(struct srvsvc_NetConnCtr0
*ctr0
,
957 uint32_t *resume_handle_p
,
958 uint32_t *total_entries
)
960 uint32_t num_entries
= 0;
961 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
963 DEBUG(5,("init_srv_conn_info_0\n"));
966 if (resume_handle_p
) {
967 *resume_handle_p
= 0;
976 for (; resume_handle
< *total_entries
; resume_handle
++) {
978 ctr0
->array
= talloc_realloc(talloc_tos(),
980 struct srvsvc_NetConnInfo0
,
986 ctr0
->array
[num_entries
].conn_id
= *total_entries
;
988 /* move on to creating next connection */
992 ctr0
->count
= num_entries
;
993 *total_entries
= num_entries
;
995 if (resume_handle_p
) {
996 if (*resume_handle_p
>= *total_entries
) {
997 *resume_handle_p
= 0;
999 *resume_handle_p
= resume_handle
;
1006 /*******************************************************************
1007 fill in a conn info level 1 structure.
1008 ********************************************************************/
1010 static WERROR
init_srv_conn_info_1(struct srvsvc_NetConnCtr1
*ctr1
,
1011 uint32_t *resume_handle_p
,
1012 uint32_t *total_entries
)
1014 uint32_t num_entries
= 0;
1015 uint32_t resume_handle
= resume_handle_p
? *resume_handle_p
: 0;
1017 DEBUG(5,("init_srv_conn_info_1\n"));
1020 if (resume_handle_p
) {
1021 *resume_handle_p
= 0;
1030 for (; resume_handle
< *total_entries
; resume_handle
++) {
1032 ctr1
->array
= talloc_realloc(talloc_tos(),
1034 struct srvsvc_NetConnInfo1
,
1040 ctr1
->array
[num_entries
].conn_id
= *total_entries
;
1041 ctr1
->array
[num_entries
].conn_type
= 0x3;
1042 ctr1
->array
[num_entries
].num_open
= 1;
1043 ctr1
->array
[num_entries
].num_users
= 1;
1044 ctr1
->array
[num_entries
].conn_time
= 3;
1045 ctr1
->array
[num_entries
].user
= "dummy_user";
1046 ctr1
->array
[num_entries
].share
= "IPC$";
1048 /* move on to creating next connection */
1052 ctr1
->count
= num_entries
;
1053 *total_entries
= num_entries
;
1055 if (resume_handle_p
) {
1056 if (*resume_handle_p
>= *total_entries
) {
1057 *resume_handle_p
= 0;
1059 *resume_handle_p
= resume_handle
;
1066 /*******************************************************************
1068 *******************************************************************/
1070 WERROR
_srvsvc_NetFileEnum(struct pipes_struct
*p
,
1071 struct srvsvc_NetFileEnum
*r
)
1073 TALLOC_CTX
*ctx
= NULL
;
1074 struct srvsvc_NetFileCtr3
*ctr3
;
1075 uint32_t resume_hnd
= 0;
1078 switch (r
->in
.info_ctr
->level
) {
1082 return WERR_UNKNOWN_LEVEL
;
1085 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1086 p
->session_info
->security_token
)) {
1087 DEBUG(1, ("Enumerating files only allowed for "
1088 "administrators\n"));
1089 return WERR_ACCESS_DENIED
;
1093 ctr3
= r
->in
.info_ctr
->ctr
.ctr3
;
1095 werr
= WERR_INVALID_PARAM
;
1099 /* TODO -- Windows enumerates
1101 (c) open directories and files */
1103 werr
= net_enum_files(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1104 if (!W_ERROR_IS_OK(werr
)) {
1108 werr
= net_enum_pipes(ctx
, r
->in
.user
, &ctr3
, resume_hnd
);
1109 if (!W_ERROR_IS_OK(werr
)) {
1113 *r
->out
.totalentries
= ctr3
->count
;
1114 r
->out
.info_ctr
->ctr
.ctr3
->array
= ctr3
->array
;
1115 r
->out
.info_ctr
->ctr
.ctr3
->count
= ctr3
->count
;
1123 /*******************************************************************
1124 _srvsvc_NetSrvGetInfo
1125 ********************************************************************/
1127 WERROR
_srvsvc_NetSrvGetInfo(struct pipes_struct
*p
,
1128 struct srvsvc_NetSrvGetInfo
*r
)
1130 WERROR status
= WERR_OK
;
1132 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1134 if (!pipe_access_check(p
)) {
1135 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1136 return WERR_ACCESS_DENIED
;
1139 switch (r
->in
.level
) {
1141 /* Technically level 102 should only be available to
1142 Administrators but there isn't anything super-secret
1143 here, as most of it is made up. */
1146 struct srvsvc_NetSrvInfo102
*info102
;
1148 info102
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1153 info102
->platform_id
= PLATFORM_ID_NT
;
1154 info102
->server_name
= lp_netbios_name();
1155 info102
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1156 info102
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1157 info102
->server_type
= lp_default_server_announce();
1158 info102
->comment
= string_truncate(lp_serverstring(),
1159 MAX_SERVER_STRING_LENGTH
);
1160 info102
->users
= 0xffffffff;
1161 info102
->disc
= 0xf;
1162 info102
->hidden
= 0;
1163 info102
->announce
= 240;
1164 info102
->anndelta
= 3000;
1165 info102
->licenses
= 100000;
1166 info102
->userpath
= "C:\\";
1168 r
->out
.info
->info102
= info102
;
1172 struct srvsvc_NetSrvInfo101
*info101
;
1174 info101
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1179 info101
->platform_id
= PLATFORM_ID_NT
;
1180 info101
->server_name
= lp_netbios_name();
1181 info101
->version_major
= SAMBA_MAJOR_NBT_ANNOUNCE_VERSION
;
1182 info101
->version_minor
= SAMBA_MINOR_NBT_ANNOUNCE_VERSION
;
1183 info101
->server_type
= lp_default_server_announce();
1184 info101
->comment
= string_truncate(lp_serverstring(),
1185 MAX_SERVER_STRING_LENGTH
);
1187 r
->out
.info
->info101
= info101
;
1191 struct srvsvc_NetSrvInfo100
*info100
;
1193 info100
= talloc(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1198 info100
->platform_id
= PLATFORM_ID_NT
;
1199 info100
->server_name
= lp_netbios_name();
1201 r
->out
.info
->info100
= info100
;
1206 status
= WERR_UNKNOWN_LEVEL
;
1210 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__
));
1215 /*******************************************************************
1216 _srvsvc_NetSrvSetInfo
1217 ********************************************************************/
1219 WERROR
_srvsvc_NetSrvSetInfo(struct pipes_struct
*p
,
1220 struct srvsvc_NetSrvSetInfo
*r
)
1222 WERROR status
= WERR_OK
;
1224 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1226 /* Set up the net server set info structure. */
1228 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__
));
1233 /*******************************************************************
1235 ********************************************************************/
1237 WERROR
_srvsvc_NetConnEnum(struct pipes_struct
*p
,
1238 struct srvsvc_NetConnEnum
*r
)
1242 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1244 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1245 p
->session_info
->security_token
)) {
1246 DEBUG(1, ("Enumerating connections only allowed for "
1247 "administrators\n"));
1248 return WERR_ACCESS_DENIED
;
1251 switch (r
->in
.info_ctr
->level
) {
1253 werr
= init_srv_conn_info_0(r
->in
.info_ctr
->ctr
.ctr0
,
1254 r
->in
.resume_handle
,
1255 r
->out
.totalentries
);
1258 werr
= init_srv_conn_info_1(r
->in
.info_ctr
->ctr
.ctr1
,
1259 r
->in
.resume_handle
,
1260 r
->out
.totalentries
);
1263 return WERR_UNKNOWN_LEVEL
;
1266 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__
));
1271 /*******************************************************************
1273 ********************************************************************/
1275 WERROR
_srvsvc_NetSessEnum(struct pipes_struct
*p
,
1276 struct srvsvc_NetSessEnum
*r
)
1280 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1282 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
1283 p
->session_info
->security_token
)) {
1284 DEBUG(1, ("Enumerating sessions only allowed for "
1285 "administrators\n"));
1286 return WERR_ACCESS_DENIED
;
1289 switch (r
->in
.info_ctr
->level
) {
1291 werr
= init_srv_sess_info_0(p
,
1292 r
->in
.info_ctr
->ctr
.ctr0
,
1293 r
->in
.resume_handle
,
1294 r
->out
.totalentries
);
1297 werr
= init_srv_sess_info_1(p
,
1298 r
->in
.info_ctr
->ctr
.ctr1
,
1299 r
->in
.resume_handle
,
1300 r
->out
.totalentries
);
1303 return WERR_UNKNOWN_LEVEL
;
1306 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__
));
1311 /*******************************************************************
1313 ********************************************************************/
1315 WERROR
_srvsvc_NetSessDel(struct pipes_struct
*p
,
1316 struct srvsvc_NetSessDel
*r
)
1318 struct sessionid
*session_list
;
1319 int num_sessions
, snum
;
1320 const char *username
;
1321 const char *machine
;
1322 bool not_root
= False
;
1325 username
= r
->in
.user
;
1326 machine
= r
->in
.client
;
1328 /* strip leading backslashes if any */
1329 if (machine
&& machine
[0] == '\\' && machine
[1] == '\\') {
1333 num_sessions
= list_sessions(p
->mem_ctx
, &session_list
);
1335 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1337 werr
= WERR_ACCESS_DENIED
;
1339 /* fail out now if you are not root or not a domain admin */
1341 if ((p
->session_info
->unix_token
->uid
!= sec_initial_uid()) &&
1342 ( ! nt_token_check_domain_rid(p
->session_info
->security_token
,
1343 DOMAIN_RID_ADMINS
))) {
1348 for (snum
= 0; snum
< num_sessions
; snum
++) {
1350 if ((strequal(session_list
[snum
].username
, username
) || username
[0] == '\0' ) &&
1351 strequal(session_list
[snum
].remote_machine
, machine
)) {
1355 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid()) {
1360 ntstat
= messaging_send(p
->msg_ctx
,
1361 session_list
[snum
].pid
,
1362 MSG_SHUTDOWN
, &data_blob_null
);
1364 if (NT_STATUS_IS_OK(ntstat
))
1372 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__
));
1379 /*******************************************************************
1380 _srvsvc_NetShareEnumAll
1381 ********************************************************************/
1383 WERROR
_srvsvc_NetShareEnumAll(struct pipes_struct
*p
,
1384 struct srvsvc_NetShareEnumAll
*r
)
1388 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1390 if (!pipe_access_check(p
)) {
1391 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1392 return WERR_ACCESS_DENIED
;
1395 /* Create the list of shares for the response. */
1396 werr
= init_srv_share_info_ctr(p
,
1398 r
->in
.resume_handle
,
1399 r
->out
.totalentries
,
1402 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__
));
1407 /*******************************************************************
1408 _srvsvc_NetShareEnum
1409 ********************************************************************/
1411 WERROR
_srvsvc_NetShareEnum(struct pipes_struct
*p
,
1412 struct srvsvc_NetShareEnum
*r
)
1416 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1418 if (!pipe_access_check(p
)) {
1419 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1420 return WERR_ACCESS_DENIED
;
1423 /* Create the list of shares for the response. */
1424 werr
= init_srv_share_info_ctr(p
,
1426 r
->in
.resume_handle
,
1427 r
->out
.totalentries
,
1430 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__
));
1435 /*******************************************************************
1436 _srvsvc_NetShareGetInfo
1437 ********************************************************************/
1439 WERROR
_srvsvc_NetShareGetInfo(struct pipes_struct
*p
,
1440 struct srvsvc_NetShareGetInfo
*r
)
1442 WERROR status
= WERR_OK
;
1443 char *share_name
= NULL
;
1445 union srvsvc_NetShareInfo
*info
= r
->out
.info
;
1447 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1449 if (!r
->in
.share_name
) {
1450 return WERR_INVALID_NAME
;
1453 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1458 return WERR_INVALID_NAME
;
1461 switch (r
->in
.level
) {
1463 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1464 W_ERROR_HAVE_NO_MEMORY(info
->info0
);
1465 init_srv_share_info_0(p
, info
->info0
, snum
);
1468 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1469 W_ERROR_HAVE_NO_MEMORY(info
->info1
);
1470 init_srv_share_info_1(p
, info
->info1
, snum
);
1473 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1474 W_ERROR_HAVE_NO_MEMORY(info
->info2
);
1475 init_srv_share_info_2(p
, info
->info2
, snum
);
1478 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1479 W_ERROR_HAVE_NO_MEMORY(info
->info501
);
1480 init_srv_share_info_501(p
, info
->info501
, snum
);
1483 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1484 W_ERROR_HAVE_NO_MEMORY(info
->info502
);
1485 init_srv_share_info_502(p
, info
->info502
, snum
);
1488 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1489 W_ERROR_HAVE_NO_MEMORY(info
->info1004
);
1490 init_srv_share_info_1004(p
, info
->info1004
, snum
);
1493 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1494 W_ERROR_HAVE_NO_MEMORY(info
->info1005
);
1495 init_srv_share_info_1005(p
, info
->info1005
, snum
);
1498 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1499 W_ERROR_HAVE_NO_MEMORY(info
->info1006
);
1500 init_srv_share_info_1006(p
, info
->info1006
, snum
);
1503 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1504 W_ERROR_HAVE_NO_MEMORY(info
->info1007
);
1505 init_srv_share_info_1007(p
, info
->info1007
, snum
);
1508 init_srv_share_info_1501(p
, &info
->info1501
, snum
);
1511 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1513 status
= WERR_UNKNOWN_LEVEL
;
1517 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__
));
1522 /*******************************************************************
1523 _srvsvc_NetShareSetInfo. Modify share details.
1524 ********************************************************************/
1526 WERROR
_srvsvc_NetShareSetInfo(struct pipes_struct
*p
,
1527 struct srvsvc_NetShareSetInfo
*r
)
1529 char *command
= NULL
;
1530 char *share_name
= NULL
;
1531 char *comment
= NULL
;
1532 const char *pathname
= NULL
;
1537 struct security_descriptor
*psd
= NULL
;
1538 bool is_disk_op
= False
;
1539 int max_connections
= 0;
1540 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1541 union srvsvc_NetShareInfo
*info
= r
->in
.info
;
1543 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1545 if (!r
->in
.share_name
) {
1546 return WERR_INVALID_NAME
;
1549 if (r
->out
.parm_error
) {
1550 *r
->out
.parm_error
= 0;
1553 if ( strequal(r
->in
.share_name
,"IPC$")
1554 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1555 || strequal(r
->in
.share_name
,"global") )
1557 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1558 "modified by a remote user.\n",
1559 r
->in
.share_name
));
1560 return WERR_ACCESS_DENIED
;
1563 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1568 /* Does this share exist ? */
1570 return WERR_NET_NAME_NOT_FOUND
;
1572 /* No change to printer shares. */
1573 if (lp_print_ok(snum
))
1574 return WERR_ACCESS_DENIED
;
1576 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1578 /* fail out now if you are not root and not a disk op */
1580 if ( p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
1581 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1582 "SeDiskOperatorPrivilege privilege needed to modify "
1584 (unsigned int)p
->session_info
->unix_token
->uid
,
1586 return WERR_ACCESS_DENIED
;
1589 switch (r
->in
.level
) {
1591 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1592 comment
= talloc_strdup(ctx
, info
->info1
->comment
);
1593 type
= info
->info1
->type
;
1597 comment
= talloc_strdup(ctx
, info
->info2
->comment
);
1598 pathname
= info
->info2
->path
;
1599 type
= info
->info2
->type
;
1600 max_connections
= (info
->info2
->max_users
== (uint32_t)-1) ?
1601 0 : info
->info2
->max_users
;
1605 /* not supported on set but here for completeness */
1607 comment
= talloc_strdup(ctx
, info
->info501
->comment
);
1608 type
= info
->info501
->type
;
1613 comment
= talloc_strdup(ctx
, info
->info502
->comment
);
1614 pathname
= info
->info502
->path
;
1615 type
= info
->info502
->type
;
1616 psd
= info
->info502
->sd_buf
.sd
;
1617 map_generic_share_sd_bits(psd
);
1620 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1621 comment
= talloc_strdup(ctx
, info
->info1004
->comment
);
1622 type
= STYPE_DISKTREE
;
1625 /* XP re-sets the csc policy even if it wasn't changed by the
1626 user, so we must compare it to see if it's what is set in
1627 smb.conf, so that we can contine other ops like setting
1629 if (((info
->info1005
->dfs_flags
&
1630 SHARE_1005_CSC_POLICY_MASK
) >>
1631 SHARE_1005_CSC_POLICY_SHIFT
) == lp_csc_policy(snum
))
1634 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1635 return WERR_ACCESS_DENIED
;
1639 return WERR_ACCESS_DENIED
;
1641 pathname
= talloc_strdup(ctx
, lp_pathname(snum
));
1642 comment
= talloc_strdup(ctx
, lp_comment(snum
));
1643 psd
= info
->info1501
->sd
;
1644 map_generic_share_sd_bits(psd
);
1645 type
= STYPE_DISKTREE
;
1648 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1650 return WERR_UNKNOWN_LEVEL
;
1653 /* We can only modify disk shares. */
1654 if (type
!= STYPE_DISKTREE
) {
1655 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1658 return WERR_ACCESS_DENIED
;
1661 if (comment
== NULL
) {
1665 /* Check if the pathname is valid. */
1666 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1667 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1669 return WERR_OBJECT_PATH_INVALID
;
1672 /* Ensure share name, pathname and comment don't contain '"' characters. */
1673 string_replace(share_name
, '"', ' ');
1674 string_replace(path
, '"', ' ');
1675 string_replace(comment
, '"', ' ');
1677 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1678 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1680 /* Only call modify function if something changed. */
1682 if (strcmp(path
, lp_pathname(snum
)) || strcmp(comment
, lp_comment(snum
))
1683 || (lp_max_connections(snum
) != max_connections
)) {
1684 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1685 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1686 return WERR_ACCESS_DENIED
;
1689 command
= talloc_asprintf(p
->mem_ctx
,
1690 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1691 lp_change_share_cmd(),
1692 get_dyn_CONFIGFILE(),
1695 comment
? comment
: "",
1701 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command
));
1703 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1708 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1709 /* Tell everyone we updated smb.conf. */
1710 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
,
1717 /********* END SeDiskOperatorPrivilege BLOCK *********/
1719 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1722 TALLOC_FREE(command
);
1725 return WERR_ACCESS_DENIED
;
1727 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1731 /* Replace SD if changed. */
1733 struct security_descriptor
*old_sd
;
1736 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(snum
), &sd_size
);
1738 if (old_sd
&& !security_descriptor_equal(old_sd
, psd
)) {
1739 if (!set_share_security(share_name
, psd
))
1740 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1745 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__
));
1750 /*******************************************************************
1751 _srvsvc_NetShareAdd.
1752 Call 'add_share_command "sharename" "pathname"
1753 "comment" "max connections = "
1754 ********************************************************************/
1756 WERROR
_srvsvc_NetShareAdd(struct pipes_struct
*p
,
1757 struct srvsvc_NetShareAdd
*r
)
1759 char *command
= NULL
;
1760 char *share_name_in
= NULL
;
1761 char *share_name
= NULL
;
1762 char *comment
= NULL
;
1763 char *pathname
= NULL
;
1768 struct security_descriptor
*psd
= NULL
;
1770 int max_connections
= 0;
1771 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1773 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1775 if (r
->out
.parm_error
) {
1776 *r
->out
.parm_error
= 0;
1779 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1781 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1782 return WERR_ACCESS_DENIED
;
1784 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1785 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1786 return WERR_ACCESS_DENIED
;
1789 switch (r
->in
.level
) {
1791 /* No path. Not enough info in a level 0 to do anything. */
1792 return WERR_ACCESS_DENIED
;
1794 /* Not enough info in a level 1 to do anything. */
1795 return WERR_ACCESS_DENIED
;
1797 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info2
->name
);
1798 comment
= talloc_strdup(ctx
, r
->in
.info
->info2
->comment
);
1799 pathname
= talloc_strdup(ctx
, r
->in
.info
->info2
->path
);
1800 max_connections
= (r
->in
.info
->info2
->max_users
== (uint32_t)-1) ?
1801 0 : r
->in
.info
->info2
->max_users
;
1802 type
= r
->in
.info
->info2
->type
;
1805 /* No path. Not enough info in a level 501 to do anything. */
1806 return WERR_ACCESS_DENIED
;
1808 share_name_in
= talloc_strdup(ctx
, r
->in
.info
->info502
->name
);
1809 comment
= talloc_strdup(ctx
, r
->in
.info
->info502
->comment
);
1810 pathname
= talloc_strdup(ctx
, r
->in
.info
->info502
->path
);
1811 max_connections
= (r
->in
.info
->info502
->max_users
== (uint32_t)-1) ?
1812 0 : r
->in
.info
->info502
->max_users
;
1813 type
= r
->in
.info
->info502
->type
;
1814 psd
= r
->in
.info
->info502
->sd_buf
.sd
;
1815 map_generic_share_sd_bits(psd
);
1818 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1824 return WERR_ACCESS_DENIED
;
1826 /* DFS only level. */
1827 return WERR_ACCESS_DENIED
;
1829 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1831 return WERR_UNKNOWN_LEVEL
;
1834 /* check for invalid share names */
1836 if (!share_name_in
|| !validate_net_name(share_name_in
,
1837 INVALID_SHARENAME_CHARS
,
1838 strlen(share_name_in
))) {
1839 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1840 share_name_in
? share_name_in
: ""));
1841 return WERR_INVALID_NAME
;
1844 if (strequal(share_name_in
,"IPC$") || strequal(share_name_in
,"global")
1845 || (lp_enable_asu_support() &&
1846 strequal(share_name_in
,"ADMIN$"))) {
1847 return WERR_ACCESS_DENIED
;
1850 snum
= find_service(ctx
, share_name_in
, &share_name
);
1855 /* Share already exists. */
1857 return WERR_FILE_EXISTS
;
1860 /* We can only add disk shares. */
1861 if (type
!= STYPE_DISKTREE
) {
1862 return WERR_ACCESS_DENIED
;
1865 /* Check if the pathname is valid. */
1866 if (!(path
= valid_share_pathname(p
->mem_ctx
, pathname
))) {
1867 return WERR_OBJECT_PATH_INVALID
;
1870 /* Ensure share name, pathname and comment don't contain '"' characters. */
1871 string_replace(share_name_in
, '"', ' ');
1872 string_replace(share_name
, '"', ' ');
1873 string_replace(path
, '"', ' ');
1875 string_replace(comment
, '"', ' ');
1878 command
= talloc_asprintf(ctx
,
1879 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1881 get_dyn_CONFIGFILE(),
1884 comment
? comment
: "",
1890 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command
));
1892 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1897 /* FIXME: use libnetconf here - gd */
1899 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1900 /* Tell everyone we updated smb.conf. */
1901 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
1908 /********* END SeDiskOperatorPrivilege BLOCK *********/
1910 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1913 TALLOC_FREE(command
);
1916 return WERR_ACCESS_DENIED
;
1919 /* Note we use share_name here, not share_name_in as
1920 we need a canonicalized name for setting security. */
1921 if (!set_share_security(share_name
, psd
)) {
1922 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1928 * We don't call reload_services() here, the message will
1929 * cause this to be done before the next packet is read
1930 * from the client. JRA.
1933 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__
));
1938 /*******************************************************************
1940 Call "delete share command" with the share name as
1942 ********************************************************************/
1944 WERROR
_srvsvc_NetShareDel(struct pipes_struct
*p
,
1945 struct srvsvc_NetShareDel
*r
)
1947 char *command
= NULL
;
1948 char *share_name
= NULL
;
1952 struct share_params
*params
;
1953 TALLOC_CTX
*ctx
= p
->mem_ctx
;
1955 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__
));
1957 if (!r
->in
.share_name
) {
1958 return WERR_NET_NAME_NOT_FOUND
;
1961 if ( strequal(r
->in
.share_name
,"IPC$")
1962 || ( lp_enable_asu_support() && strequal(r
->in
.share_name
,"ADMIN$") )
1963 || strequal(r
->in
.share_name
,"global") )
1965 return WERR_ACCESS_DENIED
;
1968 snum
= find_service(talloc_tos(), r
->in
.share_name
, &share_name
);
1974 return WERR_NO_SUCH_SHARE
;
1977 if (!(params
= get_share_params(p
->mem_ctx
, share_name
))) {
1978 return WERR_NO_SUCH_SHARE
;
1981 /* No change to printer shares. */
1982 if (lp_print_ok(snum
))
1983 return WERR_ACCESS_DENIED
;
1985 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
1987 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
)
1988 return WERR_ACCESS_DENIED
;
1990 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1991 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1992 return WERR_ACCESS_DENIED
;
1995 command
= talloc_asprintf(ctx
,
1997 lp_delete_share_cmd(),
1998 get_dyn_CONFIGFILE(),
1999 lp_servicename(snum
));
2004 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command
));
2006 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2011 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
2012 /* Tell everyone we updated smb.conf. */
2013 message_send_all(p
->msg_ctx
, MSG_SMB_CONF_UPDATED
, NULL
, 0,
2020 /********* END SeDiskOperatorPrivilege BLOCK *********/
2022 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command
, ret
));
2025 return WERR_ACCESS_DENIED
;
2027 /* Delete the SD in the database. */
2028 delete_share_security(lp_servicename(params
->service
));
2030 lp_killservice(params
->service
);
2035 /*******************************************************************
2036 _srvsvc_NetShareDelSticky
2037 ********************************************************************/
2039 WERROR
_srvsvc_NetShareDelSticky(struct pipes_struct
*p
,
2040 struct srvsvc_NetShareDelSticky
*r
)
2042 struct srvsvc_NetShareDel q
;
2044 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__
));
2046 q
.in
.server_unc
= r
->in
.server_unc
;
2047 q
.in
.share_name
= r
->in
.share_name
;
2048 q
.in
.reserved
= r
->in
.reserved
;
2050 return _srvsvc_NetShareDel(p
, &q
);
2053 /*******************************************************************
2054 _srvsvc_NetRemoteTOD
2055 ********************************************************************/
2057 WERROR
_srvsvc_NetRemoteTOD(struct pipes_struct
*p
,
2058 struct srvsvc_NetRemoteTOD
*r
)
2060 struct srvsvc_NetRemoteTODInfo
*tod
;
2062 time_t unixdate
= time(NULL
);
2064 /* We do this call first as if we do it *after* the gmtime call
2065 it overwrites the pointed-to values. JRA */
2067 uint32 zone
= get_time_zone(unixdate
)/60;
2069 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2071 if ( !(tod
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetRemoteTODInfo
)) )
2076 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2078 t
= gmtime(&unixdate
);
2081 tod
->elapsed
= unixdate
;
2083 tod
->hours
= t
->tm_hour
;
2084 tod
->mins
= t
->tm_min
;
2085 tod
->secs
= t
->tm_sec
;
2087 tod
->timezone
= zone
;
2088 tod
->tinterval
= 10000;
2089 tod
->day
= t
->tm_mday
;
2090 tod
->month
= t
->tm_mon
+ 1;
2091 tod
->year
= 1900+t
->tm_year
;
2092 tod
->weekday
= t
->tm_wday
;
2094 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__
));
2099 /***********************************************************************************
2100 _srvsvc_NetGetFileSecurity
2101 Win9x NT tools get security descriptor.
2102 ***********************************************************************************/
2104 WERROR
_srvsvc_NetGetFileSecurity(struct pipes_struct
*p
,
2105 struct srvsvc_NetGetFileSecurity
*r
)
2107 struct smb_filename
*smb_fname
= NULL
;
2108 struct security_descriptor
*psd
= NULL
;
2110 char *servicename
= NULL
;
2114 connection_struct
*conn
= NULL
;
2115 struct sec_desc_buf
*sd_buf
= NULL
;
2116 files_struct
*fsp
= NULL
;
2118 char *oldcwd
= NULL
;
2123 werr
= WERR_NET_NAME_NOT_FOUND
;
2126 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2132 DEBUG(10, ("Could not find service %s\n", servicename
));
2133 werr
= WERR_NET_NAME_NOT_FOUND
;
2137 nt_status
= create_conn_struct(talloc_tos(),
2138 server_event_context(),
2139 server_messaging_context(),
2141 snum
, lp_pathname(snum
),
2142 p
->session_info
, &oldcwd
);
2143 if (!NT_STATUS_IS_OK(nt_status
)) {
2144 DEBUG(10, ("create_conn_struct failed: %s\n",
2145 nt_errstr(nt_status
)));
2146 werr
= ntstatus_to_werror(nt_status
);
2150 nt_status
= filename_convert(talloc_tos(),
2157 if (!NT_STATUS_IS_OK(nt_status
)) {
2158 werr
= ntstatus_to_werror(nt_status
);
2162 nt_status
= SMB_VFS_CREATE_FILE(
2165 0, /* root_dir_fid */
2166 smb_fname
, /* fname */
2167 FILE_READ_ATTRIBUTES
, /* access_mask */
2168 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2169 FILE_OPEN
, /* create_disposition*/
2170 0, /* create_options */
2171 0, /* file_attributes */
2172 INTERNAL_OPEN_ONLY
, /* oplock_request */
2173 0, /* allocation_size */
2174 0, /* private_flags */
2180 if (!NT_STATUS_IS_OK(nt_status
)) {
2181 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2182 smb_fname_str_dbg(smb_fname
)));
2183 werr
= ntstatus_to_werror(nt_status
);
2187 nt_status
= SMB_VFS_FGET_NT_ACL(fsp
,
2190 |SECINFO_DACL
), &psd
);
2192 if (!NT_STATUS_IS_OK(nt_status
)) {
2193 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2194 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
2195 werr
= ntstatus_to_werror(nt_status
);
2199 sd_size
= ndr_size_security_descriptor(psd
, 0);
2201 sd_buf
= talloc_zero(p
->mem_ctx
, struct sec_desc_buf
);
2207 sd_buf
->sd_size
= sd_size
;
2210 *r
->out
.sd_buf
= sd_buf
;
2212 psd
->dacl
->revision
= NT4_ACL_REVISION
;
2214 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2215 vfs_ChDir(conn
, oldcwd
);
2216 SMB_VFS_DISCONNECT(conn
);
2224 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2228 vfs_ChDir(conn
, oldcwd
);
2232 SMB_VFS_DISCONNECT(conn
);
2237 TALLOC_FREE(smb_fname
);
2242 /***********************************************************************************
2243 _srvsvc_NetSetFileSecurity
2244 Win9x NT tools set security descriptor.
2245 ***********************************************************************************/
2247 WERROR
_srvsvc_NetSetFileSecurity(struct pipes_struct
*p
,
2248 struct srvsvc_NetSetFileSecurity
*r
)
2250 struct smb_filename
*smb_fname
= NULL
;
2251 char *servicename
= NULL
;
2252 files_struct
*fsp
= NULL
;
2256 connection_struct
*conn
= NULL
;
2258 char *oldcwd
= NULL
;
2259 struct security_descriptor
*psd
= NULL
;
2260 uint32_t security_info_sent
= 0;
2265 werr
= WERR_NET_NAME_NOT_FOUND
;
2269 snum
= find_service(talloc_tos(), r
->in
.share
, &servicename
);
2276 DEBUG(10, ("Could not find service %s\n", servicename
));
2277 werr
= WERR_NET_NAME_NOT_FOUND
;
2281 nt_status
= create_conn_struct(talloc_tos(),
2282 server_event_context(),
2283 server_messaging_context(),
2285 snum
, lp_pathname(snum
),
2286 p
->session_info
, &oldcwd
);
2287 if (!NT_STATUS_IS_OK(nt_status
)) {
2288 DEBUG(10, ("create_conn_struct failed: %s\n",
2289 nt_errstr(nt_status
)));
2290 werr
= ntstatus_to_werror(nt_status
);
2294 nt_status
= filename_convert(talloc_tos(),
2301 if (!NT_STATUS_IS_OK(nt_status
)) {
2302 werr
= ntstatus_to_werror(nt_status
);
2306 nt_status
= SMB_VFS_CREATE_FILE(
2309 0, /* root_dir_fid */
2310 smb_fname
, /* fname */
2311 FILE_WRITE_ATTRIBUTES
, /* access_mask */
2312 FILE_SHARE_READ
|FILE_SHARE_WRITE
, /* share_access */
2313 FILE_OPEN
, /* create_disposition*/
2314 0, /* create_options */
2315 0, /* file_attributes */
2316 INTERNAL_OPEN_ONLY
, /* oplock_request */
2317 0, /* allocation_size */
2318 0, /* private_flags */
2324 if (!NT_STATUS_IS_OK(nt_status
)) {
2325 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2326 smb_fname_str_dbg(smb_fname
)));
2327 werr
= ntstatus_to_werror(nt_status
);
2331 psd
= r
->in
.sd_buf
->sd
;
2332 security_info_sent
= r
->in
.securityinformation
;
2334 if (psd
->owner_sid
==0) {
2335 security_info_sent
&= ~SECINFO_OWNER
;
2337 if (psd
->group_sid
==0) {
2338 security_info_sent
&= ~SECINFO_GROUP
;
2341 security_info_sent
&= ~SECINFO_SACL
;
2344 security_info_sent
&= ~SECINFO_DACL
;
2347 /* Convert all the generic bits. */
2348 security_acl_map_generic(psd
->dacl
, &file_generic_mapping
);
2349 security_acl_map_generic(psd
->sacl
, &file_generic_mapping
);
2351 nt_status
= SMB_VFS_FSET_NT_ACL(fsp
,
2355 if (!NT_STATUS_IS_OK(nt_status
) ) {
2356 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2357 "on file %s\n", r
->in
.share
));
2358 werr
= WERR_ACCESS_DENIED
;
2362 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2363 vfs_ChDir(conn
, oldcwd
);
2364 SMB_VFS_DISCONNECT(conn
);
2372 close_file(NULL
, fsp
, NORMAL_CLOSE
);
2376 vfs_ChDir(conn
, oldcwd
);
2380 SMB_VFS_DISCONNECT(conn
);
2385 TALLOC_FREE(smb_fname
);
2390 /***********************************************************************************
2391 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2392 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2393 These disks would the disks listed by this function.
2394 Users could then create shares relative to these disks. Watch out for moving these disks around.
2395 "Nigel Williams" <nigel@veritas.com>.
2396 ***********************************************************************************/
2398 static const char *server_disks
[] = {"C:"};
2400 static uint32
get_server_disk_count(void)
2402 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2405 static uint32
init_server_disk_enum(uint32
*resume
)
2407 uint32 server_disk_count
= get_server_disk_count();
2409 /*resume can be an offset into the list for now*/
2411 if(*resume
& 0x80000000)
2414 if(*resume
> server_disk_count
)
2415 *resume
= server_disk_count
;
2417 return server_disk_count
- *resume
;
2420 static const char *next_server_disk_enum(uint32
*resume
)
2424 if(init_server_disk_enum(resume
) == 0)
2427 disk
= server_disks
[*resume
];
2431 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2436 /********************************************************************
2438 ********************************************************************/
2440 WERROR
_srvsvc_NetDiskEnum(struct pipes_struct
*p
,
2441 struct srvsvc_NetDiskEnum
*r
)
2444 const char *disk_name
;
2445 TALLOC_CTX
*ctx
= p
->mem_ctx
;
2447 uint32_t resume
= r
->in
.resume_handle
? *r
->in
.resume_handle
: 0;
2451 *r
->out
.totalentries
= init_server_disk_enum(&resume
);
2453 r
->out
.info
->disks
= talloc_zero_array(ctx
, struct srvsvc_NetDiskInfo0
,
2454 MAX_SERVER_DISK_ENTRIES
);
2455 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
);
2457 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2459 r
->out
.info
->count
= 0;
2461 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(&resume
)); i
++) {
2463 r
->out
.info
->count
++;
2465 /*copy disk name into a unicode string*/
2467 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, disk_name
);
2468 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2471 /* add a terminating null string. Is this there if there is more data to come? */
2473 r
->out
.info
->count
++;
2475 r
->out
.info
->disks
[i
].disk
= talloc_strdup(ctx
, "");
2476 W_ERROR_HAVE_NO_MEMORY(r
->out
.info
->disks
[i
].disk
);
2478 if (r
->out
.resume_handle
) {
2479 *r
->out
.resume_handle
= resume
;
2485 /********************************************************************
2486 _srvsvc_NetNameValidate
2487 ********************************************************************/
2489 WERROR
_srvsvc_NetNameValidate(struct pipes_struct
*p
,
2490 struct srvsvc_NetNameValidate
*r
)
2492 switch (r
->in
.name_type
) {
2494 if (!validate_net_name(r
->in
.name
, INVALID_SHARENAME_CHARS
,
2495 strlen_m(r
->in
.name
)))
2497 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2499 return WERR_INVALID_NAME
;
2504 return WERR_UNKNOWN_LEVEL
;
2510 /*******************************************************************
2511 ********************************************************************/
2513 struct enum_file_close_state
{
2514 struct srvsvc_NetFileClose
*r
;
2515 struct messaging_context
*msg_ctx
;
2518 static void enum_file_close_fn( const struct share_mode_entry
*e
,
2519 const char *sharepath
, const char *fname
,
2520 void *private_data
)
2522 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
2523 struct enum_file_close_state
*state
=
2524 (struct enum_file_close_state
*)private_data
;
2525 uint32_t fid
= (((uint32_t)(procid_to_pid(&e
->pid
))<<16) | e
->share_file_id
);
2527 if (fid
!= state
->r
->in
.fid
) {
2528 return; /* Not this file. */
2531 if (!process_exists(e
->pid
) ) {
2535 /* Ok - send the close message. */
2536 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2538 share_mode_str(talloc_tos(), 0, e
) ));
2540 share_mode_entry_to_message(msg
, e
);
2542 state
->r
->out
.result
= ntstatus_to_werror(
2543 messaging_send_buf(state
->msg_ctx
,
2544 e
->pid
, MSG_SMB_CLOSE_FILE
,
2546 MSG_SMB_SHARE_MODE_ENTRY_SIZE
));
2549 /********************************************************************
2550 Close a file given a 32-bit file id.
2551 ********************************************************************/
2553 WERROR
_srvsvc_NetFileClose(struct pipes_struct
*p
,
2554 struct srvsvc_NetFileClose
*r
)
2556 struct enum_file_close_state state
;
2559 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__
));
2561 is_disk_op
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_DISK_OPERATOR
);
2563 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() && !is_disk_op
) {
2564 return WERR_ACCESS_DENIED
;
2567 /* enum_file_close_fn sends the close message to
2568 * the relevent smbd process. */
2570 r
->out
.result
= WERR_BADFILE
;
2572 state
.msg_ctx
= p
->msg_ctx
;
2573 share_mode_forall(enum_file_close_fn
, &state
);
2574 return r
->out
.result
;
2577 /********************************************************************
2578 ********************************************************************/
2580 WERROR
_srvsvc_NetCharDevEnum(struct pipes_struct
*p
,
2581 struct srvsvc_NetCharDevEnum
*r
)
2583 p
->rng_fault_state
= True
;
2584 return WERR_NOT_SUPPORTED
;
2587 WERROR
_srvsvc_NetCharDevGetInfo(struct pipes_struct
*p
,
2588 struct srvsvc_NetCharDevGetInfo
*r
)
2590 p
->rng_fault_state
= True
;
2591 return WERR_NOT_SUPPORTED
;
2594 WERROR
_srvsvc_NetCharDevControl(struct pipes_struct
*p
,
2595 struct srvsvc_NetCharDevControl
*r
)
2597 p
->rng_fault_state
= True
;
2598 return WERR_NOT_SUPPORTED
;
2601 WERROR
_srvsvc_NetCharDevQEnum(struct pipes_struct
*p
,
2602 struct srvsvc_NetCharDevQEnum
*r
)
2604 p
->rng_fault_state
= True
;
2605 return WERR_NOT_SUPPORTED
;
2608 WERROR
_srvsvc_NetCharDevQGetInfo(struct pipes_struct
*p
,
2609 struct srvsvc_NetCharDevQGetInfo
*r
)
2611 p
->rng_fault_state
= True
;
2612 return WERR_NOT_SUPPORTED
;
2615 WERROR
_srvsvc_NetCharDevQSetInfo(struct pipes_struct
*p
,
2616 struct srvsvc_NetCharDevQSetInfo
*r
)
2618 p
->rng_fault_state
= True
;
2619 return WERR_NOT_SUPPORTED
;
2622 WERROR
_srvsvc_NetCharDevQPurge(struct pipes_struct
*p
,
2623 struct srvsvc_NetCharDevQPurge
*r
)
2625 p
->rng_fault_state
= True
;
2626 return WERR_NOT_SUPPORTED
;
2629 WERROR
_srvsvc_NetCharDevQPurgeSelf(struct pipes_struct
*p
,
2630 struct srvsvc_NetCharDevQPurgeSelf
*r
)
2632 p
->rng_fault_state
= True
;
2633 return WERR_NOT_SUPPORTED
;
2636 WERROR
_srvsvc_NetFileGetInfo(struct pipes_struct
*p
,
2637 struct srvsvc_NetFileGetInfo
*r
)
2639 p
->rng_fault_state
= True
;
2640 return WERR_NOT_SUPPORTED
;
2643 WERROR
_srvsvc_NetShareCheck(struct pipes_struct
*p
,
2644 struct srvsvc_NetShareCheck
*r
)
2646 p
->rng_fault_state
= True
;
2647 return WERR_NOT_SUPPORTED
;
2650 WERROR
_srvsvc_NetServerStatisticsGet(struct pipes_struct
*p
,
2651 struct srvsvc_NetServerStatisticsGet
*r
)
2653 p
->rng_fault_state
= True
;
2654 return WERR_NOT_SUPPORTED
;
2657 WERROR
_srvsvc_NetTransportAdd(struct pipes_struct
*p
,
2658 struct srvsvc_NetTransportAdd
*r
)
2660 p
->rng_fault_state
= True
;
2661 return WERR_NOT_SUPPORTED
;
2664 WERROR
_srvsvc_NetTransportEnum(struct pipes_struct
*p
,
2665 struct srvsvc_NetTransportEnum
*r
)
2667 p
->rng_fault_state
= True
;
2668 return WERR_NOT_SUPPORTED
;
2671 WERROR
_srvsvc_NetTransportDel(struct pipes_struct
*p
,
2672 struct srvsvc_NetTransportDel
*r
)
2674 p
->rng_fault_state
= True
;
2675 return WERR_NOT_SUPPORTED
;
2678 WERROR
_srvsvc_NetSetServiceBits(struct pipes_struct
*p
,
2679 struct srvsvc_NetSetServiceBits
*r
)
2681 p
->rng_fault_state
= True
;
2682 return WERR_NOT_SUPPORTED
;
2685 WERROR
_srvsvc_NetPathType(struct pipes_struct
*p
,
2686 struct srvsvc_NetPathType
*r
)
2688 p
->rng_fault_state
= True
;
2689 return WERR_NOT_SUPPORTED
;
2692 WERROR
_srvsvc_NetPathCanonicalize(struct pipes_struct
*p
,
2693 struct srvsvc_NetPathCanonicalize
*r
)
2695 p
->rng_fault_state
= True
;
2696 return WERR_NOT_SUPPORTED
;
2699 WERROR
_srvsvc_NetPathCompare(struct pipes_struct
*p
,
2700 struct srvsvc_NetPathCompare
*r
)
2702 p
->rng_fault_state
= True
;
2703 return WERR_NOT_SUPPORTED
;
2706 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct
*p
,
2707 struct srvsvc_NETRPRNAMECANONICALIZE
*r
)
2709 p
->rng_fault_state
= True
;
2710 return WERR_NOT_SUPPORTED
;
2713 WERROR
_srvsvc_NetPRNameCompare(struct pipes_struct
*p
,
2714 struct srvsvc_NetPRNameCompare
*r
)
2716 p
->rng_fault_state
= True
;
2717 return WERR_NOT_SUPPORTED
;
2720 WERROR
_srvsvc_NetShareDelStart(struct pipes_struct
*p
,
2721 struct srvsvc_NetShareDelStart
*r
)
2723 p
->rng_fault_state
= True
;
2724 return WERR_NOT_SUPPORTED
;
2727 WERROR
_srvsvc_NetShareDelCommit(struct pipes_struct
*p
,
2728 struct srvsvc_NetShareDelCommit
*r
)
2730 p
->rng_fault_state
= True
;
2731 return WERR_NOT_SUPPORTED
;
2734 WERROR
_srvsvc_NetServerTransportAddEx(struct pipes_struct
*p
,
2735 struct srvsvc_NetServerTransportAddEx
*r
)
2737 p
->rng_fault_state
= True
;
2738 return WERR_NOT_SUPPORTED
;
2741 WERROR
_srvsvc_NetServerSetServiceBitsEx(struct pipes_struct
*p
,
2742 struct srvsvc_NetServerSetServiceBitsEx
*r
)
2744 p
->rng_fault_state
= True
;
2745 return WERR_NOT_SUPPORTED
;
2748 WERROR
_srvsvc_NETRDFSGETVERSION(struct pipes_struct
*p
,
2749 struct srvsvc_NETRDFSGETVERSION
*r
)
2751 p
->rng_fault_state
= True
;
2752 return WERR_NOT_SUPPORTED
;
2755 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct
*p
,
2756 struct srvsvc_NETRDFSCREATELOCALPARTITION
*r
)
2758 p
->rng_fault_state
= True
;
2759 return WERR_NOT_SUPPORTED
;
2762 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct
*p
,
2763 struct srvsvc_NETRDFSDELETELOCALPARTITION
*r
)
2765 p
->rng_fault_state
= True
;
2766 return WERR_NOT_SUPPORTED
;
2769 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct
*p
,
2770 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE
*r
)
2772 p
->rng_fault_state
= True
;
2773 return WERR_NOT_SUPPORTED
;
2776 WERROR
_srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct
*p
,
2777 struct srvsvc_NETRDFSSETSERVERINFO
*r
)
2779 p
->rng_fault_state
= True
;
2780 return WERR_NOT_SUPPORTED
;
2783 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct
*p
,
2784 struct srvsvc_NETRDFSCREATEEXITPOINT
*r
)
2786 p
->rng_fault_state
= True
;
2787 return WERR_NOT_SUPPORTED
;
2790 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct
*p
,
2791 struct srvsvc_NETRDFSDELETEEXITPOINT
*r
)
2793 p
->rng_fault_state
= True
;
2794 return WERR_NOT_SUPPORTED
;
2797 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct
*p
,
2798 struct srvsvc_NETRDFSMODIFYPREFIX
*r
)
2800 p
->rng_fault_state
= True
;
2801 return WERR_NOT_SUPPORTED
;
2804 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct
*p
,
2805 struct srvsvc_NETRDFSFIXLOCALVOLUME
*r
)
2807 p
->rng_fault_state
= True
;
2808 return WERR_NOT_SUPPORTED
;
2811 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct
*p
,
2812 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO
*r
)
2814 p
->rng_fault_state
= True
;
2815 return WERR_NOT_SUPPORTED
;
2818 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct
*p
,
2819 struct srvsvc_NETRSERVERTRANSPORTDELEX
*r
)
2821 p
->rng_fault_state
= True
;
2822 return WERR_NOT_SUPPORTED
;