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 if (!(fenum->info[i].user = talloc_strdup(
84 fenum->ctx, uidtoname(prec.uid)))) {
85 /* There's not much we can do here. */
86 fenum->info[i].user = "";
88 if (!(fenum->info[i].path = talloc_strdup(
89 fenum->ctx, fullpath))) {
90 /* There's not much we can do here. */
91 fenum->info[i].path = "";
100 /*******************************************************************
101 ********************************************************************/
103 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
104 uint32 *count, uint32 *resume )
106 struct file_enum_count fenum;
107 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
110 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
111 return WERR_ACCESS_DENIED;
116 fenum.count = *count;
118 if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
119 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
120 tdb_errorstr(conn_tdb) ));
125 *count = fenum.count;
129 /*******************************************************************
130 ********************************************************************/
132 /* global needed to make use of the share_mode_forall() callback */
133 static struct file_enum_count f_enum_cnt;
135 static void enum_file_fn( const struct share_mode_entry *e,
136 const char *sharepath, const char *fname,
139 struct file_enum_count *fenum = &f_enum_cnt;
141 /* If the pid was not found delete the entry from connections.tdb */
143 if ( process_exists(e->pid) ) {
144 struct srvsvc_NetFileInfo3 *f;
145 int i = fenum->count;
147 struct byte_range_lock *brl;
152 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
154 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
159 /* need to count the number of locks on a file */
163 fsp.inode = e->inode;
165 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
166 num_locks = brl->num_locks;
170 if ( strcmp( fname, "." ) == 0 ) {
171 pstr_sprintf( fullpath, "C:%s", sharepath );
173 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
175 string_replace( fullpath, '/', '\\' );
177 /* mask out create (what ever that is) */
178 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
180 fenum->info[i].fid = e->share_file_id;
181 fenum->info[i].permissions = permissions;
182 fenum->info[i].num_locks = num_locks;
183 if (!(fenum->info[i].user = talloc_strdup(
184 fenum->ctx, uidtoname(e->uid)))) {
185 /* There's not much we can do here. */
186 fenum->info[i].user = "";
188 if (!(fenum->info[i].path = talloc_strdup(
189 fenum->ctx, fullpath))) {
190 /* There's not much we can do here. */
191 fenum->info[i].path = "";
201 /*******************************************************************
202 ********************************************************************/
204 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
205 uint32 *count, uint32 *resume )
207 f_enum_cnt.ctx = ctx;
208 f_enum_cnt.count = *count;
209 f_enum_cnt.info = *info;
211 share_mode_forall( enum_file_fn, NULL );
213 *info = f_enum_cnt.info;
214 *count = f_enum_cnt.count;
219 /*******************************************************************
220 Utility function to get the 'type' of a share from a share definition.
221 ********************************************************************/
222 static uint32 get_share_type(const struct share_params *params)
224 char *net_name = lp_servicename(params->service);
225 int len_net_name = strlen(net_name);
227 /* work out the share type */
228 uint32 type = STYPE_DISKTREE;
230 if (lp_print_ok(params->service))
232 if (strequal(lp_fstype(params->service), "IPC"))
234 if (net_name[len_net_name-1] == '$')
235 type |= STYPE_HIDDEN;
240 /*******************************************************************
241 Fill in a share info level 0 structure.
242 ********************************************************************/
244 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
245 const struct share_params *params)
247 sh0->name = lp_servicename(params->service);
250 /*******************************************************************
251 Fill in a share info level 1 structure.
252 ********************************************************************/
254 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
255 const struct share_params *params)
257 connection_struct *conn = p->conn;
259 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
260 conn->user, conn->connectpath, conn->gid,
261 get_current_username(),
262 current_user_info.domain,
263 lp_comment(params->service));
265 sh1->name = lp_servicename(params->service);
266 sh1->type = get_share_type(params);
269 /*******************************************************************
270 Fill in a share info level 2 structure.
271 ********************************************************************/
273 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
274 const struct share_params *params)
276 connection_struct *conn = p->conn;
279 int max_connections = lp_max_connections(params->service);
280 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
282 char *net_name = lp_servicename(params->service);
284 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
285 conn->user, conn->connectpath, conn->gid,
286 get_current_username(),
287 current_user_info.domain,
288 lp_comment(params->service));
289 path = talloc_asprintf(p->mem_ctx, "C:%s",
290 lp_pathname(params->service));
293 * Change / to \\ so that win2k will see it as a valid path. This was
294 * added to enable use of browsing in win2k add share dialog.
297 string_replace(path, '/', '\\');
299 count = count_current_connections( net_name, False );
300 sh2->name = net_name;
301 sh2->type = get_share_type(params);
302 sh2->comment = remark;
303 sh2->permissions = 0;
304 sh2->max_users = max_uses;
305 sh2->current_users = count;
310 /*******************************************************************
311 Map any generic bits to file specific bits.
312 ********************************************************************/
314 static void map_generic_share_sd_bits(SEC_DESC *psd)
317 SEC_ACL *ps_dacl = NULL;
326 for (i = 0; i < ps_dacl->num_aces; i++) {
327 SEC_ACE *psa = &ps_dacl->aces[i];
328 uint32 orig_mask = psa->access_mask;
330 se_map_generic(&psa->access_mask, &file_generic_mapping);
331 psa->access_mask |= orig_mask;
335 /*******************************************************************
336 Fill in a share info level 501 structure.
337 ********************************************************************/
339 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
340 const struct share_params *params)
342 connection_struct *conn = p->conn;
344 const char *net_name = lp_servicename(params->service);
346 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
347 conn->user, conn->connectpath, conn->gid,
348 get_current_username(),
349 current_user_info.domain,
350 lp_comment(params->service));
353 sh501->name = net_name;
354 sh501->type = get_share_type(params);
355 sh501->comment = remark;
356 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
359 /*******************************************************************
360 Fill in a share info level 502 structure.
361 ********************************************************************/
363 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
364 const struct share_params *params)
366 int max_connections = lp_max_connections(params->service);
367 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
368 connection_struct *conn = p->conn;
375 TALLOC_CTX *ctx = p->mem_ctx;
380 net_name = lp_servicename(params->service);
381 count = count_current_connections( net_name, False );
383 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
384 conn->user, conn->connectpath, conn->gid,
385 get_current_username(),
386 current_user_info.domain,
387 lp_comment(params->service));
389 path = talloc_asprintf(p->mem_ctx, "C:%s",
390 lp_pathname(params->service));
393 * Change / to \\ so that win2k will see it as a valid path. This was
394 * added to enable use of browsing in win2k add share dialog.
397 string_replace(path, '/', '\\');
399 sd = get_share_security(ctx, lp_servicename(params->service),
402 sh502->name = net_name;
403 sh502->type = get_share_type(params);
404 sh502->comment = remark;
406 sh502->password = "";
408 sh502->permissions = 0;
409 sh502->max_users = max_uses;
410 sh502->current_users = count;
414 /***************************************************************************
415 Fill in a share info level 1004 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1004(pipes_struct *p,
419 struct srvsvc_NetShareInfo1004* sh1004,
420 const struct share_params *params)
422 connection_struct *conn = p->conn;
425 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
426 conn->user, conn->connectpath, conn->gid,
427 get_current_username(),
428 current_user_info.domain,
429 lp_comment(params->service));
431 ZERO_STRUCTP(sh1004);
433 sh1004->comment = remark;
436 /***************************************************************************
437 Fill in a share info level 1005 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1005(pipes_struct *p,
441 struct srvsvc_NetShareInfo1005* sh1005,
442 const struct share_params *params)
444 sh1005->dfs_flags = 0;
446 if(lp_host_msdfs() && lp_msdfs_root(params->service))
448 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
450 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
452 /***************************************************************************
453 Fill in a share info level 1006 structure.
454 ***************************************************************************/
456 static void init_srv_share_info_1006(pipes_struct *p,
457 struct srvsvc_NetShareInfo1006* sh1006,
458 const struct share_params *params)
460 sh1006->max_users = -1;
463 /***************************************************************************
464 Fill in a share info level 1007 structure.
465 ***************************************************************************/
467 static void init_srv_share_info_1007(pipes_struct *p,
468 struct srvsvc_NetShareInfo1007* sh1007,
469 const struct share_params *params)
473 ZERO_STRUCTP(sh1007);
475 sh1007->flags = flags;
476 sh1007->alternate_directory_name = "";
479 /*******************************************************************
480 Fill in a share info level 1501 structure.
481 ********************************************************************/
483 static void init_srv_share_info_1501(pipes_struct *p,
484 struct sec_desc_buf *sh1501,
485 const struct share_params *params)
489 TALLOC_CTX *ctx = p->mem_ctx;
491 ZERO_STRUCTP(sh1501);
493 sd = get_share_security(ctx, lp_servicename(params->service),
499 /*******************************************************************
500 True if it ends in '$'.
501 ********************************************************************/
503 static BOOL is_hidden_share(const struct share_params *params)
505 const char *net_name = lp_servicename(params->service);
507 return (net_name[strlen(net_name) - 1] == '$');
510 /*******************************************************************
511 Fill in a share info structure.
512 ********************************************************************/
514 static WERROR init_srv_share_info_ctr(pipes_struct *p,
515 union srvsvc_NetShareCtr *ctr,
516 uint32 info_level, uint32 *resume_hnd,
517 uint32 *total_entries, BOOL all_shares)
519 TALLOC_CTX *ctx = p->mem_ctx;
520 struct share_iterator *shares;
521 struct share_params *share;
522 WERROR result = WERR_NOMEM;
524 DEBUG(5,("init_srv_share_info_ctr\n"));
532 /* Ensure all the usershares are loaded. */
534 load_usershare_shares();
535 load_registry_shares();
540 if (!(shares = share_list_all(ctx))) {
541 DEBUG(5, ("Could not list shares\n"));
542 return WERR_ACCESS_DENIED;
545 switch (info_level) {
547 if (!(ctr->ctr0 = talloc_zero(
548 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
553 if (!(ctr->ctr1 = talloc_zero(
554 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
559 if (!(ctr->ctr2 = talloc_zero(
560 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
565 if (!(ctr->ctr501 = talloc_zero(
566 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
571 if (!(ctr->ctr502 = talloc_zero(
572 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
577 if (!(ctr->ctr1004 = talloc_zero(
578 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
583 if (!(ctr->ctr1005 = talloc_zero(
584 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
589 if (!(ctr->ctr1006 = talloc_zero(
590 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
595 if (!(ctr->ctr1007 = talloc_zero(
596 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
601 if (!(ctr->ctr1501 = talloc_zero(
602 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
607 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
608 "value %d\n", info_level));
609 return WERR_UNKNOWN_LEVEL;
612 while ((share = next_share(shares)) != NULL) {
613 if (!lp_browseable(share->service)) {
616 if (!all_shares && is_hidden_share(share)) {
620 switch (info_level) {
623 struct srvsvc_NetShareInfo0 i;
624 init_srv_share_info_0(p, &i, share);
625 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
626 &ctr->ctr0->array, &ctr->ctr0->count);
627 if (ctr->ctr0->array == NULL) {
630 *total_entries = ctr->ctr0->count;
636 struct srvsvc_NetShareInfo1 i;
637 init_srv_share_info_1(p, &i, share);
638 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
639 &ctr->ctr1->array, &ctr->ctr1->count);
640 if (ctr->ctr1->array == NULL) {
643 *total_entries = ctr->ctr1->count;
649 struct srvsvc_NetShareInfo2 i;
650 init_srv_share_info_2(p, &i, share);
651 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
652 &ctr->ctr2->array, &ctr->ctr2->count);
653 if (ctr->ctr2->array == NULL) {
656 *total_entries = ctr->ctr2->count;
662 struct srvsvc_NetShareInfo501 i;
663 init_srv_share_info_501(p, &i, share);
664 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
665 &ctr->ctr501->array, &ctr->ctr501->count);
666 if (ctr->ctr501->array == NULL) {
669 *total_entries = ctr->ctr501->count;
675 struct srvsvc_NetShareInfo502 i;
676 init_srv_share_info_502(p, &i, share);
677 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
678 &ctr->ctr502->array, &ctr->ctr502->count);
679 if (ctr->ctr502->array == NULL) {
682 *total_entries = ctr->ctr502->count;
686 /* here for completeness but not currently used with enum
691 struct srvsvc_NetShareInfo1004 i;
692 init_srv_share_info_1004(p, &i, share);
693 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
694 &ctr->ctr1004->array, &ctr->ctr1004->count);
695 if (ctr->ctr1004->array == NULL) {
698 *total_entries = ctr->ctr1004->count;
704 struct srvsvc_NetShareInfo1005 i;
705 init_srv_share_info_1005(p, &i, share);
706 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
707 &ctr->ctr1005->array, &ctr->ctr1005->count);
708 if (ctr->ctr1005->array == NULL) {
711 *total_entries = ctr->ctr1005->count;
717 struct srvsvc_NetShareInfo1006 i;
718 init_srv_share_info_1006(p, &i, share);
719 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
720 &ctr->ctr1006->array, &ctr->ctr1006->count);
721 if (ctr->ctr1006->array == NULL) {
724 *total_entries = ctr->ctr1006->count;
730 struct srvsvc_NetShareInfo1007 i;
731 init_srv_share_info_1007(p, &i, share);
732 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
733 &ctr->ctr1007->array, &ctr->ctr1007->count);
734 if (ctr->ctr1007->array == NULL) {
737 *total_entries = ctr->ctr1007->count;
743 struct sec_desc_buf i;
744 init_srv_share_info_1501(p, &i, share);
745 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
746 &ctr->ctr1501->array, &ctr->ctr1501->count);
747 if (ctr->ctr1501->array == NULL) {
750 *total_entries = ctr->ctr1501->count;
764 /*******************************************************************
765 fill in a sess info level 0 structure.
766 ********************************************************************/
768 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
770 struct sessionid *session_list;
771 uint32 num_entries = 0;
772 (*stot) = list_sessions(&session_list);
778 SAFE_FREE(session_list);
782 DEBUG(5,("init_srv_sess_0_ss0\n"));
784 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
787 for (; (*snum) < (*stot); (*snum)++) {
788 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
792 ss0->count = num_entries;
794 if ((*snum) >= (*stot)) {
802 SAFE_FREE(session_list);
805 /*******************************************************************
806 ********************************************************************/
808 static void sess_file_fn( const struct share_mode_entry *e,
809 const char *sharepath, const char *fname,
812 struct sess_file_count *sess = (struct sess_file_count *)private_data;
814 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
821 /*******************************************************************
822 ********************************************************************/
824 static int net_count_files( uid_t uid, pid_t pid )
826 struct sess_file_count s_file_cnt;
828 s_file_cnt.count = 0;
829 s_file_cnt.uid = uid;
830 s_file_cnt.pid = pid;
832 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
834 return s_file_cnt.count;
837 /*******************************************************************
838 fill in a sess info level 1 structure.
839 ********************************************************************/
841 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
843 struct sessionid *session_list;
844 uint32 num_entries = 0;
845 time_t now = time(NULL);
862 (*stot) = list_sessions(&session_list);
864 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
866 for (; (*snum) < (*stot); (*snum)++) {
869 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
873 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
874 session_list[*snum].username));
878 connect_time = (uint32)(now - session_list[*snum].connect_start);
879 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
880 guest = strequal( session_list[*snum].username, lp_guestaccount() );
882 if (!(ss1->array[num_entries].client = talloc_strdup(
883 ss1->array, session_list[*snum].remote_machine))) {
884 ss1->array[num_entries].client = "";
886 if (!(ss1->array[num_entries].user = talloc_strdup(
887 ss1->array, session_list[*snum].username))) {
888 ss1->array[num_entries].user = "";
890 ss1->array[num_entries].num_open = num_files;
891 ss1->array[num_entries].time = connect_time;
892 ss1->array[num_entries].idle_time = 0;
893 ss1->array[num_entries].user_flags = guest;
898 ss1->count = num_entries;
900 if ((*snum) >= (*stot)) {
904 SAFE_FREE(session_list);
907 /*******************************************************************
908 makes a SRV_R_NET_SESS_ENUM structure.
909 ********************************************************************/
911 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
912 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
914 WERROR status = WERR_OK;
915 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
917 switch (switch_value) {
919 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
920 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
923 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
924 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
927 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
928 if (resume_hnd != NULL)
930 (*total_entries) = 0;
932 status = WERR_UNKNOWN_LEVEL;
939 /*******************************************************************
940 fill in a conn info level 0 structure.
941 ********************************************************************/
943 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
945 uint32 num_entries = 0;
954 DEBUG(5,("init_srv_conn_0_ss0\n"));
957 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
958 for (; (*snum) < (*stot); (*snum)++) {
960 ss0->array[num_entries].conn_id = (*stot);
962 /* move on to creating next connection */
963 /* move on to creating next conn */
967 ss0->count = num_entries;
969 if ((*snum) >= (*stot)) {
981 /*******************************************************************
982 fill in a conn info level 1 structure.
983 ********************************************************************/
985 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
987 uint32 num_entries = 0;
996 DEBUG(5,("init_srv_conn_1_ss1\n"));
999 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
1000 for (; (*snum) < (*stot); (*snum)++) {
1001 ss1->array[num_entries].conn_id = (*stot);
1002 ss1->array[num_entries].conn_type = 0x3;
1003 ss1->array[num_entries].num_open = 1;
1004 ss1->array[num_entries].num_users = 1;
1005 ss1->array[num_entries].conn_time = 3;
1006 ss1->array[num_entries].user = "dummy_user";
1007 ss1->array[num_entries].share = "IPC$";
1009 /* move on to creating next connection */
1010 /* move on to creating next conn */
1014 ss1->count = num_entries;
1016 if ((*snum) >= (*stot)) {
1028 /*******************************************************************
1029 makes a SRV_R_NET_CONN_ENUM structure.
1030 ********************************************************************/
1032 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1033 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1035 WERROR status = WERR_OK;
1036 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1038 switch (switch_value) {
1040 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1043 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1046 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1049 (*total_entries) = 0;
1050 status = WERR_UNKNOWN_LEVEL;
1057 /*******************************************************************
1058 makes a SRV_R_NET_FILE_ENUM structure.
1059 ********************************************************************/
1061 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1063 TALLOC_CTX *ctx = get_talloc_ctx();
1066 /* TODO -- Windows enumerates
1068 (c) open directories and files */
1070 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1072 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1073 if ( !W_ERROR_IS_OK(status))
1076 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1077 if ( !W_ERROR_IS_OK(status))
1080 ctr->ctr3->count = *num_entries;
1085 /*******************************************************************
1086 *******************************************************************/
1088 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1090 switch ( *r->in.level ) {
1092 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, r->out.totalentries );
1094 return WERR_UNKNOWN_LEVEL;
1100 /*******************************************************************
1102 ********************************************************************/
1104 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1106 WERROR status = WERR_OK;
1108 ZERO_STRUCTP(r->out.info);
1110 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1112 if (!pipe_access_check(p)) {
1113 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1114 return WERR_ACCESS_DENIED;
1117 switch (r->in.level) {
1119 /* Technically level 102 should only be available to
1120 Administrators but there isn't anything super-secret
1121 here, as most of it is made up. */
1124 r->out.info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1126 r->out.info->info102->platform_id = 500;
1127 r->out.info->info102->version_major = lp_major_announce_version();
1128 r->out.info->info102->version_minor = lp_minor_announce_version();
1129 r->out.info->info102->server_name = global_myname();
1130 r->out.info->info102->server_type = lp_default_server_announce();
1131 r->out.info->info102->userpath = "C:\\";
1132 r->out.info->info102->licenses = 10000;
1133 r->out.info->info102->anndelta = 3000;
1134 r->out.info->info102->disc = 0xf;
1135 r->out.info->info102->users = 0xffffffff;
1136 r->out.info->info102->hidden = 0;
1137 r->out.info->info102->announce = 240;
1138 r->out.info->info102->comment = lp_serverstring();
1141 r->out.info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1142 r->out.info->info101->platform_id = 500;
1143 r->out.info->info101->server_name = global_myname();
1144 r->out.info->info101->version_major = lp_major_announce_version();
1145 r->out.info->info101->version_minor = lp_minor_announce_version();
1146 r->out.info->info101->server_type = lp_default_server_announce();
1147 r->out.info->info101->comment = lp_serverstring();
1150 r->out.info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1151 r->out.info->info100->platform_id = 500;
1152 r->out.info->info100->server_name = global_myname();
1155 return WERR_UNKNOWN_LEVEL;
1159 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1164 /*******************************************************************
1166 ********************************************************************/
1168 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1170 /* Set up the net server set info structure. */
1171 if (r->out.parm_error) {
1172 *r->out.parm_error = 0;
1177 /*******************************************************************
1179 ********************************************************************/
1181 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1183 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1185 ZERO_STRUCTP(r->out.ctr);
1188 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1191 /*******************************************************************
1193 ********************************************************************/
1195 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1197 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1199 ZERO_STRUCTP(r->out.ctr);
1202 return init_srv_sess_info_ctr(p, r->out.ctr,
1204 r->in.resume_handle,
1205 r->out.totalentries);
1208 /*******************************************************************
1210 ********************************************************************/
1212 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1214 struct sessionid *session_list;
1215 int num_sessions, snum;
1218 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1220 /* strip leading backslashes if any */
1221 while (machine[0] == '\\') {
1222 memmove(machine, &machine[1], strlen(machine));
1225 num_sessions = list_sessions(&session_list);
1227 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1229 status = WERR_ACCESS_DENIED;
1231 /* fail out now if you are not root or not a domain admin */
1233 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1234 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1239 for (snum = 0; snum < num_sessions; snum++) {
1241 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1242 strequal(session_list[snum].remote_machine, machine)) {
1244 if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)))
1249 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1253 SAFE_FREE(session_list);
1258 /*******************************************************************
1260 ********************************************************************/
1262 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1264 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1266 if (!pipe_access_check(p)) {
1267 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1268 return WERR_ACCESS_DENIED;
1271 /* Create the list of shares for the response. */
1272 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1273 r->in.resume_handle, r->out.totalentries, True);
1276 /*******************************************************************
1278 ********************************************************************/
1280 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
1282 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1284 if (!pipe_access_check(p)) {
1285 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1286 return WERR_ACCESS_DENIED;
1289 /* Create the list of shares for the response. */
1290 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1291 r->in.resume_handle, r->out.totalentries, False);
1294 /*******************************************************************
1296 ********************************************************************/
1298 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1300 const struct share_params *params;
1302 params = get_share_params(p->mem_ctx, r->in.share_name);
1304 if (params != NULL) {
1305 switch (r->in.level) {
1307 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1308 init_srv_share_info_0(p, r->out.info->info0, params);
1311 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1312 init_srv_share_info_1(p, r->out.info->info1, params);
1315 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1316 init_srv_share_info_2(p, r->out.info->info2, params);
1319 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1320 init_srv_share_info_501(p, r->out.info->info501, params);
1323 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1324 init_srv_share_info_502(p, r->out.info->info502, params);
1327 /* here for completeness */
1329 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1330 init_srv_share_info_1004(p, r->out.info->info1004, params);
1333 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1334 init_srv_share_info_1005(p, r->out.info->info1005, params);
1337 /* here for completeness 1006 - 1501 */
1339 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1340 init_srv_share_info_1006(p, r->out.info->info1006,
1344 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1345 init_srv_share_info_1007(p, r->out.info->info1007,
1349 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1350 init_srv_share_info_1501(p, r->out.info->info1501,
1354 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1355 "switch value %d\n", r->in.level));
1356 return WERR_UNKNOWN_LEVEL;
1360 return WERR_INVALID_NAME;
1366 /*******************************************************************
1367 Check a given DOS pathname is valid for a share.
1368 ********************************************************************/
1370 char *valid_share_pathname(char *dos_pathname)
1374 /* Convert any '\' paths to '/' */
1375 unix_format(dos_pathname);
1376 unix_clean_name(dos_pathname);
1378 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1380 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1383 /* Only absolute paths allowed. */
1390 static void setval_helper(struct registry_key *key, const char *name,
1391 const char *value, WERROR *err)
1393 struct registry_value val;
1395 if (!W_ERROR_IS_OK(*err)) {
1401 val.v.sz.str = CONST_DISCARD(char *, value);
1402 val.v.sz.len = strlen(value)+1;
1404 *err = reg_setvalue(key, name, &val);
1407 static WERROR add_share(const char *share_name, const char *path,
1408 const char *comment, uint32 max_connections,
1409 const struct nt_user_token *token,
1412 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1416 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1417 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1418 path, comment, max_connections) == -1) {
1422 DEBUG(10,("add_share: Running [%s]\n", command ));
1424 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1429 if ( (ret = smbrun(command, NULL)) == 0 ) {
1430 /* Tell everyone we updated smb.conf. */
1431 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1432 NULL, 0, False, NULL);
1438 /********* END SeDiskOperatorPrivilege BLOCK *********/
1440 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1444 * No fallback to registry shares, the user did define a add
1445 * share command, so fail here.
1449 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1452 if (lp_registry_shares()) {
1454 struct registry_key *key;
1455 enum winreg_CreateAction action;
1457 TALLOC_CTX *mem_ctx;
1459 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1464 mem_ctx = (TALLOC_CTX *)keyname;
1466 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1467 is_disk_op ? get_root_nt_token():token,
1470 if (action != REG_CREATED_NEW_KEY) {
1471 err = WERR_ALREADY_EXISTS;
1474 if (!W_ERROR_IS_OK(err)) {
1475 TALLOC_FREE(mem_ctx);
1479 setval_helper(key, "path", path, &err);
1480 if ((comment != NULL) && (comment[0] != '\0')) {
1481 setval_helper(key, "comment", comment, &err);
1483 if (max_connections != 0) {
1485 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1486 setval_helper(key, "max connections", tmp, &err);
1489 if (!W_ERROR_IS_OK(err)) {
1491 * Hmmmm. We'd need transactions on the registry to
1492 * get this right....
1494 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1497 TALLOC_FREE(mem_ctx);
1501 return WERR_ACCESS_DENIED;
1504 static WERROR delete_share(const char *sharename,
1505 const struct nt_user_token *token,
1508 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1512 if (asprintf(&command, "%s \"%s\" \"%s\"",
1513 lp_delete_share_cmd(), dyn_CONFIGFILE,
1518 DEBUG(10,("delete_share: Running [%s]\n", command ));
1520 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1525 if ( (ret = smbrun(command, NULL)) == 0 ) {
1526 /* Tell everyone we updated smb.conf. */
1527 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1528 NULL, 0, False, NULL);
1534 /********* END SeDiskOperatorPrivilege BLOCK *********/
1538 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1540 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1543 if (lp_registry_shares()) {
1547 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1552 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1558 return WERR_ACCESS_DENIED;
1561 static WERROR change_share(const char *share_name, const char *path,
1562 const char *comment, uint32 max_connections,
1563 const struct nt_user_token *token,
1566 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1570 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1571 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1572 path, comment, max_connections) == -1) {
1576 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1578 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1583 if ( (ret = smbrun(command, NULL)) == 0 ) {
1584 /* Tell everyone we updated smb.conf. */
1585 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1586 NULL, 0, False, NULL);
1592 /********* END SeDiskOperatorPrivilege BLOCK *********/
1594 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1595 "(%d)\n", command, ret ));
1599 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1602 if (lp_registry_shares()) {
1604 struct registry_key *key;
1606 TALLOC_CTX *mem_ctx;
1608 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1613 mem_ctx = (TALLOC_CTX *)keyname;
1615 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1616 is_disk_op ? get_root_nt_token():token,
1618 if (!W_ERROR_IS_OK(err)) {
1619 TALLOC_FREE(mem_ctx);
1623 setval_helper(key, "path", path, &err);
1625 reg_deletevalue(key, "comment");
1626 if ((comment != NULL) && (comment[0] != '\0')) {
1627 setval_helper(key, "comment", comment, &err);
1630 reg_deletevalue(key, "max connections");
1631 if (max_connections != 0) {
1633 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1634 setval_helper(key, "max connections", tmp, &err);
1637 TALLOC_FREE(mem_ctx);
1641 return WERR_ACCESS_DENIED;
1644 /*******************************************************************
1645 Net share set info. Modify share details.
1646 ********************************************************************/
1648 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1655 SEC_DESC *psd = NULL;
1656 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1657 BOOL is_disk_op = False;
1658 int max_connections = 0;
1659 fstring tmp_share_name;
1661 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1663 if (r->out.parm_error) {
1664 *r->out.parm_error = 0;
1667 if ( strequal(r->in.share_name,"IPC$")
1668 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1669 || strequal(r->in.share_name,"global") )
1671 return WERR_ACCESS_DENIED;
1674 fstrcpy(tmp_share_name, r->in.share_name);
1675 snum = find_service(tmp_share_name);
1677 /* Does this share exist ? */
1679 return WERR_NET_NAME_NOT_FOUND;
1681 /* No change to printer shares. */
1682 if (lp_print_ok(snum))
1683 return WERR_ACCESS_DENIED;
1685 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1688 /* fail out now if you are not root and not a disk op */
1690 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1691 return WERR_ACCESS_DENIED;
1693 switch (r->in.level) {
1695 pstrcpy(pathname, lp_pathname(snum));
1696 pstrcpy(comment, r->in.info.info1->comment);
1697 type = r->in.info.info1->type;
1701 pstrcpy(comment, r->in.info.info2->comment);
1702 pstrcpy(pathname, r->in.info.info2->path);
1703 type = r->in.info.info2->type;
1704 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1705 0 : r->in.info.info2->max_users;
1709 pstrcpy(comment, r->in.info.info502->comment);
1710 pstrcpy(pathname, r->in.info.info502->path);
1711 type = r->in.info.info502->type;
1712 psd = r->in.info.info502->sd;
1713 map_generic_share_sd_bits(psd);
1716 pstrcpy(pathname, lp_pathname(snum));
1717 pstrcpy(comment, r->in.info.info1004->comment);
1718 type = STYPE_DISKTREE;
1721 /* XP re-sets the csc policy even if it wasn't changed by the
1722 user, so we must compare it to see if it's what is set in
1723 smb.conf, so that we can contine other ops like setting
1725 if (((r->in.info.info1005->dfs_flags &
1726 SHARE_1005_CSC_POLICY_MASK) >>
1727 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1730 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1731 "to change csc policy from the network; "
1732 "must be done with smb.conf\n"));
1733 return WERR_ACCESS_DENIED;
1737 return WERR_ACCESS_DENIED;
1739 pstrcpy(pathname, lp_pathname(snum));
1740 pstrcpy(comment, lp_comment(snum));
1741 psd = r->in.info.info1501->sd;
1742 map_generic_share_sd_bits(psd);
1743 type = STYPE_DISKTREE;
1746 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1747 "%d\n", r->in.level));
1748 return WERR_UNKNOWN_LEVEL;
1751 /* We can only modify disk shares. */
1752 if (type != STYPE_DISKTREE)
1753 return WERR_ACCESS_DENIED;
1755 /* Check if the pathname is valid. */
1756 if (!(path = valid_share_pathname( pathname )))
1757 return WERR_OBJECT_PATH_INVALID;
1759 /* Ensure share name, pathname and comment don't contain '"'
1761 string_replace(tmp_share_name, '"', ' ');
1762 string_replace(path, '"', ' ');
1763 string_replace(comment, '"', ' ');
1765 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1766 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1768 /* Only call modify function if something changed. */
1770 if (strcmp(path, lp_pathname(snum))
1771 || strcmp(comment, lp_comment(snum))
1772 || (lp_max_connections(snum) != max_connections) ) {
1775 err = change_share(tmp_share_name, path, comment,
1776 max_connections, p->pipe_user.nt_user_token,
1779 if (!W_ERROR_IS_OK(err)) {
1784 /* Replace SD if changed. */
1789 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1792 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1793 if (!set_share_security(r->in.share_name, psd)) {
1794 DEBUG(0,("_srv_net_share_set_info: Failed to "
1795 "change security info in share %s.\n",
1796 r->in.share_name ));
1801 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1807 /*******************************************************************
1808 Net share add. Call 'add_share_command "sharename" "pathname"
1809 "comment" "max connections = "
1810 ********************************************************************/
1812 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1819 SEC_DESC *psd = NULL;
1820 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1822 uint32 max_connections = 0;
1825 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1827 if (r->out.parm_error) {
1828 *r->out.parm_error = 0;
1831 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1834 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1835 return WERR_ACCESS_DENIED;
1837 switch (r->in.level) {
1839 /* No path. Not enough info in a level 0 to do anything. */
1840 return WERR_ACCESS_DENIED;
1842 /* Not enough info in a level 1 to do anything. */
1843 return WERR_ACCESS_DENIED;
1845 pstrcpy(share_name, r->in.info.info2->name);
1846 pstrcpy(comment, r->in.info.info2->comment);
1847 pstrcpy(pathname, r->in.info.info2->path);
1848 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1849 0 : r->in.info.info2->max_users;
1850 type = r->in.info.info2->type;
1853 /* No path. Not enough info in a level 501 to do anything. */
1854 return WERR_ACCESS_DENIED;
1856 pstrcpy(share_name, r->in.info.info502->name);
1857 pstrcpy(comment, r->in.info.info502->comment);
1858 pstrcpy(pathname, r->in.info.info502->path);
1859 type = r->in.info.info502->type;
1860 psd = r->in.info.info502->sd;
1861 map_generic_share_sd_bits(psd);
1864 /* none of the following contain share names. NetShareAdd
1865 * does not have a separate parameter for the share name */
1871 return WERR_ACCESS_DENIED;
1873 /* DFS only level. */
1874 return WERR_ACCESS_DENIED;
1876 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1878 return WERR_UNKNOWN_LEVEL;
1881 /* check for invalid share names */
1883 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1884 sizeof(share_name) ) ) {
1885 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1887 return WERR_INVALID_NAME;
1890 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1891 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1893 return WERR_ACCESS_DENIED;
1896 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1897 /* Share already exists. */
1898 return WERR_ALREADY_EXISTS;
1901 /* We can only add disk shares. */
1902 if (type != STYPE_DISKTREE)
1903 return WERR_ACCESS_DENIED;
1905 /* Check if the pathname is valid. */
1906 if (!(path = valid_share_pathname( pathname )))
1907 return WERR_OBJECT_PATH_INVALID;
1909 /* Ensure share name, pathname and comment don't contain '"'
1912 string_replace(share_name, '"', ' ');
1913 string_replace(path, '"', ' ');
1914 string_replace(comment, '"', ' ');
1916 err = add_share(share_name, path, comment, max_connections,
1917 p->pipe_user.nt_user_token, is_disk_op);
1919 if (!W_ERROR_IS_OK(err)) {
1924 if (!set_share_security(share_name, psd)) {
1925 DEBUG(0,("_srv_net_share_add: Failed to add security "
1926 "info to share %s.\n", share_name ));
1931 * We don't call reload_services() here, the message will
1932 * cause this to be done before the next packet is read
1933 * from the client. JRA.
1936 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1941 /*******************************************************************
1942 Net share delete. Call "delete share command" with the share name as
1944 ********************************************************************/
1946 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1948 struct share_params *params;
1949 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1953 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1955 if ( strequal(r->in.share_name, "IPC$")
1956 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1957 || strequal(r->in.share_name, "global") )
1959 return WERR_ACCESS_DENIED;
1962 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1963 return WERR_NO_SUCH_SHARE;
1966 /* No change to printer shares. */
1967 if (lp_print_ok(params->service))
1968 return WERR_ACCESS_DENIED;
1970 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1973 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1974 return WERR_ACCESS_DENIED;
1976 err = delete_share(lp_servicename(params->service),
1977 p->pipe_user.nt_user_token, is_disk_op);
1979 if (!W_ERROR_IS_OK(err)) {
1983 /* Delete the SD in the database. */
1984 delete_share_security(params);
1986 lp_killservice(params->service);
1991 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
1993 struct srvsvc_NetShareDel s;
1995 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1997 s.in.server_unc = r->in.server_unc;
1998 s.in.share_name = r->in.share_name;
1999 s.in.reserved = r->in.reserved;
2001 return _srvsvc_NetShareDel(p, &s);
2004 /*******************************************************************
2006 ********************************************************************/
2008 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
2011 time_t unixdate = time(NULL);
2012 WERROR status = WERR_OK;
2014 /* We do this call first as if we do it *after* the gmtime call
2015 it overwrites the pointed-to values. JRA */
2017 uint32 zone = get_time_zone(unixdate)/60;
2019 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2021 t = gmtime(&unixdate);
2024 r->out.info->elapsed = unixdate;
2025 r->out.info->msecs = 0;
2026 r->out.info->hours = t->tm_hour;
2027 r->out.info->mins = t->tm_min;
2028 r->out.info->secs = t->tm_sec;
2029 r->out.info->hunds = 0;
2030 r->out.info->timezone = zone;
2031 r->out.info->tinterval = 10000;
2032 r->out.info->day = t->tm_mday;
2033 r->out.info->month = t->tm_mon + 1;
2034 r->out.info->year = 1900+t->tm_year;
2035 r->out.info->weekday = t->tm_wday;
2037 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2042 /***********************************************************************************
2043 Win9x NT tools get security descriptor.
2044 ***********************************************************************************/
2046 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2048 SEC_DESC *psd = NULL;
2051 files_struct *fsp = NULL;
2054 connection_struct *conn = NULL;
2055 BOOL became_user = False;
2056 WERROR status = WERR_OK;
2062 /* Null password is ok - we are already an authenticated user... */
2063 null_pw = data_blob(NULL, 0);
2066 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2070 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2071 status = ntstatus_to_werror(nt_status);
2075 if (!become_user(conn, conn->vuid)) {
2076 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2077 status = WERR_ACCESS_DENIED;
2082 pstrcpy(tmp_file, r->in.file);
2083 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2084 if (!NT_STATUS_IS_OK(nt_status)) {
2085 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2086 status = WERR_ACCESS_DENIED;
2090 nt_status = check_name(conn, r->in.file);
2091 if (!NT_STATUS_IS_OK(nt_status)) {
2092 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", r->in.file));
2093 status = WERR_ACCESS_DENIED;
2097 nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2098 if (!NT_STATUS_IS_OK(nt_status)) {
2099 /* Perhaps it is a directory */
2100 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2101 nt_status = open_directory(conn, r->in.file, &st,
2102 READ_CONTROL_ACCESS,
2103 FILE_SHARE_READ|FILE_SHARE_WRITE,
2106 FILE_ATTRIBUTE_DIRECTORY,
2109 if (!NT_STATUS_IS_OK(nt_status)) {
2110 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", r->in.file));
2111 status = WERR_ACCESS_DENIED;
2116 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2119 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", r->in.file));
2120 status = WERR_ACCESS_DENIED;
2124 r->out.sd_buf->sd_size= sd_size;
2125 r->out.sd_buf->sd = psd;
2127 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2129 close_file(fsp, NORMAL_CLOSE);
2131 close_cnum(conn, p->pipe_user.vuid);
2137 close_file(fsp, NORMAL_CLOSE);
2144 close_cnum(conn, p->pipe_user.vuid);
2149 /***********************************************************************************
2150 Win9x NT tools set security descriptor.
2151 ***********************************************************************************/
2153 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2157 files_struct *fsp = NULL;
2160 connection_struct *conn = NULL;
2161 BOOL became_user = False;
2162 WERROR status = WERR_OK;
2167 /* Null password is ok - we are already an authenticated user... */
2168 null_pw = data_blob(NULL, 0);
2171 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2175 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2176 status = ntstatus_to_werror(nt_status);
2180 if (!become_user(conn, conn->vuid)) {
2181 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2182 status = WERR_ACCESS_DENIED;
2187 pstrcpy(tmp_file, r->in.file);
2188 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2189 if (!NT_STATUS_IS_OK(nt_status)) {
2190 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2191 status = WERR_ACCESS_DENIED;
2195 nt_status = check_name(conn, r->in.file);
2196 if (!NT_STATUS_IS_OK(nt_status)) {
2197 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", r->in.file));
2198 status = WERR_ACCESS_DENIED;
2203 nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2205 if (!NT_STATUS_IS_OK(nt_status)) {
2206 /* Perhaps it is a directory */
2207 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2208 nt_status = open_directory(conn, r->in.file, &st,
2209 FILE_READ_ATTRIBUTES,
2210 FILE_SHARE_READ|FILE_SHARE_WRITE,
2213 FILE_ATTRIBUTE_DIRECTORY,
2216 if (!NT_STATUS_IS_OK(nt_status)) {
2217 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", r->in.file));
2218 status = WERR_ACCESS_DENIED;
2223 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2226 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
2227 status = WERR_ACCESS_DENIED;
2231 close_file(fsp, NORMAL_CLOSE);
2233 close_cnum(conn, p->pipe_user.vuid);
2239 close_file(fsp, NORMAL_CLOSE);
2247 close_cnum(conn, p->pipe_user.vuid);
2253 /***********************************************************************************
2254 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2255 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2256 These disks would the disks listed by this function.
2257 Users could then create shares relative to these disks. Watch out for moving these disks around.
2258 "Nigel Williams" <nigel@veritas.com>.
2259 ***********************************************************************************/
2261 static const char *server_disks[] = {"C:"};
2263 static uint32 get_server_disk_count(void)
2265 return sizeof(server_disks)/sizeof(server_disks[0]);
2268 static uint32 init_server_disk_enum(uint32 *resume)
2270 uint32 server_disk_count = get_server_disk_count();
2272 /*resume can be an offset into the list for now*/
2274 if(*resume & 0x80000000)
2277 if(*resume > server_disk_count)
2278 *resume = server_disk_count;
2280 return server_disk_count - *resume;
2283 static const char *next_server_disk_enum(uint32 *resume)
2287 if(init_server_disk_enum(resume) == 0)
2290 disk = server_disks[*resume];
2294 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2299 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2302 const char *disk_name;
2304 WERROR status = WERR_OK;
2306 *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2307 r->out.info->count = 0;
2309 if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2313 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2315 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2317 r->out.info->count++;
2318 (*r->out.totalentries)++;
2320 /*copy disk name into a unicode string*/
2322 r->out.info->disks[i].disk = disk_name;
2325 /* add a terminating null string. Is this there if there is more data to come? */
2327 r->out.info->count++;
2328 (*r->out.totalentries)++;
2330 r->out.info->disks[i].disk = "";
2335 /********************************************************************
2336 ********************************************************************/
2338 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2342 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2343 return WERR_INVALID_PARAM;
2346 switch ( r->in.name_type ) {
2348 len = strlen_m(r->in.name);
2350 if ((r->in.flags == 0x0) && (len > 81)) {
2351 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2352 return WERR_INVALID_NAME;
2354 if ((r->in.flags == 0x80000000) && (len > 13)) {
2355 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2356 return WERR_INVALID_NAME;
2359 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2360 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2361 return WERR_INVALID_NAME;
2366 return WERR_UNKNOWN_LEVEL;
2373 /********************************************************************
2374 ********************************************************************/
2376 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2378 return WERR_ACCESS_DENIED;
2381 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2383 p->rng_fault_state = True;
2384 return WERR_NOT_SUPPORTED;
2387 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2389 p->rng_fault_state = True;
2390 return WERR_NOT_SUPPORTED;
2393 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2395 p->rng_fault_state = True;
2396 return WERR_NOT_SUPPORTED;
2399 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2401 p->rng_fault_state = True;
2402 return WERR_NOT_SUPPORTED;
2405 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2407 p->rng_fault_state = True;
2408 return WERR_NOT_SUPPORTED;
2411 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2413 p->rng_fault_state = True;
2414 return WERR_NOT_SUPPORTED;
2417 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2419 p->rng_fault_state = True;
2420 return WERR_NOT_SUPPORTED;
2423 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2425 p->rng_fault_state = True;
2426 return WERR_NOT_SUPPORTED;
2429 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2431 p->rng_fault_state = True;
2432 return WERR_NOT_SUPPORTED;
2435 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2437 p->rng_fault_state = True;
2438 return WERR_NOT_SUPPORTED;
2441 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2443 p->rng_fault_state = True;
2444 return WERR_NOT_SUPPORTED;
2447 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2449 p->rng_fault_state = True;
2450 return WERR_NOT_SUPPORTED;
2453 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2455 p->rng_fault_state = True;
2456 return WERR_NOT_SUPPORTED;
2459 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2461 p->rng_fault_state = True;
2462 return WERR_NOT_SUPPORTED;
2465 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2467 p->rng_fault_state = True;
2468 return WERR_NOT_SUPPORTED;
2471 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2473 p->rng_fault_state = True;
2474 return WERR_NOT_SUPPORTED;
2477 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2479 p->rng_fault_state = True;
2480 return WERR_NOT_SUPPORTED;
2483 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2485 p->rng_fault_state = True;
2486 return WERR_NOT_SUPPORTED;
2489 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2491 p->rng_fault_state = True;
2492 return WERR_NOT_SUPPORTED;
2495 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2497 p->rng_fault_state = True;
2498 return WERR_NOT_SUPPORTED;
2501 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2503 p->rng_fault_state = True;
2504 return WERR_NOT_SUPPORTED;
2507 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2509 p->rng_fault_state = True;
2510 return WERR_NOT_SUPPORTED;
2513 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2515 p->rng_fault_state = True;
2516 return WERR_NOT_SUPPORTED;
2519 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2521 p->rng_fault_state = True;
2522 return WERR_NOT_SUPPORTED;
2525 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2527 p->rng_fault_state = True;
2528 return WERR_NOT_SUPPORTED;
2531 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2533 p->rng_fault_state = True;
2534 return WERR_NOT_SUPPORTED;
2537 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2539 p->rng_fault_state = True;
2540 return WERR_NOT_SUPPORTED;
2543 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2545 p->rng_fault_state = True;
2546 return WERR_NOT_SUPPORTED;
2549 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2555 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2557 p->rng_fault_state = True;
2558 return WERR_NOT_SUPPORTED;
2561 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2563 p->rng_fault_state = True;
2564 return WERR_NOT_SUPPORTED;
2567 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2569 p->rng_fault_state = True;
2570 return WERR_NOT_SUPPORTED;
2573 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2575 p->rng_fault_state = True;
2576 return WERR_NOT_SUPPORTED;
2579 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2581 p->rng_fault_state = True;
2582 return WERR_NOT_SUPPORTED;
2585 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2587 p->rng_fault_state = True;
2588 return WERR_NOT_SUPPORTED;