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 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
28 #define MAX_SERVER_DISK_ENTRIES 15
30 extern const struct generic_mapping file_generic_mapping;
31 extern userdom_struct current_user_info;
34 #define DBGC_CLASS DBGC_RPC_SRV
36 /* Use for enumerating connections, pipes, & files */
38 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( struct db_record *rec, void *p)
57 struct pipe_open_rec prec;
58 struct file_enum_count *fenum = (struct file_enum_count *)p;
59 struct srvsvc_NetFileInfo3 *f;
64 if (rec->value.dsize != sizeof(struct pipe_open_rec))
67 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
69 if ( !process_exists(prec.pid) ) {
73 username = uidtoname(prec.uid);
75 if ((fenum->username != NULL)
76 && !strequal(username, fenum->username)) {
80 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
82 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info,
83 struct srvsvc_NetFileInfo3, i+1 );
85 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
91 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
92 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
93 fenum->info[i].num_locks = 0;
94 fenum->info[i].user = talloc_move(fenum->ctx, &username);
95 if (!(fenum->info[i].path = talloc_strdup(
96 fenum->ctx, fullpath))) {
97 /* There's not much we can do here. */
98 fenum->info[i].path = "";
106 /*******************************************************************
107 ********************************************************************/
109 static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username,
110 struct srvsvc_NetFileInfo3 **info,
111 uint32 *count, uint32 *resume )
113 struct file_enum_count fenum;
116 fenum.username = username;
118 fenum.count = *count;
120 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
121 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
127 *count = fenum.count;
132 /*******************************************************************
133 ********************************************************************/
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 =
140 (struct file_enum_count *)private_data;
142 struct srvsvc_NetFileInfo3 *f;
143 int i = fenum->count;
145 struct byte_range_lock *brl;
149 const char *username;
151 /* If the pid was not found delete the entry from connections.tdb */
153 if (!process_exists(e->pid)) {
157 username = uidtoname(e->uid);
159 if ((fenum->username != NULL)
160 && !strequal(username, fenum->username)) {
164 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info,
165 struct srvsvc_NetFileInfo3, i+1 );
167 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
172 /* need to count the number of locks on a file */
177 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
178 num_locks = brl->num_locks;
182 if ( strcmp( fname, "." ) == 0 ) {
183 pstr_sprintf( fullpath, "C:%s", sharepath );
185 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
187 string_replace( fullpath, '/', '\\' );
189 /* mask out create (what ever that is) */
190 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
192 fenum->info[i].fid = e->share_file_id;
193 fenum->info[i].permissions = permissions;
194 fenum->info[i].num_locks = num_locks;
195 fenum->info[i].user = talloc_move(fenum->ctx, &username);
196 if (!(fenum->info[i].path = talloc_strdup(
197 fenum->ctx, fullpath))) {
198 /* There's not much we can do here. */
199 fenum->info[i].path = "";
205 /*******************************************************************
206 ********************************************************************/
208 static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username,
209 struct srvsvc_NetFileInfo3 **info,
210 uint32 *count, uint32 *resume )
212 struct file_enum_count f_enum_cnt;
214 f_enum_cnt.ctx = ctx;
215 f_enum_cnt.username = username;
216 f_enum_cnt.count = *count;
217 f_enum_cnt.info = *info;
219 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
221 *info = f_enum_cnt.info;
222 *count = f_enum_cnt.count;
227 /*******************************************************************
228 Utility function to get the 'type' of a share from a share definition.
229 ********************************************************************/
230 static uint32 get_share_type(const struct share_params *params)
232 char *net_name = lp_servicename(params->service);
233 int len_net_name = strlen(net_name);
235 /* work out the share type */
236 uint32 type = STYPE_DISKTREE;
238 if (lp_print_ok(params->service))
240 if (strequal(lp_fstype(params->service), "IPC"))
242 if (net_name[len_net_name-1] == '$')
243 type |= STYPE_HIDDEN;
248 /*******************************************************************
249 Fill in a share info level 0 structure.
250 ********************************************************************/
252 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
253 const struct share_params *params)
255 sh0->name = lp_servicename(params->service);
258 /*******************************************************************
259 Fill in a share info level 1 structure.
260 ********************************************************************/
262 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
263 const struct share_params *params)
265 connection_struct *conn = p->conn;
267 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
268 conn->user, conn->connectpath, conn->gid,
269 get_current_username(),
270 current_user_info.domain,
271 lp_comment(params->service));
273 sh1->name = lp_servicename(params->service);
274 sh1->type = get_share_type(params);
277 /*******************************************************************
278 Fill in a share info level 2 structure.
279 ********************************************************************/
281 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
282 const struct share_params *params)
284 connection_struct *conn = p->conn;
287 int max_connections = lp_max_connections(params->service);
288 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
290 char *net_name = lp_servicename(params->service);
292 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
293 conn->user, conn->connectpath, conn->gid,
294 get_current_username(),
295 current_user_info.domain,
296 lp_comment(params->service));
297 path = talloc_asprintf(p->mem_ctx, "C:%s",
298 lp_pathname(params->service));
301 * Change / to \\ so that win2k will see it as a valid path. This was
302 * added to enable use of browsing in win2k add share dialog.
305 string_replace(path, '/', '\\');
307 count = count_current_connections( net_name, False );
308 sh2->name = net_name;
309 sh2->type = get_share_type(params);
310 sh2->comment = remark;
311 sh2->permissions = 0;
312 sh2->max_users = max_uses;
313 sh2->current_users = count;
318 /*******************************************************************
319 Map any generic bits to file specific bits.
320 ********************************************************************/
322 static void map_generic_share_sd_bits(SEC_DESC *psd)
325 SEC_ACL *ps_dacl = NULL;
334 for (i = 0; i < ps_dacl->num_aces; i++) {
335 SEC_ACE *psa = &ps_dacl->aces[i];
336 uint32 orig_mask = psa->access_mask;
338 se_map_generic(&psa->access_mask, &file_generic_mapping);
339 psa->access_mask |= orig_mask;
343 /*******************************************************************
344 Fill in a share info level 501 structure.
345 ********************************************************************/
347 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
348 const struct share_params *params)
350 connection_struct *conn = p->conn;
352 const char *net_name = lp_servicename(params->service);
354 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
355 conn->user, conn->connectpath, conn->gid,
356 get_current_username(),
357 current_user_info.domain,
358 lp_comment(params->service));
361 sh501->name = net_name;
362 sh501->type = get_share_type(params);
363 sh501->comment = remark;
364 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
367 /*******************************************************************
368 Fill in a share info level 502 structure.
369 ********************************************************************/
371 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
372 const struct share_params *params)
374 int max_connections = lp_max_connections(params->service);
375 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
376 connection_struct *conn = p->conn;
383 TALLOC_CTX *ctx = p->mem_ctx;
388 net_name = lp_servicename(params->service);
389 count = count_current_connections( net_name, False );
391 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
392 conn->user, conn->connectpath, conn->gid,
393 get_current_username(),
394 current_user_info.domain,
395 lp_comment(params->service));
397 path = talloc_asprintf(p->mem_ctx, "C:%s",
398 lp_pathname(params->service));
401 * Change / to \\ so that win2k will see it as a valid path. This was
402 * added to enable use of browsing in win2k add share dialog.
405 string_replace(path, '/', '\\');
407 sd = get_share_security(ctx, lp_servicename(params->service),
410 sh502->name = net_name;
411 sh502->type = get_share_type(params);
412 sh502->comment = remark;
414 sh502->password = "";
416 sh502->permissions = 0;
417 sh502->max_users = max_uses;
418 sh502->current_users = count;
422 /***************************************************************************
423 Fill in a share info level 1004 structure.
424 ***************************************************************************/
426 static void init_srv_share_info_1004(pipes_struct *p,
427 struct srvsvc_NetShareInfo1004* sh1004,
428 const struct share_params *params)
430 connection_struct *conn = p->conn;
433 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
434 conn->user, conn->connectpath, conn->gid,
435 get_current_username(),
436 current_user_info.domain,
437 lp_comment(params->service));
439 ZERO_STRUCTP(sh1004);
441 sh1004->comment = remark;
444 /***************************************************************************
445 Fill in a share info level 1005 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1005(pipes_struct *p,
449 struct srvsvc_NetShareInfo1005* sh1005,
450 const struct share_params *params)
452 sh1005->dfs_flags = 0;
454 if(lp_host_msdfs() && lp_msdfs_root(params->service))
456 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
458 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
460 /***************************************************************************
461 Fill in a share info level 1006 structure.
462 ***************************************************************************/
464 static void init_srv_share_info_1006(pipes_struct *p,
465 struct srvsvc_NetShareInfo1006* sh1006,
466 const struct share_params *params)
468 sh1006->max_users = -1;
471 /***************************************************************************
472 Fill in a share info level 1007 structure.
473 ***************************************************************************/
475 static void init_srv_share_info_1007(pipes_struct *p,
476 struct srvsvc_NetShareInfo1007* sh1007,
477 const struct share_params *params)
481 ZERO_STRUCTP(sh1007);
483 sh1007->flags = flags;
484 sh1007->alternate_directory_name = "";
487 /*******************************************************************
488 Fill in a share info level 1501 structure.
489 ********************************************************************/
491 static void init_srv_share_info_1501(pipes_struct *p,
492 struct sec_desc_buf *sh1501,
493 const struct share_params *params)
497 TALLOC_CTX *ctx = p->mem_ctx;
499 ZERO_STRUCTP(sh1501);
501 sd = get_share_security(ctx, lp_servicename(params->service),
507 /*******************************************************************
508 True if it ends in '$'.
509 ********************************************************************/
511 static BOOL is_hidden_share(const struct share_params *params)
513 const char *net_name = lp_servicename(params->service);
515 return (net_name[strlen(net_name) - 1] == '$');
518 /*******************************************************************
519 Fill in a share info structure.
520 ********************************************************************/
522 static WERROR init_srv_share_info_ctr(pipes_struct *p,
523 union srvsvc_NetShareCtr *ctr,
524 uint32 info_level, uint32 *resume_hnd,
525 uint32 *total_entries, BOOL all_shares)
527 TALLOC_CTX *ctx = p->mem_ctx;
528 struct share_iterator *shares;
529 struct share_params *share;
530 WERROR result = WERR_NOMEM;
532 DEBUG(5,("init_srv_share_info_ctr\n"));
540 /* Ensure all the usershares are loaded. */
542 load_usershare_shares();
543 load_registry_shares();
548 if (!(shares = share_list_all(ctx))) {
549 DEBUG(5, ("Could not list shares\n"));
550 return WERR_ACCESS_DENIED;
553 switch (info_level) {
555 if (!(ctr->ctr0 = TALLOC_ZERO_P(
556 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
561 if (!(ctr->ctr1 = TALLOC_ZERO_P(
562 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
567 if (!(ctr->ctr2 = TALLOC_ZERO_P(
568 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
573 if (!(ctr->ctr501 = TALLOC_ZERO_P(
574 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
579 if (!(ctr->ctr502 = TALLOC_ZERO_P(
580 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
585 if (!(ctr->ctr1004 = TALLOC_ZERO_P(
586 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
591 if (!(ctr->ctr1005 = TALLOC_ZERO_P(
592 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
597 if (!(ctr->ctr1006 = TALLOC_ZERO_P(
598 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
603 if (!(ctr->ctr1007 = TALLOC_ZERO_P(
604 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
609 if (!(ctr->ctr1501 = TALLOC_ZERO_P(
610 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
615 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
616 "value %d\n", info_level));
617 return WERR_UNKNOWN_LEVEL;
620 while ((share = next_share(shares)) != NULL) {
621 if (!lp_browseable(share->service)) {
624 if (!all_shares && is_hidden_share(share)) {
628 switch (info_level) {
631 struct srvsvc_NetShareInfo0 i;
632 init_srv_share_info_0(p, &i, share);
633 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
634 &ctr->ctr0->array, &ctr->ctr0->count);
635 if (ctr->ctr0->array == NULL) {
638 *total_entries = ctr->ctr0->count;
644 struct srvsvc_NetShareInfo1 i;
645 init_srv_share_info_1(p, &i, share);
646 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
647 &ctr->ctr1->array, &ctr->ctr1->count);
648 if (ctr->ctr1->array == NULL) {
651 *total_entries = ctr->ctr1->count;
657 struct srvsvc_NetShareInfo2 i;
658 init_srv_share_info_2(p, &i, share);
659 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
660 &ctr->ctr2->array, &ctr->ctr2->count);
661 if (ctr->ctr2->array == NULL) {
664 *total_entries = ctr->ctr2->count;
670 struct srvsvc_NetShareInfo501 i;
671 init_srv_share_info_501(p, &i, share);
672 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
673 &ctr->ctr501->array, &ctr->ctr501->count);
674 if (ctr->ctr501->array == NULL) {
677 *total_entries = ctr->ctr501->count;
683 struct srvsvc_NetShareInfo502 i;
684 init_srv_share_info_502(p, &i, share);
685 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
686 &ctr->ctr502->array, &ctr->ctr502->count);
687 if (ctr->ctr502->array == NULL) {
690 *total_entries = ctr->ctr502->count;
694 /* here for completeness but not currently used with enum
699 struct srvsvc_NetShareInfo1004 i;
700 init_srv_share_info_1004(p, &i, share);
701 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
702 &ctr->ctr1004->array, &ctr->ctr1004->count);
703 if (ctr->ctr1004->array == NULL) {
706 *total_entries = ctr->ctr1004->count;
712 struct srvsvc_NetShareInfo1005 i;
713 init_srv_share_info_1005(p, &i, share);
714 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
715 &ctr->ctr1005->array, &ctr->ctr1005->count);
716 if (ctr->ctr1005->array == NULL) {
719 *total_entries = ctr->ctr1005->count;
725 struct srvsvc_NetShareInfo1006 i;
726 init_srv_share_info_1006(p, &i, share);
727 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
728 &ctr->ctr1006->array, &ctr->ctr1006->count);
729 if (ctr->ctr1006->array == NULL) {
732 *total_entries = ctr->ctr1006->count;
738 struct srvsvc_NetShareInfo1007 i;
739 init_srv_share_info_1007(p, &i, share);
740 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
741 &ctr->ctr1007->array, &ctr->ctr1007->count);
742 if (ctr->ctr1007->array == NULL) {
745 *total_entries = ctr->ctr1007->count;
751 struct sec_desc_buf i;
752 init_srv_share_info_1501(p, &i, share);
753 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
754 &ctr->ctr1501->array, &ctr->ctr1501->count);
755 if (ctr->ctr1501->array == NULL) {
758 *total_entries = ctr->ctr1501->count;
772 /*******************************************************************
773 fill in a sess info level 0 structure.
774 ********************************************************************/
776 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
778 struct sessionid *session_list;
779 uint32 num_entries = 0;
780 (*stot) = list_sessions(p->mem_ctx, &session_list);
789 DEBUG(5,("init_srv_sess_0_ss0\n"));
791 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
794 for (; (*snum) < (*stot); (*snum)++) {
795 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
799 ss0->count = num_entries;
801 if ((*snum) >= (*stot)) {
811 /*******************************************************************
812 ********************************************************************/
814 static void sess_file_fn( const struct share_mode_entry *e,
815 const char *sharepath, const char *fname,
818 struct sess_file_count *sess = (struct sess_file_count *)private_data;
820 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
827 /*******************************************************************
828 ********************************************************************/
830 static int net_count_files( uid_t uid, struct server_id pid )
832 struct sess_file_count s_file_cnt;
834 s_file_cnt.count = 0;
835 s_file_cnt.uid = uid;
836 s_file_cnt.pid = pid;
838 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
840 return s_file_cnt.count;
843 /*******************************************************************
844 fill in a sess info level 1 structure.
845 ********************************************************************/
847 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
849 struct sessionid *session_list;
850 uint32 num_entries = 0;
851 time_t now = time(NULL);
868 (*stot) = list_sessions(p->mem_ctx, &session_list);
870 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
872 for (; (*snum) < (*stot); (*snum)++) {
875 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
879 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
880 session_list[*snum].username));
884 connect_time = (uint32)(now - session_list[*snum].connect_start);
885 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
886 guest = strequal( session_list[*snum].username, lp_guestaccount() );
888 if (!(ss1->array[num_entries].client = talloc_strdup(
889 ss1->array, session_list[*snum].remote_machine))) {
890 ss1->array[num_entries].client = "";
892 if (!(ss1->array[num_entries].user = talloc_strdup(
893 ss1->array, session_list[*snum].username))) {
894 ss1->array[num_entries].user = "";
896 ss1->array[num_entries].num_open = num_files;
897 ss1->array[num_entries].time = connect_time;
898 ss1->array[num_entries].idle_time = 0;
899 ss1->array[num_entries].user_flags = guest;
904 ss1->count = num_entries;
906 if ((*snum) >= (*stot)) {
911 /*******************************************************************
912 makes a SRV_R_NET_SESS_ENUM structure.
913 ********************************************************************/
915 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
916 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
918 WERROR status = WERR_OK;
919 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
921 switch (switch_value) {
923 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
924 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
927 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
928 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
931 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
932 if (resume_hnd != NULL)
934 (*total_entries) = 0;
936 status = WERR_UNKNOWN_LEVEL;
943 /*******************************************************************
944 fill in a conn info level 0 structure.
945 ********************************************************************/
947 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
949 uint32 num_entries = 0;
958 DEBUG(5,("init_srv_conn_0_ss0\n"));
961 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
962 for (; (*snum) < (*stot); (*snum)++) {
964 ss0->array[num_entries].conn_id = (*stot);
966 /* move on to creating next connection */
967 /* move on to creating next conn */
971 ss0->count = num_entries;
973 if ((*snum) >= (*stot)) {
985 /*******************************************************************
986 fill in a conn info level 1 structure.
987 ********************************************************************/
989 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
991 uint32 num_entries = 0;
1000 DEBUG(5,("init_srv_conn_1_ss1\n"));
1003 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
1004 for (; (*snum) < (*stot); (*snum)++) {
1005 ss1->array[num_entries].conn_id = (*stot);
1006 ss1->array[num_entries].conn_type = 0x3;
1007 ss1->array[num_entries].num_open = 1;
1008 ss1->array[num_entries].num_users = 1;
1009 ss1->array[num_entries].conn_time = 3;
1010 ss1->array[num_entries].user = "dummy_user";
1011 ss1->array[num_entries].share = "IPC$";
1013 /* move on to creating next connection */
1014 /* move on to creating next conn */
1018 ss1->count = num_entries;
1020 if ((*snum) >= (*stot)) {
1032 /*******************************************************************
1033 makes a SRV_R_NET_CONN_ENUM structure.
1034 ********************************************************************/
1036 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1037 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1039 WERROR status = WERR_OK;
1040 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1042 switch (switch_value) {
1044 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1047 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1050 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1053 (*total_entries) = 0;
1054 status = WERR_UNKNOWN_LEVEL;
1061 /*******************************************************************
1062 makes a SRV_R_NET_FILE_ENUM structure.
1063 ********************************************************************/
1065 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr,
1066 uint32 *resume_hnd, const char *username,
1067 uint32 *num_entries )
1071 /* TODO -- Windows enumerates
1073 (c) open directories and files */
1075 ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3);
1077 status = net_enum_files(p->mem_ctx, username, &ctr->ctr3->array,
1078 num_entries, resume_hnd );
1079 if ( !W_ERROR_IS_OK(status))
1082 status = net_enum_pipes(p->mem_ctx, username, &ctr->ctr3->array,
1083 num_entries, resume_hnd );
1084 if ( !W_ERROR_IS_OK(status))
1087 ctr->ctr3->count = *num_entries;
1092 /*******************************************************************
1093 *******************************************************************/
1095 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1097 switch ( *r->in.level ) {
1099 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle,
1100 r->in.user, r->out.totalentries );
1102 return WERR_UNKNOWN_LEVEL;
1108 /*******************************************************************
1110 ********************************************************************/
1112 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1114 WERROR status = WERR_OK;
1116 ZERO_STRUCTP(r->out.info);
1118 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1120 if (!pipe_access_check(p)) {
1121 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1122 return WERR_ACCESS_DENIED;
1125 switch (r->in.level) {
1127 /* Technically level 102 should only be available to
1128 Administrators but there isn't anything super-secret
1129 here, as most of it is made up. */
1132 r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1134 r->out.info->info102->platform_id = 500;
1135 r->out.info->info102->version_major = lp_major_announce_version();
1136 r->out.info->info102->version_minor = lp_minor_announce_version();
1137 r->out.info->info102->server_name = global_myname();
1138 r->out.info->info102->server_type = lp_default_server_announce();
1139 r->out.info->info102->userpath = "C:\\";
1140 r->out.info->info102->licenses = 10000;
1141 r->out.info->info102->anndelta = 3000;
1142 r->out.info->info102->disc = 0xf;
1143 r->out.info->info102->users = 0xffffffff;
1144 r->out.info->info102->hidden = 0;
1145 r->out.info->info102->announce = 240;
1146 r->out.info->info102->comment = lp_serverstring();
1149 r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1150 r->out.info->info101->platform_id = 500;
1151 r->out.info->info101->server_name = global_myname();
1152 r->out.info->info101->version_major = lp_major_announce_version();
1153 r->out.info->info101->version_minor = lp_minor_announce_version();
1154 r->out.info->info101->server_type = lp_default_server_announce();
1155 r->out.info->info101->comment = lp_serverstring();
1158 r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1159 r->out.info->info100->platform_id = 500;
1160 r->out.info->info100->server_name = global_myname();
1163 return WERR_UNKNOWN_LEVEL;
1167 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1172 /*******************************************************************
1174 ********************************************************************/
1176 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1178 /* Set up the net server set info structure. */
1179 if (r->out.parm_error) {
1180 *r->out.parm_error = 0;
1185 /*******************************************************************
1187 ********************************************************************/
1189 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1191 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1193 ZERO_STRUCTP(r->out.ctr);
1196 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1199 /*******************************************************************
1201 ********************************************************************/
1203 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1205 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1207 ZERO_STRUCTP(r->out.ctr);
1210 return init_srv_sess_info_ctr(p, r->out.ctr,
1212 r->in.resume_handle,
1213 r->out.totalentries);
1216 /*******************************************************************
1218 ********************************************************************/
1220 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1222 struct sessionid *session_list;
1223 int num_sessions, snum;
1226 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1228 /* strip leading backslashes if any */
1229 while (machine[0] == '\\') {
1230 memmove(machine, &machine[1], strlen(machine));
1233 num_sessions = list_sessions(p->mem_ctx, &session_list);
1235 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1237 status = WERR_ACCESS_DENIED;
1239 /* fail out now if you are not root or not a domain admin */
1241 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1242 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1247 for (snum = 0; snum < num_sessions; snum++) {
1249 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1250 strequal(session_list[snum].remote_machine, machine)) {
1253 ntstat = messaging_send(smbd_messaging_context(),
1254 session_list[snum].pid,
1255 MSG_SHUTDOWN, &data_blob_null);
1257 if (NT_STATUS_IS_OK(ntstat))
1262 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1268 /*******************************************************************
1270 ********************************************************************/
1272 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1274 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1276 if (!pipe_access_check(p)) {
1277 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1278 return WERR_ACCESS_DENIED;
1281 /* Create the list of shares for the response. */
1282 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1283 r->in.resume_handle, r->out.totalentries, True);
1286 /*******************************************************************
1288 ********************************************************************/
1290 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
1292 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1294 if (!pipe_access_check(p)) {
1295 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1296 return WERR_ACCESS_DENIED;
1299 /* Create the list of shares for the response. */
1300 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1301 r->in.resume_handle, r->out.totalentries, False);
1304 /*******************************************************************
1306 ********************************************************************/
1308 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1310 const struct share_params *params;
1312 params = get_share_params(p->mem_ctx, r->in.share_name);
1314 if (params != NULL) {
1315 switch (r->in.level) {
1317 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1318 init_srv_share_info_0(p, r->out.info->info0, params);
1321 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1322 init_srv_share_info_1(p, r->out.info->info1, params);
1325 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1326 init_srv_share_info_2(p, r->out.info->info2, params);
1329 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1330 init_srv_share_info_501(p, r->out.info->info501, params);
1333 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1334 init_srv_share_info_502(p, r->out.info->info502, params);
1337 /* here for completeness */
1339 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1340 init_srv_share_info_1004(p, r->out.info->info1004, params);
1343 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1344 init_srv_share_info_1005(p, r->out.info->info1005, params);
1347 /* here for completeness 1006 - 1501 */
1349 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1350 init_srv_share_info_1006(p, r->out.info->info1006,
1354 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1355 init_srv_share_info_1007(p, r->out.info->info1007,
1359 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1360 init_srv_share_info_1501(p, r->out.info->info1501,
1364 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1365 "switch value %d\n", r->in.level));
1366 return WERR_UNKNOWN_LEVEL;
1370 return WERR_INVALID_NAME;
1376 /*******************************************************************
1377 Check a given DOS pathname is valid for a share.
1378 ********************************************************************/
1380 char *valid_share_pathname(char *dos_pathname)
1384 /* Convert any '\' paths to '/' */
1385 unix_format(dos_pathname);
1386 unix_clean_name(dos_pathname);
1388 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1390 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1393 /* Only absolute paths allowed. */
1400 static void setval_helper(struct registry_key *key, const char *name,
1401 const char *value, WERROR *err)
1403 struct registry_value val;
1405 if (!W_ERROR_IS_OK(*err)) {
1411 val.v.sz.str = CONST_DISCARD(char *, value);
1412 val.v.sz.len = strlen(value)+1;
1414 *err = reg_setvalue(key, name, &val);
1417 static WERROR add_share(const char *share_name, const char *path,
1418 const char *comment, uint32 max_connections,
1419 const struct nt_user_token *token,
1422 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1426 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1427 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1428 path, comment, max_connections) == -1) {
1432 DEBUG(10,("add_share: Running [%s]\n", command ));
1434 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1439 if ( (ret = smbrun(command, NULL)) == 0 ) {
1440 /* Tell everyone we updated smb.conf. */
1441 message_send_all(smbd_messaging_context(),
1442 MSG_SMB_CONF_UPDATED,
1449 /********* END SeDiskOperatorPrivilege BLOCK *********/
1451 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1455 * No fallback to registry shares, the user did define a add
1456 * share command, so fail here.
1460 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1463 if (lp_registry_shares()) {
1465 struct registry_key *key;
1466 enum winreg_CreateAction action;
1468 TALLOC_CTX *mem_ctx;
1470 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1475 mem_ctx = (TALLOC_CTX *)keyname;
1477 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1478 is_disk_op ? get_root_nt_token():token,
1481 if (action != REG_CREATED_NEW_KEY) {
1482 err = WERR_ALREADY_EXISTS;
1485 if (!W_ERROR_IS_OK(err)) {
1486 TALLOC_FREE(mem_ctx);
1490 setval_helper(key, "path", path, &err);
1491 if ((comment != NULL) && (comment[0] != '\0')) {
1492 setval_helper(key, "comment", comment, &err);
1494 if (max_connections != 0) {
1496 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1497 setval_helper(key, "max connections", tmp, &err);
1500 if (!W_ERROR_IS_OK(err)) {
1502 * Hmmmm. We'd need transactions on the registry to
1503 * get this right....
1505 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1508 TALLOC_FREE(mem_ctx);
1512 return WERR_ACCESS_DENIED;
1515 static WERROR delete_share(const char *sharename,
1516 const struct nt_user_token *token,
1519 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1523 if (asprintf(&command, "%s \"%s\" \"%s\"",
1524 lp_delete_share_cmd(), dyn_CONFIGFILE,
1529 DEBUG(10,("delete_share: Running [%s]\n", command ));
1531 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1536 if ( (ret = smbrun(command, NULL)) == 0 ) {
1537 /* Tell everyone we updated smb.conf. */
1538 message_send_all(smbd_messaging_context(),
1539 MSG_SMB_CONF_UPDATED,
1546 /********* END SeDiskOperatorPrivilege BLOCK *********/
1550 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1552 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1555 if (lp_registry_shares()) {
1559 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1564 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1570 return WERR_ACCESS_DENIED;
1573 static WERROR change_share(const char *share_name, const char *path,
1574 const char *comment, uint32 max_connections,
1575 const struct nt_user_token *token,
1578 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1582 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1583 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1584 path, comment, max_connections) == -1) {
1588 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1590 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1595 if ( (ret = smbrun(command, NULL)) == 0 ) {
1596 /* Tell everyone we updated smb.conf. */
1597 message_send_all(smbd_messaging_context(),
1598 MSG_SMB_CONF_UPDATED,
1605 /********* END SeDiskOperatorPrivilege BLOCK *********/
1607 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1608 "(%d)\n", command, ret ));
1612 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1615 if (lp_registry_shares()) {
1617 struct registry_key *key;
1619 TALLOC_CTX *mem_ctx;
1621 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1626 mem_ctx = (TALLOC_CTX *)keyname;
1628 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1629 is_disk_op ? get_root_nt_token():token,
1631 if (!W_ERROR_IS_OK(err)) {
1632 TALLOC_FREE(mem_ctx);
1636 setval_helper(key, "path", path, &err);
1638 reg_deletevalue(key, "comment");
1639 if ((comment != NULL) && (comment[0] != '\0')) {
1640 setval_helper(key, "comment", comment, &err);
1643 reg_deletevalue(key, "max connections");
1644 if (max_connections != 0) {
1646 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1647 setval_helper(key, "max connections", tmp, &err);
1650 TALLOC_FREE(mem_ctx);
1654 return WERR_ACCESS_DENIED;
1657 /*******************************************************************
1658 Net share set info. Modify share details.
1659 ********************************************************************/
1661 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1668 SEC_DESC *psd = NULL;
1669 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1670 BOOL is_disk_op = False;
1671 int max_connections = 0;
1672 fstring tmp_share_name;
1674 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1676 if (r->out.parm_error) {
1677 *r->out.parm_error = 0;
1680 if ( strequal(r->in.share_name,"IPC$")
1681 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1682 || strequal(r->in.share_name,"global") )
1684 return WERR_ACCESS_DENIED;
1687 fstrcpy(tmp_share_name, r->in.share_name);
1688 snum = find_service(tmp_share_name);
1690 /* Does this share exist ? */
1692 return WERR_NET_NAME_NOT_FOUND;
1694 /* No change to printer shares. */
1695 if (lp_print_ok(snum))
1696 return WERR_ACCESS_DENIED;
1698 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1701 /* fail out now if you are not root and not a disk op */
1703 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1704 return WERR_ACCESS_DENIED;
1706 switch (r->in.level) {
1708 pstrcpy(pathname, lp_pathname(snum));
1709 pstrcpy(comment, r->in.info.info1->comment);
1710 type = r->in.info.info1->type;
1714 pstrcpy(comment, r->in.info.info2->comment);
1715 pstrcpy(pathname, r->in.info.info2->path);
1716 type = r->in.info.info2->type;
1717 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1718 0 : r->in.info.info2->max_users;
1722 pstrcpy(comment, r->in.info.info502->comment);
1723 pstrcpy(pathname, r->in.info.info502->path);
1724 type = r->in.info.info502->type;
1725 psd = r->in.info.info502->sd;
1726 map_generic_share_sd_bits(psd);
1729 pstrcpy(pathname, lp_pathname(snum));
1730 pstrcpy(comment, r->in.info.info1004->comment);
1731 type = STYPE_DISKTREE;
1734 /* XP re-sets the csc policy even if it wasn't changed by the
1735 user, so we must compare it to see if it's what is set in
1736 smb.conf, so that we can contine other ops like setting
1738 if (((r->in.info.info1005->dfs_flags &
1739 SHARE_1005_CSC_POLICY_MASK) >>
1740 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1743 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1744 "to change csc policy from the network; "
1745 "must be done with smb.conf\n"));
1746 return WERR_ACCESS_DENIED;
1750 return WERR_ACCESS_DENIED;
1752 pstrcpy(pathname, lp_pathname(snum));
1753 pstrcpy(comment, lp_comment(snum));
1754 psd = r->in.info.info1501->sd;
1755 map_generic_share_sd_bits(psd);
1756 type = STYPE_DISKTREE;
1759 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1760 "%d\n", r->in.level));
1761 return WERR_UNKNOWN_LEVEL;
1764 /* We can only modify disk shares. */
1765 if (type != STYPE_DISKTREE)
1766 return WERR_ACCESS_DENIED;
1768 /* Check if the pathname is valid. */
1769 if (!(path = valid_share_pathname( pathname )))
1770 return WERR_OBJECT_PATH_INVALID;
1772 /* Ensure share name, pathname and comment don't contain '"'
1774 string_replace(tmp_share_name, '"', ' ');
1775 string_replace(path, '"', ' ');
1776 string_replace(comment, '"', ' ');
1778 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1779 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1781 /* Only call modify function if something changed. */
1783 if (strcmp(path, lp_pathname(snum))
1784 || strcmp(comment, lp_comment(snum))
1785 || (lp_max_connections(snum) != max_connections) ) {
1788 err = change_share(tmp_share_name, path, comment,
1789 max_connections, p->pipe_user.nt_user_token,
1792 if (!W_ERROR_IS_OK(err)) {
1797 /* Replace SD if changed. */
1802 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1805 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1806 if (!set_share_security(r->in.share_name, psd)) {
1807 DEBUG(0,("_srv_net_share_set_info: Failed to "
1808 "change security info in share %s.\n",
1809 r->in.share_name ));
1814 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1820 /*******************************************************************
1821 Net share add. Call 'add_share_command "sharename" "pathname"
1822 "comment" "max connections = "
1823 ********************************************************************/
1825 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1832 SEC_DESC *psd = NULL;
1833 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1835 uint32 max_connections = 0;
1838 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1840 if (r->out.parm_error) {
1841 *r->out.parm_error = 0;
1844 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1847 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1848 return WERR_ACCESS_DENIED;
1850 switch (r->in.level) {
1852 /* No path. Not enough info in a level 0 to do anything. */
1853 return WERR_ACCESS_DENIED;
1855 /* Not enough info in a level 1 to do anything. */
1856 return WERR_ACCESS_DENIED;
1858 pstrcpy(share_name, r->in.info.info2->name);
1859 pstrcpy(comment, r->in.info.info2->comment);
1860 pstrcpy(pathname, r->in.info.info2->path);
1861 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1862 0 : r->in.info.info2->max_users;
1863 type = r->in.info.info2->type;
1866 /* No path. Not enough info in a level 501 to do anything. */
1867 return WERR_ACCESS_DENIED;
1869 pstrcpy(share_name, r->in.info.info502->name);
1870 pstrcpy(comment, r->in.info.info502->comment);
1871 pstrcpy(pathname, r->in.info.info502->path);
1872 type = r->in.info.info502->type;
1873 psd = r->in.info.info502->sd;
1874 map_generic_share_sd_bits(psd);
1877 /* none of the following contain share names. NetShareAdd
1878 * does not have a separate parameter for the share name */
1884 return WERR_ACCESS_DENIED;
1886 /* DFS only level. */
1887 return WERR_ACCESS_DENIED;
1889 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1891 return WERR_UNKNOWN_LEVEL;
1894 /* check for invalid share names */
1896 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1897 sizeof(share_name) ) ) {
1898 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1900 return WERR_INVALID_NAME;
1903 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1904 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1906 return WERR_ACCESS_DENIED;
1909 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1910 /* Share already exists. */
1911 return WERR_ALREADY_EXISTS;
1914 /* We can only add disk shares. */
1915 if (type != STYPE_DISKTREE)
1916 return WERR_ACCESS_DENIED;
1918 /* Check if the pathname is valid. */
1919 if (!(path = valid_share_pathname( pathname )))
1920 return WERR_OBJECT_PATH_INVALID;
1922 /* Ensure share name, pathname and comment don't contain '"'
1925 string_replace(share_name, '"', ' ');
1926 string_replace(path, '"', ' ');
1927 string_replace(comment, '"', ' ');
1929 err = add_share(share_name, path, comment, max_connections,
1930 p->pipe_user.nt_user_token, is_disk_op);
1932 if (!W_ERROR_IS_OK(err)) {
1937 if (!set_share_security(share_name, psd)) {
1938 DEBUG(0,("_srv_net_share_add: Failed to add security "
1939 "info to share %s.\n", share_name ));
1944 * We don't call reload_services() here, the message will
1945 * cause this to be done before the next packet is read
1946 * from the client. JRA.
1949 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1954 /*******************************************************************
1955 Net share delete. Call "delete share command" with the share name as
1957 ********************************************************************/
1959 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1961 struct share_params *params;
1962 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1966 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1968 if ( strequal(r->in.share_name, "IPC$")
1969 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1970 || strequal(r->in.share_name, "global") )
1972 return WERR_ACCESS_DENIED;
1975 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1976 return WERR_NO_SUCH_SHARE;
1979 /* No change to printer shares. */
1980 if (lp_print_ok(params->service))
1981 return WERR_ACCESS_DENIED;
1983 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1986 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1987 return WERR_ACCESS_DENIED;
1989 err = delete_share(lp_servicename(params->service),
1990 p->pipe_user.nt_user_token, is_disk_op);
1992 if (!W_ERROR_IS_OK(err)) {
1996 /* Delete the SD in the database. */
1997 delete_share_security(params);
1999 lp_killservice(params->service);
2004 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
2006 struct srvsvc_NetShareDel s;
2008 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
2010 s.in.server_unc = r->in.server_unc;
2011 s.in.share_name = r->in.share_name;
2012 s.in.reserved = r->in.reserved;
2014 return _srvsvc_NetShareDel(p, &s);
2017 /*******************************************************************
2019 ********************************************************************/
2021 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
2024 time_t unixdate = time(NULL);
2025 WERROR status = WERR_OK;
2027 /* We do this call first as if we do it *after* the gmtime call
2028 it overwrites the pointed-to values. JRA */
2030 uint32 zone = get_time_zone(unixdate)/60;
2032 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2034 t = gmtime(&unixdate);
2037 r->out.info->elapsed = unixdate;
2038 r->out.info->msecs = 0;
2039 r->out.info->hours = t->tm_hour;
2040 r->out.info->mins = t->tm_min;
2041 r->out.info->secs = t->tm_sec;
2042 r->out.info->hunds = 0;
2043 r->out.info->timezone = zone;
2044 r->out.info->tinterval = 10000;
2045 r->out.info->day = t->tm_mday;
2046 r->out.info->month = t->tm_mon + 1;
2047 r->out.info->year = 1900+t->tm_year;
2048 r->out.info->weekday = t->tm_wday;
2050 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2055 /***********************************************************************************
2056 Win9x NT tools get security descriptor.
2057 ***********************************************************************************/
2059 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2061 SEC_DESC *psd = NULL;
2064 files_struct *fsp = NULL;
2067 connection_struct *conn = NULL;
2068 BOOL became_user = False;
2069 WERROR status = WERR_OK;
2070 char *tmp_file = NULL;
2071 TALLOC_CTX *ctx = talloc_tos();
2076 /* Null password is ok - we are already an authenticated user... */
2077 null_pw = data_blob_null;
2080 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2084 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2085 status = ntstatus_to_werror(nt_status);
2089 if (!become_user(conn, conn->vuid)) {
2090 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2091 status = WERR_ACCESS_DENIED;
2097 status = WERR_INVALID_PARAM;
2100 nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st);
2101 if (!NT_STATUS_IS_OK(nt_status)) {
2102 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2103 status = WERR_ACCESS_DENIED;
2107 nt_status = check_name(conn, tmp_file);
2108 if (!NT_STATUS_IS_OK(nt_status)) {
2109 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", tmp_file));
2110 status = WERR_ACCESS_DENIED;
2114 nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
2115 if (!NT_STATUS_IS_OK(nt_status)) {
2116 /* Perhaps it is a directory */
2117 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2118 nt_status = open_directory(conn, NULL, tmp_file, &st,
2119 READ_CONTROL_ACCESS,
2120 FILE_SHARE_READ|FILE_SHARE_WRITE,
2123 FILE_ATTRIBUTE_DIRECTORY,
2126 if (!NT_STATUS_IS_OK(nt_status)) {
2127 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", tmp_file));
2128 status = WERR_ACCESS_DENIED;
2133 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2136 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", tmp_file));
2137 status = WERR_ACCESS_DENIED;
2141 r->out.sd_buf->sd_size= sd_size;
2142 r->out.sd_buf->sd = psd;
2144 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2146 close_file(fsp, NORMAL_CLOSE);
2148 close_cnum(conn, p->pipe_user.vuid);
2154 close_file(fsp, NORMAL_CLOSE);
2161 close_cnum(conn, p->pipe_user.vuid);
2166 /***********************************************************************************
2167 Win9x NT tools set security descriptor.
2168 ***********************************************************************************/
2170 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2173 files_struct *fsp = NULL;
2176 connection_struct *conn = NULL;
2177 BOOL became_user = False;
2178 WERROR status = WERR_OK;
2179 char *tmp_file = NULL;
2180 TALLOC_CTX *ctx = talloc_tos();
2184 /* Null password is ok - we are already an authenticated user... */
2185 null_pw = data_blob_null;
2188 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2192 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2193 status = ntstatus_to_werror(nt_status);
2197 if (!become_user(conn, conn->vuid)) {
2198 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2199 status = WERR_ACCESS_DENIED;
2205 status = WERR_INVALID_PARAM;
2208 nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st);
2209 if (!NT_STATUS_IS_OK(nt_status)) {
2210 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2211 status = WERR_ACCESS_DENIED;
2215 nt_status = check_name(conn, tmp_file);
2216 if (!NT_STATUS_IS_OK(nt_status)) {
2217 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", tmp_file));
2218 status = WERR_ACCESS_DENIED;
2223 nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
2225 if (!NT_STATUS_IS_OK(nt_status)) {
2226 /* Perhaps it is a directory */
2227 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2228 nt_status = open_directory(conn, NULL, tmp_file, &st,
2229 FILE_READ_ATTRIBUTES,
2230 FILE_SHARE_READ|FILE_SHARE_WRITE,
2233 FILE_ATTRIBUTE_DIRECTORY,
2236 if (!NT_STATUS_IS_OK(nt_status)) {
2237 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", tmp_file));
2238 status = WERR_ACCESS_DENIED;
2243 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2245 if (!NT_STATUS_IS_OK(nt_status)) {
2246 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", tmp_file));
2247 status = WERR_ACCESS_DENIED;
2251 close_file(fsp, NORMAL_CLOSE);
2253 close_cnum(conn, p->pipe_user.vuid);
2259 close_file(fsp, NORMAL_CLOSE);
2267 close_cnum(conn, p->pipe_user.vuid);
2273 /***********************************************************************************
2274 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2275 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2276 These disks would the disks listed by this function.
2277 Users could then create shares relative to these disks. Watch out for moving these disks around.
2278 "Nigel Williams" <nigel@veritas.com>.
2279 ***********************************************************************************/
2281 static const char *server_disks[] = {"C:"};
2283 static uint32 get_server_disk_count(void)
2285 return sizeof(server_disks)/sizeof(server_disks[0]);
2288 static uint32 init_server_disk_enum(uint32 *resume)
2290 uint32 server_disk_count = get_server_disk_count();
2292 /*resume can be an offset into the list for now*/
2294 if(*resume & 0x80000000)
2297 if(*resume > server_disk_count)
2298 *resume = server_disk_count;
2300 return server_disk_count - *resume;
2303 static const char *next_server_disk_enum(uint32 *resume)
2307 if(init_server_disk_enum(resume) == 0)
2310 disk = server_disks[*resume];
2314 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2319 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2322 const char *disk_name;
2324 WERROR status = WERR_OK;
2326 *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2327 r->out.info->count = 0;
2329 if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2333 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2335 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2337 r->out.info->count++;
2338 (*r->out.totalentries)++;
2340 /*copy disk name into a unicode string*/
2342 r->out.info->disks[i].disk = disk_name;
2345 /* add a terminating null string. Is this there if there is more data to come? */
2347 r->out.info->count++;
2348 (*r->out.totalentries)++;
2350 r->out.info->disks[i].disk = "";
2355 /********************************************************************
2356 ********************************************************************/
2358 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2362 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2363 return WERR_INVALID_PARAM;
2366 switch ( r->in.name_type ) {
2368 len = strlen_m(r->in.name);
2370 if ((r->in.flags == 0x0) && (len > 81)) {
2371 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2372 return WERR_INVALID_NAME;
2374 if ((r->in.flags == 0x80000000) && (len > 13)) {
2375 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2376 return WERR_INVALID_NAME;
2379 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2380 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2381 return WERR_INVALID_NAME;
2386 return WERR_UNKNOWN_LEVEL;
2393 /********************************************************************
2394 ********************************************************************/
2396 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2398 return WERR_ACCESS_DENIED;
2401 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2403 p->rng_fault_state = True;
2404 return WERR_NOT_SUPPORTED;
2407 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2409 p->rng_fault_state = True;
2410 return WERR_NOT_SUPPORTED;
2413 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2415 p->rng_fault_state = True;
2416 return WERR_NOT_SUPPORTED;
2419 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2421 p->rng_fault_state = True;
2422 return WERR_NOT_SUPPORTED;
2425 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2427 p->rng_fault_state = True;
2428 return WERR_NOT_SUPPORTED;
2431 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2433 p->rng_fault_state = True;
2434 return WERR_NOT_SUPPORTED;
2437 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2439 p->rng_fault_state = True;
2440 return WERR_NOT_SUPPORTED;
2443 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2445 p->rng_fault_state = True;
2446 return WERR_NOT_SUPPORTED;
2449 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2451 p->rng_fault_state = True;
2452 return WERR_NOT_SUPPORTED;
2455 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2457 p->rng_fault_state = True;
2458 return WERR_NOT_SUPPORTED;
2461 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2463 p->rng_fault_state = True;
2464 return WERR_NOT_SUPPORTED;
2467 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2469 p->rng_fault_state = True;
2470 return WERR_NOT_SUPPORTED;
2473 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2475 p->rng_fault_state = True;
2476 return WERR_NOT_SUPPORTED;
2479 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2481 p->rng_fault_state = True;
2482 return WERR_NOT_SUPPORTED;
2485 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2487 p->rng_fault_state = True;
2488 return WERR_NOT_SUPPORTED;
2491 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2493 p->rng_fault_state = True;
2494 return WERR_NOT_SUPPORTED;
2497 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2499 p->rng_fault_state = True;
2500 return WERR_NOT_SUPPORTED;
2503 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2505 p->rng_fault_state = True;
2506 return WERR_NOT_SUPPORTED;
2509 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2511 p->rng_fault_state = True;
2512 return WERR_NOT_SUPPORTED;
2515 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2517 p->rng_fault_state = True;
2518 return WERR_NOT_SUPPORTED;
2521 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2523 p->rng_fault_state = True;
2524 return WERR_NOT_SUPPORTED;
2527 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2529 p->rng_fault_state = True;
2530 return WERR_NOT_SUPPORTED;
2533 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2535 p->rng_fault_state = True;
2536 return WERR_NOT_SUPPORTED;
2539 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2541 p->rng_fault_state = True;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2547 p->rng_fault_state = True;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2553 p->rng_fault_state = True;
2554 return WERR_NOT_SUPPORTED;
2557 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2559 p->rng_fault_state = True;
2560 return WERR_NOT_SUPPORTED;
2563 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;
2569 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2571 p->rng_fault_state = True;
2572 return WERR_NOT_SUPPORTED;
2575 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2577 p->rng_fault_state = True;
2578 return WERR_NOT_SUPPORTED;
2581 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2583 p->rng_fault_state = True;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2589 p->rng_fault_state = True;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2595 p->rng_fault_state = True;
2596 return WERR_NOT_SUPPORTED;
2599 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2601 p->rng_fault_state = True;
2602 return WERR_NOT_SUPPORTED;
2605 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2607 p->rng_fault_state = True;
2608 return WERR_NOT_SUPPORTED;