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) Jelmer Vernooij 2006.
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 2 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, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* This is the implementation of the srvsvc pipe. */
29 #define MAX_SERVER_DISK_ENTRIES 15
31 extern struct generic_mapping file_generic_mapping
;
32 extern userdom_struct current_user_info
;
35 #define DBGC_CLASS DBGC_RPC_SRV
37 /* Use for enumerating connections, pipes, & files */
39 struct file_enum_count
{
42 struct srvsvc_NetFileInfo3
*info
;
45 struct sess_file_count
{
51 /****************************************************************************
52 Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
55 static int pipe_enum_fn( TDB_CONTEXT
*the_tdb
, TDB_DATA kbuf
, TDB_DATA dbuf
, void *p
)
57 struct pipe_open_rec prec
;
58 struct file_enum_count
*fenum
= (struct file_enum_count
*)p
;
60 if (dbuf
.dsize
!= sizeof(struct pipe_open_rec
))
63 memcpy(&prec
, dbuf
.dptr
, sizeof(struct pipe_open_rec
));
65 if ( process_exists(prec
.pid
) ) {
66 struct srvsvc_NetFileInfo3
*f
;
70 snprintf( fullpath
, sizeof(fullpath
), "\\PIPE\\%s", prec
.name
);
72 f
= TALLOC_REALLOC_ARRAY( fenum
->ctx
, fenum
->info
, struct srvsvc_NetFileInfo3
, i
+1 );
74 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
80 fenum
->info
[i
].fid
= (uint32
)((procid_to_pid(&prec
.pid
)<<16) & prec
.pnum
);
81 fenum
->info
[i
].permissions
= (FILE_READ_DATA
|FILE_WRITE_DATA
);
82 fenum
->info
[i
].num_locks
= 0;
83 fenum
->info
[i
].user
= uidtoname( prec
.uid
);
84 fenum
->info
[i
].path
= fullpath
;
92 /*******************************************************************
93 ********************************************************************/
95 static WERROR
net_enum_pipes( TALLOC_CTX
*ctx
, struct srvsvc_NetFileInfo3
**info
,
96 uint32
*count
, uint32
*resume
)
98 struct file_enum_count fenum
;
99 TDB_CONTEXT
*conn_tdb
= conn_tdb_ctx();
102 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103 return WERR_ACCESS_DENIED
;
108 fenum
.count
= *count
;
110 if (tdb_traverse(conn_tdb
, pipe_enum_fn
, &fenum
) == -1) {
111 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112 tdb_errorstr(conn_tdb
) ));
117 *count
= fenum
.count
;
121 /*******************************************************************
122 ********************************************************************/
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt
;
127 static void enum_file_fn( const struct share_mode_entry
*e
,
128 const char *sharepath
, const char *fname
,
131 struct file_enum_count
*fenum
= &f_enum_cnt
;
133 /* If the pid was not found delete the entry from connections.tdb */
135 if ( process_exists(e
->pid
) ) {
136 struct srvsvc_NetFileInfo3
*f
;
137 int i
= fenum
->count
;
139 struct byte_range_lock
*brl
;
144 f
= TALLOC_REALLOC_ARRAY( fenum
->ctx
, fenum
->info
, struct srvsvc_NetFileInfo3
, i
+1 );
146 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i
+1));
151 /* need to count the number of locks on a file */
155 fsp
.inode
= e
->inode
;
157 if ( (brl
= brl_get_locks_readonly(NULL
,&fsp
)) != NULL
) {
158 num_locks
= brl
->num_locks
;
162 if ( strcmp( fname
, "." ) == 0 ) {
163 pstr_sprintf( fullpath
, "C:%s", sharepath
);
165 pstr_sprintf( fullpath
, "C:%s/%s", sharepath
, fname
);
167 string_replace( fullpath
, '/', '\\' );
169 /* mask out create (what ever that is) */
170 permissions
= e
->share_access
& (FILE_READ_DATA
|FILE_WRITE_DATA
);
172 fenum
->info
[i
].fid
= e
->share_file_id
;
173 fenum
->info
[i
].permissions
= permissions
;
174 fenum
->info
[i
].num_locks
= num_locks
;
175 fenum
->info
[i
].user
= uidtoname(e
->uid
);
176 fenum
->info
[i
].path
= fullpath
;
185 /*******************************************************************
186 ********************************************************************/
188 static WERROR
net_enum_files( TALLOC_CTX
*ctx
, struct srvsvc_NetFileInfo3
**info
,
189 uint32
*count
, uint32
*resume
)
191 f_enum_cnt
.ctx
= ctx
;
192 f_enum_cnt
.count
= *count
;
193 f_enum_cnt
.info
= *info
;
195 share_mode_forall( enum_file_fn
, NULL
);
197 *info
= f_enum_cnt
.info
;
198 *count
= f_enum_cnt
.count
;
203 /*******************************************************************
204 Utility function to get the 'type' of a share from a share definition.
205 ********************************************************************/
206 static uint32
get_share_type(const struct share_params
*params
)
208 char *net_name
= lp_servicename(params
->service
);
209 int len_net_name
= strlen(net_name
);
211 /* work out the share type */
212 uint32 type
= STYPE_DISKTREE
;
214 if (lp_print_ok(params
->service
))
216 if (strequal(lp_fstype(params
->service
), "IPC"))
218 if (net_name
[len_net_name
] == '$')
219 type
|= STYPE_HIDDEN
;
224 /*******************************************************************
225 Fill in a share info level 0 structure.
226 ********************************************************************/
228 static void init_srv_share_info_0(pipes_struct
*p
, struct srvsvc_NetShareInfo0
*sh0
,
229 const struct share_params
*params
)
231 sh0
->name
= lp_servicename(params
->service
);
234 /*******************************************************************
235 Fill in a share info level 1 structure.
236 ********************************************************************/
238 static void init_srv_share_info_1(pipes_struct
*p
, struct srvsvc_NetShareInfo1
*sh1
,
239 const struct share_params
*params
)
241 connection_struct
*conn
= p
->conn
;
243 sh1
->comment
= talloc_sub_advanced(p
->mem_ctx
, lp_servicename(SNUM(conn
)),
244 conn
->user
, conn
->connectpath
, conn
->gid
,
245 get_current_username(),
246 current_user_info
.domain
,
247 lp_comment(params
->service
));
249 sh1
->name
= lp_servicename(params
->service
);
250 sh1
->type
= get_share_type(params
);
253 /*******************************************************************
254 Fill in a share info level 2 structure.
255 ********************************************************************/
257 static void init_srv_share_info_2(pipes_struct
*p
, struct srvsvc_NetShareInfo2
*sh2
,
258 const struct share_params
*params
)
260 connection_struct
*conn
= p
->conn
;
263 int max_connections
= lp_max_connections(params
->service
);
264 uint32 max_uses
= max_connections
!=0 ? max_connections
: 0xffffffff;
266 char *net_name
= lp_servicename(params
->service
);
268 remark
= talloc_sub_advanced(p
->mem_ctx
, lp_servicename(SNUM(conn
)),
269 conn
->user
, conn
->connectpath
, conn
->gid
,
270 get_current_username(),
271 current_user_info
.domain
,
272 lp_comment(params
->service
));
273 path
= talloc_asprintf(p
->mem_ctx
, "C:%s",
274 lp_pathname(params
->service
));
277 * Change / to \\ so that win2k will see it as a valid path. This was
278 * added to enable use of browsing in win2k add share dialog.
281 string_replace(path
, '/', '\\');
283 count
= count_current_connections( net_name
, False
);
284 sh2
->name
= net_name
;
285 sh2
->type
= get_share_type(params
);
286 sh2
->comment
= remark
;
287 sh2
->permissions
= 0;
288 sh2
->max_users
= max_uses
;
289 sh2
->current_users
= count
;
294 /*******************************************************************
295 Map any generic bits to file specific bits.
296 ********************************************************************/
298 static void map_generic_share_sd_bits(SEC_DESC
*psd
)
301 SEC_ACL
*ps_dacl
= NULL
;
310 for (i
= 0; i
< ps_dacl
->num_aces
; i
++) {
311 SEC_ACE
*psa
= &ps_dacl
->aces
[i
];
312 uint32 orig_mask
= psa
->access_mask
;
314 se_map_generic(&psa
->access_mask
, &file_generic_mapping
);
315 psa
->access_mask
|= orig_mask
;
319 /*******************************************************************
320 Fill in a share info level 501 structure.
321 ********************************************************************/
323 static void init_srv_share_info_501(pipes_struct
*p
, struct srvsvc_NetShareInfo501
*sh501
,
324 const struct share_params
*params
)
326 connection_struct
*conn
= p
->conn
;
328 const char *net_name
= lp_servicename(params
->service
);
330 remark
= talloc_sub_advanced(p
->mem_ctx
, lp_servicename(SNUM(conn
)),
331 conn
->user
, conn
->connectpath
, conn
->gid
,
332 get_current_username(),
333 current_user_info
.domain
,
334 lp_comment(params
->service
));
337 sh501
->name
= net_name
;
338 sh501
->type
= get_share_type(params
);
339 sh501
->comment
= remark
;
340 sh501
->csc_policy
= (lp_csc_policy(params
->service
) << 4);
343 /*******************************************************************
344 Fill in a share info level 502 structure.
345 ********************************************************************/
347 static void init_srv_share_info_502(pipes_struct
*p
, struct srvsvc_NetShareInfo502
*sh502
,
348 const struct share_params
*params
)
350 int max_connections
= lp_max_connections(params
->service
);
351 uint32 max_uses
= max_connections
!=0 ? max_connections
: 0xffffffff;
352 connection_struct
*conn
= p
->conn
;
359 TALLOC_CTX
*ctx
= p
->mem_ctx
;
364 net_name
= lp_servicename(params
->service
);
365 count
= count_current_connections( net_name
, False
);
367 remark
= talloc_sub_advanced(p
->mem_ctx
, lp_servicename(SNUM(conn
)),
368 conn
->user
, conn
->connectpath
, conn
->gid
,
369 get_current_username(),
370 current_user_info
.domain
,
371 lp_comment(params
->service
));
373 path
= talloc_asprintf(p
->mem_ctx
, "C:%s",
374 lp_pathname(params
->service
));
377 * Change / to \\ so that win2k will see it as a valid path. This was
378 * added to enable use of browsing in win2k add share dialog.
381 string_replace(path
, '/', '\\');
383 sd
= get_share_security(ctx
, lp_servicename(params
->service
),
386 sh502
->name
= net_name
;
387 sh502
->type
= get_share_type(params
);
388 sh502
->comment
= remark
;
390 sh502
->password
= "";
392 sh502
->permissions
= 0;
393 sh502
->max_users
= max_uses
;
394 sh502
->current_users
= count
;
398 /***************************************************************************
399 Fill in a share info level 1004 structure.
400 ***************************************************************************/
402 static void init_srv_share_info_1004(pipes_struct
*p
,
403 struct srvsvc_NetShareInfo1004
* sh1004
,
404 const struct share_params
*params
)
406 connection_struct
*conn
= p
->conn
;
409 remark
= talloc_sub_advanced(p
->mem_ctx
, lp_servicename(SNUM(conn
)),
410 conn
->user
, conn
->connectpath
, conn
->gid
,
411 get_current_username(),
412 current_user_info
.domain
,
413 lp_comment(params
->service
));
415 ZERO_STRUCTP(sh1004
);
417 sh1004
->comment
= remark
;
420 /***************************************************************************
421 Fill in a share info level 1005 structure.
422 ***************************************************************************/
424 static void init_srv_share_info_1005(pipes_struct
*p
,
425 struct srvsvc_NetShareInfo1005
* sh1005
,
426 const struct share_params
*params
)
428 sh1005
->dfs_flags
= 0;
430 if(lp_host_msdfs() && lp_msdfs_root(params
->service
))
432 SHARE_1005_IN_DFS
| SHARE_1005_DFS_ROOT
;
434 lp_csc_policy(params
->service
) << SHARE_1005_CSC_POLICY_SHIFT
;
436 /***************************************************************************
437 Fill in a share info level 1006 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1006(pipes_struct
*p
,
441 struct srvsvc_NetShareInfo1006
* sh1006
,
442 const struct share_params
*params
)
444 sh1006
->max_users
= -1;
447 /***************************************************************************
448 Fill in a share info level 1007 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1007(pipes_struct
*p
,
452 struct srvsvc_NetShareInfo1007
* sh1007
,
453 const struct share_params
*params
)
457 ZERO_STRUCTP(sh1007
);
459 sh1007
->flags
= flags
;
460 sh1007
->alternate_directory_name
= "";
463 /*******************************************************************
464 Fill in a share info level 1501 structure.
465 ********************************************************************/
467 static void init_srv_share_info_1501(pipes_struct
*p
,
468 struct sec_desc_buf
*sh1501
,
469 const struct share_params
*params
)
473 TALLOC_CTX
*ctx
= p
->mem_ctx
;
475 ZERO_STRUCTP(sh1501
);
477 sd
= get_share_security(ctx
, lp_servicename(params
->service
),
483 /*******************************************************************
484 True if it ends in '$'.
485 ********************************************************************/
487 static BOOL
is_hidden_share(const struct share_params
*params
)
489 const char *net_name
= lp_servicename(params
->service
);
491 return (net_name
[strlen(net_name
) - 1] == '$');
494 /*******************************************************************
495 Fill in a share info structure.
496 ********************************************************************/
498 static WERROR
init_srv_share_info_ctr(pipes_struct
*p
,
499 union srvsvc_NetShareCtr
*ctr
,
500 uint32 info_level
, uint32
*resume_hnd
,
501 uint32
*total_entries
, BOOL all_shares
)
503 TALLOC_CTX
*ctx
= p
->mem_ctx
;
504 struct share_iterator
*shares
;
505 struct share_params
*share
;
507 DEBUG(5,("init_srv_share_info_ctr\n"));
515 /* Ensure all the usershares are loaded. */
517 load_usershare_shares();
522 if (!(shares
= share_list_all(ctx
))) {
523 DEBUG(5, ("Could not list shares\n"));
524 return WERR_ACCESS_DENIED
;
527 switch (info_level
) {
529 ctr
->ctr0
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr0
);
532 ctr
->ctr1
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr1
);
535 ctr
->ctr2
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr2
);
538 ctr
->ctr501
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr501
);
541 ctr
->ctr502
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr502
);
544 ctr
->ctr1004
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr1004
);
547 ctr
->ctr1005
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr1005
);
550 ctr
->ctr1006
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr1006
);
553 ctr
->ctr1007
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr1007
);
556 ctr
->ctr1501
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetShareCtr1501
);
559 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
560 "value %d\n", info_level
));
561 return WERR_UNKNOWN_LEVEL
;
564 while ((share
= next_share(shares
)) != NULL
) {
565 if (!lp_browseable(share
->service
)) {
568 if (!all_shares
&& is_hidden_share(share
)) {
572 switch (info_level
) {
575 struct srvsvc_NetShareInfo0 i
;
576 init_srv_share_info_0(p
, &i
, share
);
577 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo0
, i
,
578 &ctr
->ctr0
->array
, &ctr
->ctr0
->count
);
579 if (ctr
->ctr0
->array
== NULL
) {
582 *total_entries
= ctr
->ctr0
->count
;
588 struct srvsvc_NetShareInfo1 i
;
589 init_srv_share_info_1(p
, &i
, share
);
590 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo1
, i
,
591 &ctr
->ctr1
->array
, &ctr
->ctr1
->count
);
592 if (ctr
->ctr1
->array
== NULL
) {
595 *total_entries
= ctr
->ctr1
->count
;
601 struct srvsvc_NetShareInfo2 i
;
602 init_srv_share_info_2(p
, &i
, share
);
603 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo2
, i
,
604 &ctr
->ctr2
->array
, &ctr
->ctr2
->count
);
605 if (ctr
->ctr2
->array
== NULL
) {
608 *total_entries
= ctr
->ctr2
->count
;
614 struct srvsvc_NetShareInfo501 i
;
615 init_srv_share_info_501(p
, &i
, share
);
616 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo501
, i
,
617 &ctr
->ctr501
->array
, &ctr
->ctr501
->count
);
618 if (ctr
->ctr501
->array
== NULL
) {
621 *total_entries
= ctr
->ctr501
->count
;
627 struct srvsvc_NetShareInfo502 i
;
628 init_srv_share_info_502(p
, &i
, share
);
629 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo502
, i
,
630 &ctr
->ctr502
->array
, &ctr
->ctr502
->count
);
631 if (ctr
->ctr502
->array
== NULL
) {
634 *total_entries
= ctr
->ctr502
->count
;
638 /* here for completeness but not currently used with enum
643 struct srvsvc_NetShareInfo1004 i
;
644 init_srv_share_info_1004(p
, &i
, share
);
645 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo1004
, i
,
646 &ctr
->ctr1004
->array
, &ctr
->ctr1004
->count
);
647 if (ctr
->ctr1004
->array
== NULL
) {
650 *total_entries
= ctr
->ctr1004
->count
;
656 struct srvsvc_NetShareInfo1005 i
;
657 init_srv_share_info_1005(p
, &i
, share
);
658 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo1005
, i
,
659 &ctr
->ctr1005
->array
, &ctr
->ctr1005
->count
);
660 if (ctr
->ctr1005
->array
== NULL
) {
663 *total_entries
= ctr
->ctr1005
->count
;
669 struct srvsvc_NetShareInfo1006 i
;
670 init_srv_share_info_1006(p
, &i
, share
);
671 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo1006
, i
,
672 &ctr
->ctr1006
->array
, &ctr
->ctr1006
->count
);
673 if (ctr
->ctr1006
->array
== NULL
) {
676 *total_entries
= ctr
->ctr1006
->count
;
682 struct srvsvc_NetShareInfo1007 i
;
683 init_srv_share_info_1007(p
, &i
, share
);
684 ADD_TO_ARRAY(ctx
, struct srvsvc_NetShareInfo1007
, i
,
685 &ctr
->ctr1007
->array
, &ctr
->ctr1007
->count
);
686 if (ctr
->ctr1007
->array
== NULL
) {
689 *total_entries
= ctr
->ctr1007
->count
;
695 struct sec_desc_buf i
;
696 init_srv_share_info_1501(p
, &i
, share
);
697 ADD_TO_ARRAY(ctx
, struct sec_desc_buf
, i
,
698 &ctr
->ctr1501
->array
, &ctr
->ctr1501
->count
);
699 if (ctr
->ctr1501
->array
== NULL
) {
702 *total_entries
= ctr
->ctr1501
->count
;
713 /*******************************************************************
714 fill in a sess info level 0 structure.
715 ********************************************************************/
717 static void init_srv_sess_info_0(pipes_struct
*p
, struct srvsvc_NetSessCtr0
*ss0
, uint32
*snum
, uint32
*stot
)
719 struct sessionid
*session_list
;
720 uint32 num_entries
= 0;
721 (*stot
) = list_sessions(&session_list
);
727 SAFE_FREE(session_list
);
731 DEBUG(5,("init_srv_sess_0_ss0\n"));
733 ss0
->array
= talloc_array(p
->mem_ctx
, struct srvsvc_NetSessInfo0
, *stot
);
736 for (; (*snum
) < (*stot
); (*snum
)++) {
737 ss0
->array
[num_entries
].client
= session_list
[(*snum
)].remote_machine
;
741 ss0
->count
= num_entries
;
743 if ((*snum
) >= (*stot
)) {
751 SAFE_FREE(session_list
);
754 /*******************************************************************
755 ********************************************************************/
757 static void sess_file_fn( const struct share_mode_entry
*e
,
758 const char *sharepath
, const char *fname
,
761 struct sess_file_count
*sess
= (struct sess_file_count
*)private_data
;
763 if ( (procid_to_pid(&e
->pid
) == sess
->pid
) && (sess
->uid
== e
->uid
) ) {
770 /*******************************************************************
771 ********************************************************************/
773 static int net_count_files( uid_t uid
, pid_t pid
)
775 struct sess_file_count s_file_cnt
;
777 s_file_cnt
.count
= 0;
778 s_file_cnt
.uid
= uid
;
779 s_file_cnt
.pid
= pid
;
781 share_mode_forall( sess_file_fn
, (void *)&s_file_cnt
);
783 return s_file_cnt
.count
;
786 /*******************************************************************
787 fill in a sess info level 1 structure.
788 ********************************************************************/
790 static void init_srv_sess_info_1(pipes_struct
*p
, struct srvsvc_NetSessCtr1
*ss1
, uint32
*snum
, uint32
*stot
)
792 struct sessionid
*session_list
;
793 uint32 num_entries
= 0;
794 time_t now
= time(NULL
);
811 (*stot
) = list_sessions(&session_list
);
813 ss1
->array
= talloc_array(p
->mem_ctx
, struct srvsvc_NetSessInfo1
, *stot
);
815 for (; (*snum
) < (*stot
); (*snum
)++) {
818 struct passwd
*pw
= sys_getpwnam(session_list
[*snum
].username
);
822 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
823 session_list
[*snum
].username
));
827 connect_time
= (uint32
)(now
- session_list
[*snum
].connect_start
);
828 num_files
= net_count_files(pw
->pw_uid
, session_list
[*snum
].pid
);
829 guest
= strequal( session_list
[*snum
].username
, lp_guestaccount() );
831 ss1
->array
[num_entries
].client
= session_list
[*snum
].remote_machine
;
832 ss1
->array
[num_entries
].user
= session_list
[*snum
].username
;
833 ss1
->array
[num_entries
].num_open
= num_files
;
834 ss1
->array
[num_entries
].time
= connect_time
;
835 ss1
->array
[num_entries
].idle_time
= 0;
836 ss1
->array
[num_entries
].user_flags
= guest
;
841 ss1
->count
= num_entries
;
843 if ((*snum
) >= (*stot
)) {
847 SAFE_FREE(session_list
);
850 /*******************************************************************
851 makes a SRV_R_NET_SESS_ENUM structure.
852 ********************************************************************/
854 static WERROR
init_srv_sess_info_ctr(pipes_struct
*p
, union srvsvc_NetSessCtr
*ctr
,
855 int switch_value
, uint32
*resume_hnd
, uint32
*total_entries
)
857 WERROR status
= WERR_OK
;
858 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__
));
860 switch (switch_value
) {
862 ctr
->ctr0
= talloc(p
->mem_ctx
, struct srvsvc_NetSessCtr0
);
863 init_srv_sess_info_0(p
, ctr
->ctr0
, resume_hnd
, total_entries
);
866 ctr
->ctr1
= talloc(p
->mem_ctx
, struct srvsvc_NetSessCtr1
);
867 init_srv_sess_info_1(p
, ctr
->ctr1
, resume_hnd
, total_entries
);
870 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value
));
871 if (resume_hnd
!= NULL
)
873 (*total_entries
) = 0;
875 status
= WERR_UNKNOWN_LEVEL
;
882 /*******************************************************************
883 fill in a conn info level 0 structure.
884 ********************************************************************/
886 static void init_srv_conn_info_0(pipes_struct
*p
, struct srvsvc_NetConnCtr0
*ss0
, uint32
*snum
, uint32
*stot
)
888 uint32 num_entries
= 0;
897 DEBUG(5,("init_srv_conn_0_ss0\n"));
900 ss0
->array
= talloc_array(p
->mem_ctx
, struct srvsvc_NetConnInfo0
, *stot
);
901 for (; (*snum
) < (*stot
); (*snum
)++) {
903 ss0
->array
[num_entries
].conn_id
= (*stot
);
905 /* move on to creating next connection */
906 /* move on to creating next conn */
910 ss0
->count
= num_entries
;
912 if ((*snum
) >= (*stot
)) {
924 /*******************************************************************
925 fill in a conn info level 1 structure.
926 ********************************************************************/
928 static void init_srv_conn_info_1(pipes_struct
*p
, struct srvsvc_NetConnCtr1
*ss1
, uint32
*snum
, uint32
*stot
)
930 uint32 num_entries
= 0;
939 DEBUG(5,("init_srv_conn_1_ss1\n"));
942 ss1
->array
= talloc_array(p
->mem_ctx
, struct srvsvc_NetConnInfo1
, *stot
);
943 for (; (*snum
) < (*stot
); (*snum
)++) {
944 ss1
->array
[num_entries
].conn_id
= (*stot
);
945 ss1
->array
[num_entries
].conn_type
= 0x3;
946 ss1
->array
[num_entries
].num_open
= 1;
947 ss1
->array
[num_entries
].num_users
= 1;
948 ss1
->array
[num_entries
].conn_time
= 3;
949 ss1
->array
[num_entries
].user
= "dummy_user";
950 ss1
->array
[num_entries
].share
= "IPC$";
952 /* move on to creating next connection */
953 /* move on to creating next conn */
957 ss1
->count
= num_entries
;
959 if ((*snum
) >= (*stot
)) {
971 /*******************************************************************
972 makes a SRV_R_NET_CONN_ENUM structure.
973 ********************************************************************/
975 static WERROR
init_srv_conn_info_ctr(pipes_struct
*p
, union srvsvc_NetConnCtr
*ctr
,
976 int switch_value
, uint32
*resume_hnd
, uint32
*total_entries
)
978 WERROR status
= WERR_OK
;
979 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__
));
981 switch (switch_value
) {
983 init_srv_conn_info_0(p
, ctr
->ctr0
, resume_hnd
, total_entries
);
986 init_srv_conn_info_1(p
, ctr
->ctr1
, resume_hnd
, total_entries
);
989 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value
));
992 (*total_entries
) = 0;
993 status
= WERR_UNKNOWN_LEVEL
;
1000 /*******************************************************************
1001 makes a SRV_R_NET_FILE_ENUM structure.
1002 ********************************************************************/
1004 static WERROR
net_file_enum_3(pipes_struct
*p
, union srvsvc_NetFileCtr
*ctr
, uint32
*resume_hnd
, uint32
*num_entries
)
1006 TALLOC_CTX
*ctx
= get_talloc_ctx();
1009 /* TODO -- Windows enumerates
1011 (c) open directories and files */
1013 ctr
->ctr3
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetFileCtr3
);
1015 status
= net_enum_files( ctx
, &ctr
->ctr3
->array
, num_entries
, resume_hnd
);
1016 if ( !W_ERROR_IS_OK(status
))
1019 status
= net_enum_pipes( ctx
, &ctr
->ctr3
->array
, num_entries
, resume_hnd
);
1020 if ( !W_ERROR_IS_OK(status
))
1023 ctr
->ctr3
->count
= *num_entries
;
1028 /*******************************************************************
1029 *******************************************************************/
1031 WERROR
_srvsvc_NetFileEnum(pipes_struct
*p
, const char *server_unc
, const char *path
, const char *user
, uint32_t *level
, union srvsvc_NetFileCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
1035 return net_file_enum_3(p
, ctr
, resume_handle
, totalentries
);
1037 return WERR_UNKNOWN_LEVEL
;
1043 /*******************************************************************
1045 ********************************************************************/
1047 WERROR
_srvsvc_NetSrvGetInfo(pipes_struct
*p
, const char *server_unc
, uint32_t level
, union srvsvc_NetSrvInfo
*info
)
1049 WERROR status
= WERR_OK
;
1053 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__
));
1055 if (!pipe_access_check(p
)) {
1056 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1057 return WERR_ACCESS_DENIED
;
1062 /* Technically level 102 should only be available to
1063 Administrators but there isn't anything super-secret
1064 here, as most of it is made up. */
1067 info
->info102
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetSrvInfo102
);
1069 info
->info102
->platform_id
= 500;
1070 info
->info102
->version_major
= lp_major_announce_version();
1071 info
->info102
->version_minor
= lp_minor_announce_version();
1072 info
->info102
->server_name
= global_myname();
1073 info
->info102
->server_type
= lp_default_server_announce();
1074 info
->info102
->userpath
= "C:\\";
1075 info
->info102
->licenses
= 10000;
1076 info
->info102
->anndelta
= 3000;
1077 info
->info102
->disc
= 0xf;
1078 info
->info102
->users
= 0xffffffff;
1079 info
->info102
->hidden
= 0;
1080 info
->info102
->announce
= 240;
1081 info
->info102
->comment
= lp_serverstring();
1084 info
->info101
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetSrvInfo101
);
1085 info
->info101
->platform_id
= 500;
1086 info
->info101
->server_name
= global_myname();
1087 info
->info101
->version_major
= lp_major_announce_version();
1088 info
->info101
->version_minor
= lp_minor_announce_version();
1089 info
->info101
->server_type
= lp_default_server_announce();
1090 info
->info101
->comment
= lp_serverstring();
1093 info
->info100
= talloc_zero(p
->mem_ctx
, struct srvsvc_NetSrvInfo100
);
1094 info
->info100
->platform_id
= 500;
1095 info
->info100
->server_name
= global_myname();
1098 return WERR_UNKNOWN_LEVEL
;
1102 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__
));
1107 /*******************************************************************
1109 ********************************************************************/
1111 WERROR
_srvsvc_NetSrvSetInfo(pipes_struct
*p
, const char *server_unc
, uint32_t level
, union srvsvc_NetSrvInfo info
, uint32_t *parm_error
)
1113 /* Set up the net server set info structure. */
1118 /*******************************************************************
1120 ********************************************************************/
1122 WERROR
_srvsvc_NetConnEnum(pipes_struct
*p
, const char *server_unc
, const char *path
, uint32_t *level
, union srvsvc_NetConnCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
1124 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__
));
1129 return init_srv_conn_info_ctr(p
, ctr
, *level
, resume_handle
, totalentries
);
1132 /*******************************************************************
1134 ********************************************************************/
1136 WERROR
_srvsvc_NetSessEnum(pipes_struct
*p
, const char *server_unc
, const char *client
, const char *user
, uint32_t *level
, union srvsvc_NetSessCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
1138 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__
));
1143 return init_srv_sess_info_ctr(p
, ctr
,
1149 /*******************************************************************
1151 ********************************************************************/
1153 WERROR
_srvsvc_NetSessDel(pipes_struct
*p
, const char *server_unc
, const char *client
, const char *user
)
1155 struct sessionid
*session_list
;
1156 int num_sessions
, snum
;
1159 char *machine
= talloc_strdup(p
->mem_ctx
, server_unc
);
1161 /* strip leading backslashes if any */
1162 while (machine
[0] == '\\') {
1163 memmove(machine
, &machine
[1], strlen(machine
));
1166 num_sessions
= list_sessions(&session_list
);
1168 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__
));
1170 status
= WERR_ACCESS_DENIED
;
1172 /* fail out now if you are not root or not a domain admin */
1174 if ((p
->pipe_user
.ut
.uid
!= sec_initial_uid()) &&
1175 ( ! nt_token_check_domain_rid(p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
))) {
1180 for (snum
= 0; snum
< num_sessions
; snum
++) {
1182 if ((strequal(session_list
[snum
].username
, user
) || user
[0] == '\0' ) &&
1183 strequal(session_list
[snum
].remote_machine
, machine
)) {
1185 if (message_send_pid(pid_to_procid(session_list
[snum
].pid
), MSG_SHUTDOWN
, NULL
, 0, False
))
1190 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__
));
1194 SAFE_FREE(session_list
);
1199 /*******************************************************************
1201 ********************************************************************/
1203 WERROR
_srvsvc_NetShareEnumAll(pipes_struct
*p
, const char *server_unc
, uint32_t *level
, union srvsvc_NetShareCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
1205 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__
));
1207 if (!pipe_access_check(p
)) {
1208 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1209 return WERR_ACCESS_DENIED
;
1212 /* Create the list of shares for the response. */
1213 return init_srv_share_info_ctr(p
, ctr
, *level
,
1214 resume_handle
, totalentries
, True
);
1217 /*******************************************************************
1219 ********************************************************************/
1221 WERROR
_srvsvc_NetShareEnum(pipes_struct
*p
, const char *server_unc
, uint32_t *level
, union srvsvc_NetShareCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
1223 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__
));
1225 if (!pipe_access_check(p
)) {
1226 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1227 return WERR_ACCESS_DENIED
;
1230 /* Create the list of shares for the response. */
1231 return init_srv_share_info_ctr(p
, ctr
, *level
,
1232 resume_handle
, totalentries
, False
);
1235 /*******************************************************************
1237 ********************************************************************/
1239 WERROR
_srvsvc_NetShareGetInfo(pipes_struct
*p
, const char *server_unc
, const char *share_name
, uint32_t level
, union srvsvc_NetShareInfo
*info
)
1241 const struct share_params
*params
;
1243 params
= get_share_params(p
->mem_ctx
, share_name
);
1245 if (params
!= NULL
) {
1248 info
->info0
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo0
);
1249 init_srv_share_info_0(p
, info
->info0
,
1253 info
->info1
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1
);
1254 init_srv_share_info_1(p
, info
->info1
,
1258 info
->info2
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo2
);
1259 init_srv_share_info_2(p
, info
->info2
,
1263 info
->info501
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo501
);
1264 init_srv_share_info_501(p
, info
->info501
,
1268 info
->info502
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo502
);
1269 init_srv_share_info_502(p
, info
->info502
,
1273 /* here for completeness */
1275 info
->info1004
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1004
);
1276 init_srv_share_info_1004(p
, info
->info1004
,
1280 info
->info1005
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1005
);
1281 init_srv_share_info_1005(p
, info
->info1005
,
1285 /* here for completeness 1006 - 1501 */
1287 info
->info1006
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1006
);
1288 init_srv_share_info_1006(p
, info
->info1006
,
1292 info
->info1007
= talloc(p
->mem_ctx
, struct srvsvc_NetShareInfo1007
);
1293 init_srv_share_info_1007(p
, info
->info1007
,
1297 info
->info1501
= talloc(p
->mem_ctx
, struct sec_desc_buf
);
1298 init_srv_share_info_1501(p
, info
->info1501
,
1302 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1303 "switch value %d\n", level
));
1304 return WERR_UNKNOWN_LEVEL
;
1308 return WERR_INVALID_NAME
;
1314 /*******************************************************************
1315 Check a given DOS pathname is valid for a share.
1316 ********************************************************************/
1318 char *valid_share_pathname(char *dos_pathname
)
1322 /* Convert any '\' paths to '/' */
1323 unix_format(dos_pathname
);
1324 unix_clean_name(dos_pathname
);
1326 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1328 if (strlen(dos_pathname
) > 2 && ptr
[1] == ':' && ptr
[0] != '/')
1331 /* Only absolute paths allowed. */
1338 /*******************************************************************
1339 Net share set info. Modify share details.
1340 ********************************************************************/
1342 WERROR
_srvsvc_NetShareSetInfo(pipes_struct
*p
, const char *server_unc
, const char *share_name
, uint32_t level
, union srvsvc_NetShareInfo info
, uint32_t *parm_error
)
1351 SEC_DESC
*psd
= NULL
;
1352 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
1353 BOOL is_disk_op
= False
;
1354 int max_connections
= 0;
1355 fstring tmp_share_name
;
1357 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__
));
1361 if ( strequal(share_name
,"IPC$")
1362 || ( lp_enable_asu_support() && strequal(share_name
,"ADMIN$") )
1363 || strequal(share_name
,"global") )
1365 return WERR_ACCESS_DENIED
;
1368 fstrcpy(tmp_share_name
, share_name
);
1369 snum
= find_service(tmp_share_name
);
1371 /* Does this share exist ? */
1373 return WERR_NET_NAME_NOT_FOUND
;
1375 /* No change to printer shares. */
1376 if (lp_print_ok(snum
))
1377 return WERR_ACCESS_DENIED
;
1379 is_disk_op
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_diskop
);
1381 /* fail out now if you are not root and not a disk op */
1383 if ( p
->pipe_user
.ut
.uid
!= sec_initial_uid() && !is_disk_op
)
1384 return WERR_ACCESS_DENIED
;
1388 pstrcpy(pathname
, lp_pathname(snum
));
1389 pstrcpy(comment
, info
.info1
->comment
);
1390 type
= info
.info1
->type
;
1394 pstrcpy(comment
, info
.info2
->comment
);
1395 pstrcpy(pathname
, info
.info2
->path
);
1396 type
= info
.info2
->type
;
1397 max_connections
= (info
.info2
->max_users
== 0xffffffff) ? 0 : info
.info2
->max_users
;
1401 /* not supported on set but here for completeness */
1403 unistr2_to_ascii(comment
, &q_u
->info
.share
.info501
.info_501_str
.uni_remark
, sizeof(comment
));
1404 type
= q_u
->info
.share
.info501
.info_501
.type
;
1409 pstrcpy(comment
, info
.info502
->comment
);
1410 pstrcpy(pathname
, info
.info502
->path
);
1411 type
= info
.info502
->type
;
1412 psd
= info
.info502
->sd
;
1413 map_generic_share_sd_bits(psd
);
1416 pstrcpy(pathname
, lp_pathname(snum
));
1417 pstrcpy(comment
, info
.info1004
->comment
);
1418 type
= STYPE_DISKTREE
;
1421 /* XP re-sets the csc policy even if it wasn't changed by the
1422 user, so we must compare it to see if it's what is set in
1423 smb.conf, so that we can contine other ops like setting
1425 if (((info
.info1005
->dfs_flags
&
1426 SHARE_1005_CSC_POLICY_MASK
) >>
1427 SHARE_1005_CSC_POLICY_SHIFT
) == lp_csc_policy(snum
))
1430 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1431 return WERR_ACCESS_DENIED
;
1435 return WERR_ACCESS_DENIED
;
1437 pstrcpy(pathname
, lp_pathname(snum
));
1438 pstrcpy(comment
, lp_comment(snum
));
1439 psd
= info
.info1501
->sd
;
1440 map_generic_share_sd_bits(psd
);
1441 type
= STYPE_DISKTREE
;
1444 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level
));
1445 return WERR_UNKNOWN_LEVEL
;
1448 /* We can only modify disk shares. */
1449 if (type
!= STYPE_DISKTREE
)
1450 return WERR_ACCESS_DENIED
;
1452 /* Check if the pathname is valid. */
1453 if (!(path
= valid_share_pathname( pathname
)))
1454 return WERR_OBJECT_PATH_INVALID
;
1456 /* Ensure share name, pathname and comment don't contain '"' characters. */
1457 string_replace(tmp_share_name
, '"', ' ');
1458 string_replace(path
, '"', ' ');
1459 string_replace(comment
, '"', ' ');
1461 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1462 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1464 /* Only call modify function if something changed. */
1466 if (strcmp(path
, lp_pathname(snum
)) || strcmp(comment
, lp_comment(snum
))
1467 || (lp_max_connections(snum
) != max_connections
) )
1469 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1470 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1471 return WERR_ACCESS_DENIED
;
1474 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1475 lp_change_share_cmd(), dyn_CONFIGFILE
, share_name
, path
, comment
, max_connections
);
1477 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command
));
1479 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1484 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1485 /* Tell everyone we updated smb.conf. */
1486 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED
, NULL
, 0, False
, NULL
);
1492 /********* END SeDiskOperatorPrivilege BLOCK *********/
1494 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command
, ret
));
1497 return WERR_ACCESS_DENIED
;
1499 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name
));
1502 /* Replace SD if changed. */
1507 old_sd
= get_share_security(p
->mem_ctx
, lp_servicename(snum
),
1510 if (old_sd
&& !sec_desc_equal(old_sd
, psd
)) {
1511 if (!set_share_security(p
->mem_ctx
, share_name
, psd
))
1512 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1517 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__
));
1522 /*******************************************************************
1523 Net share add. Call 'add_share_command "sharename" "pathname"
1524 "comment" "max connections = "
1525 ********************************************************************/
1527 WERROR
_srvsvc_NetShareAdd(pipes_struct
*p
, const char *server_unc
, uint32_t level
, union srvsvc_NetShareInfo info
, uint32_t *parm_error
)
1537 SEC_DESC
*psd
= NULL
;
1538 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
1540 int max_connections
= 0;
1542 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__
));
1546 is_disk_op
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_diskop
);
1548 if (p
->pipe_user
.ut
.uid
!= sec_initial_uid() && !is_disk_op
)
1549 return WERR_ACCESS_DENIED
;
1551 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1552 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1553 return WERR_ACCESS_DENIED
;
1558 /* No path. Not enough info in a level 0 to do anything. */
1559 return WERR_ACCESS_DENIED
;
1561 /* Not enough info in a level 1 to do anything. */
1562 return WERR_ACCESS_DENIED
;
1564 pstrcpy(share_name
, info
.info2
->name
);
1565 pstrcpy(comment
, info
.info2
->comment
);
1566 pstrcpy(pathname
, info
.info2
->path
);
1567 max_connections
= (info
.info2
->max_users
== 0xffffffff) ? 0 : info
.info2
->max_users
;
1568 type
= info
.info2
->type
;
1571 /* No path. Not enough info in a level 501 to do anything. */
1572 return WERR_ACCESS_DENIED
;
1574 pstrcpy(share_name
, info
.info502
->name
);
1575 pstrcpy(comment
, info
.info502
->comment
);
1576 pstrcpy(pathname
, info
.info502
->path
);
1577 type
= info
.info502
->type
;
1578 psd
= info
.info502
->sd
;
1579 map_generic_share_sd_bits(psd
);
1582 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1588 return WERR_ACCESS_DENIED
;
1590 /* DFS only level. */
1591 return WERR_ACCESS_DENIED
;
1593 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level
));
1594 return WERR_UNKNOWN_LEVEL
;
1597 /* check for invalid share names */
1599 if ( !validate_net_name( share_name
, INVALID_SHARENAME_CHARS
, sizeof(share_name
) ) ) {
1600 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name
));
1601 return WERR_INVALID_NAME
;
1604 if ( strequal(share_name
,"IPC$") || strequal(share_name
,"global")
1605 || ( lp_enable_asu_support() && strequal(share_name
,"ADMIN$") ) )
1607 return WERR_ACCESS_DENIED
;
1610 snum
= find_service(share_name
);
1612 /* Share already exists. */
1614 return WERR_ALREADY_EXISTS
;
1616 /* We can only add disk shares. */
1617 if (type
!= STYPE_DISKTREE
)
1618 return WERR_ACCESS_DENIED
;
1620 /* Check if the pathname is valid. */
1621 if (!(path
= valid_share_pathname( pathname
)))
1622 return WERR_OBJECT_PATH_INVALID
;
1624 /* Ensure share name, pathname and comment don't contain '"' characters. */
1625 string_replace(share_name
, '"', ' ');
1626 string_replace(path
, '"', ' ');
1627 string_replace(comment
, '"', ' ');
1629 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1637 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command
));
1639 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1644 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1645 /* Tell everyone we updated smb.conf. */
1646 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED
, NULL
, 0, False
, NULL
);
1652 /********* END SeDiskOperatorPrivilege BLOCK *********/
1654 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command
, ret
));
1657 return WERR_ACCESS_DENIED
;
1660 if (!set_share_security(p
->mem_ctx
, share_name
, psd
)) {
1661 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name
));
1666 * We don't call reload_services() here, the message will
1667 * cause this to be done before the next packet is read
1668 * from the client. JRA.
1671 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__
));
1676 /*******************************************************************
1677 Net share delete. Call "delete share command" with the share name as
1679 ********************************************************************/
1681 WERROR
_srvsvc_NetShareDel(pipes_struct
*p
, const char *server_unc
, const char *share_name
, uint32_t reserved
)
1686 SE_PRIV se_diskop
= SE_DISK_OPERATOR
;
1688 fstring tmp_share_name
;
1690 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__
));
1692 if ( strequal(share_name
,"IPC$")
1693 || ( lp_enable_asu_support() && strequal(share_name
,"ADMIN$") )
1694 || strequal(share_name
,"global") )
1696 return WERR_ACCESS_DENIED
;
1699 fstrcpy(tmp_share_name
, share_name
);
1700 snum
= find_service(tmp_share_name
);
1703 return WERR_NO_SUCH_SHARE
;
1705 /* No change to printer shares. */
1706 if (lp_print_ok(snum
))
1707 return WERR_ACCESS_DENIED
;
1709 is_disk_op
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_diskop
);
1711 if (p
->pipe_user
.ut
.uid
!= sec_initial_uid() && !is_disk_op
)
1712 return WERR_ACCESS_DENIED
;
1714 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1715 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1716 return WERR_ACCESS_DENIED
;
1719 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\"",
1720 lp_delete_share_cmd(), dyn_CONFIGFILE
, lp_servicename(snum
));
1722 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command
));
1724 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1729 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
1730 /* Tell everyone we updated smb.conf. */
1731 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED
, NULL
, 0, False
, NULL
);
1737 /********* END SeDiskOperatorPrivilege BLOCK *********/
1739 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command
, ret
));
1742 return WERR_ACCESS_DENIED
;
1744 /* Delete the SD in the database. */
1745 delete_share_security(snum
);
1747 lp_killservice(snum
);
1752 WERROR
_srvsvc_NetShareDelSticky(pipes_struct
*p
, const char *server_unc
, const char *share_name
, uint32_t reserved
)
1754 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__
));
1756 return _srvsvc_NetShareDel(p
, server_unc
, share_name
, reserved
);
1759 /*******************************************************************
1761 ********************************************************************/
1763 WERROR
_srvsvc_NetRemoteTOD(pipes_struct
*p
, const char *server_unc
, struct srvsvc_NetRemoteTODInfo
*tod
)
1766 time_t unixdate
= time(NULL
);
1767 WERROR status
= WERR_OK
;
1769 /* We do this call first as if we do it *after* the gmtime call
1770 it overwrites the pointed-to values. JRA */
1772 uint32 zone
= get_time_zone(unixdate
)/60;
1774 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__
));
1776 t
= gmtime(&unixdate
);
1779 tod
->elapsed
= unixdate
;
1781 tod
->hours
= t
->tm_hour
;
1782 tod
->mins
= t
->tm_min
;
1783 tod
->secs
= t
->tm_sec
;
1785 tod
->timezone
= zone
;
1786 tod
->tinterval
= 10000;
1787 tod
->day
= t
->tm_mday
;
1788 tod
->month
= t
->tm_mon
+ 1;
1789 tod
->year
= 1900+t
->tm_year
;
1790 tod
->weekday
= t
->tm_wday
;
1792 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__
));
1797 /***********************************************************************************
1798 Win9x NT tools get security descriptor.
1799 ***********************************************************************************/
1801 WERROR
_srvsvc_NetGetFileSecurity(pipes_struct
*p
, const char *server_unc
, const char *share
, const char *file
, uint32_t securityinformation
, struct sec_desc_buf
*sd_buf
)
1803 SEC_DESC
*psd
= NULL
;
1806 files_struct
*fsp
= NULL
;
1810 connection_struct
*conn
= NULL
;
1811 BOOL became_user
= False
;
1812 WERROR status
= WERR_OK
;
1818 /* Null password is ok - we are already an authenticated user... */
1819 null_pw
= data_blob(NULL
, 0);
1822 conn
= make_connection(share
, null_pw
, "A:", p
->pipe_user
.vuid
, &nt_status
);
1826 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share
));
1827 status
= ntstatus_to_werror(nt_status
);
1831 if (!become_user(conn
, conn
->vuid
)) {
1832 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1833 status
= WERR_ACCESS_DENIED
;
1838 pstrcpy(tmp_file
, file
);
1839 unix_convert(tmp_file
, conn
, NULL
, &bad_path
, &st
);
1841 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file
));
1842 status
= WERR_ACCESS_DENIED
;
1846 if (!check_name(file
,conn
)) {
1847 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file
));
1848 status
= WERR_ACCESS_DENIED
;
1852 nt_status
= open_file_stat(conn
, file
, &st
, &fsp
);
1853 if (!NT_STATUS_IS_OK(nt_status
)) {
1854 /* Perhaps it is a directory */
1855 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_FILE_IS_A_DIRECTORY
))
1856 nt_status
= open_directory(conn
, file
, &st
,
1857 READ_CONTROL_ACCESS
,
1858 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1863 if (!NT_STATUS_IS_OK(nt_status
)) {
1864 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file
));
1865 status
= WERR_ACCESS_DENIED
;
1870 sd_size
= SMB_VFS_GET_NT_ACL(fsp
, fsp
->fsp_name
, (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
|DACL_SECURITY_INFORMATION
), &psd
);
1873 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file
));
1874 status
= WERR_ACCESS_DENIED
;
1878 sd_buf
->sd_size
= sd_size
;
1881 psd
->dacl
->revision
= (uint16
) NT4_ACL_REVISION
;
1883 close_file(fsp
, NORMAL_CLOSE
);
1885 close_cnum(conn
, p
->pipe_user
.vuid
);
1891 close_file(fsp
, NORMAL_CLOSE
);
1898 close_cnum(conn
, p
->pipe_user
.vuid
);
1903 /***********************************************************************************
1904 Win9x NT tools set security descriptor.
1905 ***********************************************************************************/
1907 WERROR
_srvsvc_NetSetFileSecurity(pipes_struct
*p
, const char *server_unc
, const char *share
, const char *file
, uint32_t securityinformation
, struct sec_desc_buf sd_buf
)
1911 files_struct
*fsp
= NULL
;
1915 connection_struct
*conn
= NULL
;
1916 BOOL became_user
= False
;
1917 WERROR status
= WERR_OK
;
1922 /* Null password is ok - we are already an authenticated user... */
1923 null_pw
= data_blob(NULL
, 0);
1926 conn
= make_connection(share
, null_pw
, "A:", p
->pipe_user
.vuid
, &nt_status
);
1930 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share
));
1931 status
= ntstatus_to_werror(nt_status
);
1935 if (!become_user(conn
, conn
->vuid
)) {
1936 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1937 status
= WERR_ACCESS_DENIED
;
1942 pstrcpy(tmp_file
, file
);
1943 unix_convert(tmp_file
, conn
, NULL
, &bad_path
, &st
);
1945 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file
));
1946 status
= WERR_ACCESS_DENIED
;
1950 if (!check_name(file
,conn
)) {
1951 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file
));
1952 status
= WERR_ACCESS_DENIED
;
1957 nt_status
= open_file_stat(conn
, file
, &st
, &fsp
);
1959 if (!NT_STATUS_IS_OK(nt_status
)) {
1960 /* Perhaps it is a directory */
1961 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_FILE_IS_A_DIRECTORY
))
1962 nt_status
= open_directory(conn
, file
, &st
,
1963 FILE_READ_ATTRIBUTES
,
1964 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1969 if (!NT_STATUS_IS_OK(nt_status
)) {
1970 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file
));
1971 status
= WERR_ACCESS_DENIED
;
1976 ret
= SMB_VFS_SET_NT_ACL(fsp
, fsp
->fsp_name
, securityinformation
, sd_buf
.sd
);
1979 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file
));
1980 status
= WERR_ACCESS_DENIED
;
1984 close_file(fsp
, NORMAL_CLOSE
);
1986 close_cnum(conn
, p
->pipe_user
.vuid
);
1992 close_file(fsp
, NORMAL_CLOSE
);
2000 close_cnum(conn
, p
->pipe_user
.vuid
);
2006 /***********************************************************************************
2007 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2008 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2009 These disks would the disks listed by this function.
2010 Users could then create shares relative to these disks. Watch out for moving these disks around.
2011 "Nigel Williams" <nigel@veritas.com>.
2012 ***********************************************************************************/
2014 static const char *server_disks
[] = {"C:"};
2016 static uint32
get_server_disk_count(void)
2018 return sizeof(server_disks
)/sizeof(server_disks
[0]);
2021 static uint32
init_server_disk_enum(uint32
*resume
)
2023 uint32 server_disk_count
= get_server_disk_count();
2025 /*resume can be an offset into the list for now*/
2027 if(*resume
& 0x80000000)
2030 if(*resume
> server_disk_count
)
2031 *resume
= server_disk_count
;
2033 return server_disk_count
- *resume
;
2036 static const char *next_server_disk_enum(uint32
*resume
)
2040 if(init_server_disk_enum(resume
) == 0)
2043 disk
= server_disks
[*resume
];
2047 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk
, *resume
));
2052 WERROR
_srvsvc_NetDiskEnum(pipes_struct
*p
, const char *server_unc
, uint32_t level
, struct srvsvc_NetDiskInfo
*info
, uint32_t maxlen
, uint32_t *totalentries
, uint32_t *resume_handle
)
2055 const char *disk_name
;
2057 WERROR status
= WERR_OK
;
2059 *totalentries
= init_server_disk_enum(resume_handle
);
2062 if(!(info
->disks
= TALLOC_ARRAY(p
->mem_ctx
, struct srvsvc_NetDiskInfo0
, MAX_SERVER_DISK_ENTRIES
))) {
2066 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2068 for(i
= 0; i
< MAX_SERVER_DISK_ENTRIES
-1 && (disk_name
= next_server_disk_enum(resume_handle
)); i
++) {
2073 /*copy disk name into a unicode string*/
2075 info
->disks
[i
].disk
= disk_name
;
2078 /* add a terminating null string. Is this there if there is more data to come? */
2083 info
->disks
[i
].disk
= "";
2088 /********************************************************************
2089 ********************************************************************/
2091 WERROR
_srvsvc_NetNameValidate(pipes_struct
*p
, const char *server_unc
, const char *name
, uint32_t name_type
, uint32_t flags
)
2095 if ((flags
!= 0x0) && (flags
!= 0x80000000)) {
2096 return WERR_INVALID_PARAM
;
2099 switch ( name_type
) {
2101 len
= strlen_m(name
);
2103 if ((flags
== 0x0) && (len
> 81)) {
2104 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name
));
2105 return WERR_INVALID_NAME
;
2107 if ((flags
== 0x80000000) && (len
> 13)) {
2108 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name
));
2109 return WERR_INVALID_NAME
;
2112 if ( ! validate_net_name( name
, INVALID_SHARENAME_CHARS
, sizeof(name
) ) ) {
2113 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name
));
2114 return WERR_INVALID_NAME
;
2119 return WERR_UNKNOWN_LEVEL
;
2126 /********************************************************************
2127 ********************************************************************/
2129 WERROR
_srvsvc_NetFileClose(pipes_struct
*p
, const char *server_unc
, uint32_t fid
)
2131 return WERR_ACCESS_DENIED
;
2134 WERROR
_srvsvc_NetCharDevEnum(pipes_struct
*p
, const char *server_unc
, uint32_t *level
, union srvsvc_NetCharDevCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
2136 p
->rng_fault_state
= True
;
2137 return WERR_NOT_SUPPORTED
;
2140 WERROR
_srvsvc_NetCharDevGetInfo(pipes_struct
*p
, const char *server_unc
, const char *device_name
, uint32_t level
, union srvsvc_NetCharDevInfo
*info
)
2142 p
->rng_fault_state
= True
;
2143 return WERR_NOT_SUPPORTED
;
2146 WERROR
_srvsvc_NetCharDevControl(pipes_struct
*p
, const char *server_unc
, const char *device_name
, uint32_t opcode
)
2148 p
->rng_fault_state
= True
;
2149 return WERR_NOT_SUPPORTED
;
2152 WERROR
_srvsvc_NetCharDevQEnum(pipes_struct
*p
, const char *server_unc
, const char *user
, uint32_t *level
, union srvsvc_NetCharDevQCtr
*ctr
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
2154 p
->rng_fault_state
= True
;
2155 return WERR_NOT_SUPPORTED
;
2158 WERROR
_srvsvc_NetCharDevQGetInfo(pipes_struct
*p
, const char *server_unc
, const char *queue_name
, const char *user
, uint32_t level
, union srvsvc_NetCharDevQInfo
*info
)
2160 p
->rng_fault_state
= True
;
2161 return WERR_NOT_SUPPORTED
;
2164 WERROR
_srvsvc_NetCharDevQSetInfo(pipes_struct
*p
, const char *server_unc
, const char *queue_name
, uint32_t level
, union srvsvc_NetCharDevQInfo info
, uint32_t *parm_error
)
2166 p
->rng_fault_state
= True
;
2167 return WERR_NOT_SUPPORTED
;
2170 WERROR
_srvsvc_NetCharDevQPurge(pipes_struct
*p
, const char *server_unc
, const char *queue_name
)
2172 p
->rng_fault_state
= True
;
2173 return WERR_NOT_SUPPORTED
;
2176 WERROR
_srvsvc_NetCharDevQPurgeSelf(pipes_struct
*p
, const char *server_unc
, const char *queue_name
, const char *computer_name
)
2178 p
->rng_fault_state
= True
;
2179 return WERR_NOT_SUPPORTED
;
2182 WERROR
_srvsvc_NetFileGetInfo(pipes_struct
*p
, const char *server_unc
, uint32_t fid
, uint32_t level
, union srvsvc_NetFileInfo
*info
)
2184 p
->rng_fault_state
= True
;
2185 return WERR_NOT_SUPPORTED
;
2188 WERROR
_srvsvc_NetShareCheck(pipes_struct
*p
, const char *server_unc
, const char *device_name
, enum srvsvc_ShareType
*type
)
2190 p
->rng_fault_state
= True
;
2191 return WERR_NOT_SUPPORTED
;
2194 WERROR
_srvsvc_NetServerStatisticsGet(pipes_struct
*p
, const char *server_unc
, const char *service
, uint32_t level
, uint32_t options
, struct srvsvc_Statistics
*stats
)
2196 p
->rng_fault_state
= True
;
2197 return WERR_NOT_SUPPORTED
;
2200 WERROR
_srvsvc_NetTransportAdd(pipes_struct
*p
, const char *server_unc
, uint32_t level
, union srvsvc_NetTransportInfo info
)
2202 p
->rng_fault_state
= True
;
2203 return WERR_NOT_SUPPORTED
;
2206 WERROR
_srvsvc_NetTransportEnum(pipes_struct
*p
, const char *server_unc
, uint32_t *level
, union srvsvc_NetTransportCtr
*transports
, uint32_t max_buffer
, uint32_t *totalentries
, uint32_t *resume_handle
)
2208 p
->rng_fault_state
= True
;
2209 return WERR_NOT_SUPPORTED
;
2212 WERROR
_srvsvc_NetTransportDel(pipes_struct
*p
, const char *server_unc
, uint32_t unknown
, struct srvsvc_NetTransportInfo0 transport
)
2214 p
->rng_fault_state
= True
;
2215 return WERR_NOT_SUPPORTED
;
2218 WERROR
_srvsvc_NetSetServiceBits(pipes_struct
*p
, const char *server_unc
, const char *transport
, uint32_t servicebits
, uint32_t updateimmediately
)
2220 p
->rng_fault_state
= True
;
2221 return WERR_NOT_SUPPORTED
;
2224 WERROR
_srvsvc_NetPathType(pipes_struct
*p
, const char *server_unc
, const char *path
, uint32_t pathflags
, uint32_t *pathtype
)
2226 p
->rng_fault_state
= True
;
2227 return WERR_NOT_SUPPORTED
;
2230 WERROR
_srvsvc_NetPathCanonicalize(pipes_struct
*p
, const char *server_unc
, const char *path
, uint8_t *can_path
, uint32_t maxbuf
, const char *prefix
, uint32_t *pathtype
, uint32_t pathflags
)
2232 p
->rng_fault_state
= True
;
2233 return WERR_NOT_SUPPORTED
;
2236 WERROR
_srvsvc_NetPathCompare(pipes_struct
*p
, const char *server_unc
, const char *path1
, const char *path2
, uint32_t pathtype
, uint32_t pathflags
)
2238 p
->rng_fault_state
= True
;
2239 return WERR_NOT_SUPPORTED
;
2242 WERROR
_srvsvc_NETRPRNAMECANONICALIZE(pipes_struct
*p
)
2244 p
->rng_fault_state
= True
;
2245 return WERR_NOT_SUPPORTED
;
2248 WERROR
_srvsvc_NetPRNameCompare(pipes_struct
*p
, const char *server_unc
, const char *name1
, const char *name2
, uint32_t name_type
, uint32_t flags
)
2250 p
->rng_fault_state
= True
;
2251 return WERR_NOT_SUPPORTED
;
2254 WERROR
_srvsvc_NetShareDelStart(pipes_struct
*p
, const char *server_unc
, const char *share
, uint32_t reserved
, struct policy_handle
*hnd
)
2256 p
->rng_fault_state
= True
;
2257 return WERR_NOT_SUPPORTED
;
2260 WERROR
_srvsvc_NetShareDelCommit(pipes_struct
*p
, struct policy_handle
*hnd
)
2262 p
->rng_fault_state
= True
;
2263 return WERR_NOT_SUPPORTED
;
2266 WERROR
_srvsvc_NetServerTransportAddEx(pipes_struct
*p
, const char *server_unc
, uint32_t level
, union srvsvc_NetTransportInfo info
)
2268 p
->rng_fault_state
= True
;
2269 return WERR_NOT_SUPPORTED
;
2272 WERROR
_srvsvc_NetServerSetServiceBitsEx(pipes_struct
*p
, const char *server_unc
, const char *emulated_server_unc
, const char *transport
, uint32_t servicebitsofinterest
, uint32_t servicebits
, uint32_t updateimmediately
)
2274 p
->rng_fault_state
= True
;
2275 return WERR_NOT_SUPPORTED
;
2278 WERROR
_srvsvc_NETRDFSGETVERSION(pipes_struct
*p
)
2280 p
->rng_fault_state
= True
;
2281 return WERR_NOT_SUPPORTED
;
2284 WERROR
_srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct
*p
)
2286 p
->rng_fault_state
= True
;
2287 return WERR_NOT_SUPPORTED
;
2290 WERROR
_srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct
*p
)
2292 p
->rng_fault_state
= True
;
2293 return WERR_NOT_SUPPORTED
;
2296 WERROR
_srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct
*p
)
2298 p
->rng_fault_state
= True
;
2299 return WERR_NOT_SUPPORTED
;
2302 WERROR
_srvsvc_NETRDFSSETSERVERINFO(pipes_struct
*p
)
2304 p
->rng_fault_state
= True
;
2305 return WERR_NOT_SUPPORTED
;
2308 WERROR
_srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct
*p
)
2310 p
->rng_fault_state
= True
;
2311 return WERR_NOT_SUPPORTED
;
2314 WERROR
_srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct
*p
)
2316 p
->rng_fault_state
= True
;
2317 return WERR_NOT_SUPPORTED
;
2320 WERROR
_srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct
*p
)
2322 p
->rng_fault_state
= True
;
2323 return WERR_NOT_SUPPORTED
;
2326 WERROR
_srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct
*p
)
2328 p
->rng_fault_state
= True
;
2329 return WERR_NOT_SUPPORTED
;
2332 WERROR
_srvsvc_NETRDFSMODIFYPREFIX(pipes_struct
*p
)
2334 p
->rng_fault_state
= True
;
2335 return WERR_NOT_SUPPORTED
;
2338 WERROR
_srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct
*p
)
2340 p
->rng_fault_state
= True
;
2341 return WERR_NOT_SUPPORTED
;