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 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 {
41 struct srvsvc_NetFileInfo3 *info;
44 struct sess_file_count {
50 /****************************************************************************
51 Count the entries belonging to a service in the connection db.
52 ****************************************************************************/
54 static int pipe_enum_fn( struct db_record *rec, void *p)
56 struct pipe_open_rec prec;
57 struct file_enum_count *fenum = (struct file_enum_count *)p;
59 if (rec->value.dsize != sizeof(struct pipe_open_rec))
62 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
64 if ( process_exists(prec.pid) ) {
65 struct srvsvc_NetFileInfo3 *f;
69 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
71 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
73 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
79 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
80 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
81 fenum->info[i].num_locks = 0;
82 if (!(fenum->info[i].user = talloc_strdup(
83 fenum->ctx, uidtoname(prec.uid)))) {
84 /* There's not much we can do here. */
85 fenum->info[i].user = "";
87 if (!(fenum->info[i].path = talloc_strdup(
88 fenum->ctx, fullpath))) {
89 /* There's not much we can do here. */
90 fenum->info[i].path = "";
99 /*******************************************************************
100 ********************************************************************/
102 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
103 uint32 *count, uint32 *resume )
105 struct file_enum_count fenum;
109 fenum.count = *count;
111 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
112 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
118 *count = fenum.count;
123 /*******************************************************************
124 ********************************************************************/
126 static void enum_file_fn( const struct share_mode_entry *e,
127 const char *sharepath, const char *fname,
130 struct file_enum_count *fenum =
131 (struct file_enum_count *)private_data;
133 /* If the pid was not found delete the entry from connections.tdb */
135 if ( process_exists(e->pid) ) {
136 struct srvsvc_NetFileInfo3 *f;
137 int i = fenum->count;
139 struct byte_range_lock *brl;
144 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
146 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
151 /* need to count the number of locks on a file */
156 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
157 num_locks = brl->num_locks;
161 if ( strcmp( fname, "." ) == 0 ) {
162 pstr_sprintf( fullpath, "C:%s", sharepath );
164 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
166 string_replace( fullpath, '/', '\\' );
168 /* mask out create (what ever that is) */
169 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
171 fenum->info[i].fid = e->share_file_id;
172 fenum->info[i].permissions = permissions;
173 fenum->info[i].num_locks = num_locks;
174 if (!(fenum->info[i].user = talloc_strdup(
175 fenum->ctx, uidtoname(e->uid)))) {
176 /* There's not much we can do here. */
177 fenum->info[i].user = "";
179 if (!(fenum->info[i].path = talloc_strdup(
180 fenum->ctx, fullpath))) {
181 /* There's not much we can do here. */
182 fenum->info[i].path = "";
192 /*******************************************************************
193 ********************************************************************/
195 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
196 uint32 *count, uint32 *resume )
198 struct file_enum_count f_enum_cnt;
200 f_enum_cnt.ctx = ctx;
201 f_enum_cnt.count = *count;
202 f_enum_cnt.info = *info;
204 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
206 *info = f_enum_cnt.info;
207 *count = f_enum_cnt.count;
212 /*******************************************************************
213 Utility function to get the 'type' of a share from a share definition.
214 ********************************************************************/
215 static uint32 get_share_type(const struct share_params *params)
217 char *net_name = lp_servicename(params->service);
218 int len_net_name = strlen(net_name);
220 /* work out the share type */
221 uint32 type = STYPE_DISKTREE;
223 if (lp_print_ok(params->service))
225 if (strequal(lp_fstype(params->service), "IPC"))
227 if (net_name[len_net_name-1] == '$')
228 type |= STYPE_HIDDEN;
233 /*******************************************************************
234 Fill in a share info level 0 structure.
235 ********************************************************************/
237 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
238 const struct share_params *params)
240 sh0->name = lp_servicename(params->service);
243 /*******************************************************************
244 Fill in a share info level 1 structure.
245 ********************************************************************/
247 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
248 const struct share_params *params)
250 connection_struct *conn = p->conn;
252 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
253 conn->user, conn->connectpath, conn->gid,
254 get_current_username(),
255 current_user_info.domain,
256 lp_comment(params->service));
258 sh1->name = lp_servicename(params->service);
259 sh1->type = get_share_type(params);
262 /*******************************************************************
263 Fill in a share info level 2 structure.
264 ********************************************************************/
266 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
267 const struct share_params *params)
269 connection_struct *conn = p->conn;
272 int max_connections = lp_max_connections(params->service);
273 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
275 char *net_name = lp_servicename(params->service);
277 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
278 conn->user, conn->connectpath, conn->gid,
279 get_current_username(),
280 current_user_info.domain,
281 lp_comment(params->service));
282 path = talloc_asprintf(p->mem_ctx, "C:%s",
283 lp_pathname(params->service));
286 * Change / to \\ so that win2k will see it as a valid path. This was
287 * added to enable use of browsing in win2k add share dialog.
290 string_replace(path, '/', '\\');
292 count = count_current_connections( net_name, False );
293 sh2->name = net_name;
294 sh2->type = get_share_type(params);
295 sh2->comment = remark;
296 sh2->permissions = 0;
297 sh2->max_users = max_uses;
298 sh2->current_users = count;
303 /*******************************************************************
304 Map any generic bits to file specific bits.
305 ********************************************************************/
307 static void map_generic_share_sd_bits(SEC_DESC *psd)
310 SEC_ACL *ps_dacl = NULL;
319 for (i = 0; i < ps_dacl->num_aces; i++) {
320 SEC_ACE *psa = &ps_dacl->aces[i];
321 uint32 orig_mask = psa->access_mask;
323 se_map_generic(&psa->access_mask, &file_generic_mapping);
324 psa->access_mask |= orig_mask;
328 /*******************************************************************
329 Fill in a share info level 501 structure.
330 ********************************************************************/
332 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
333 const struct share_params *params)
335 connection_struct *conn = p->conn;
337 const char *net_name = lp_servicename(params->service);
339 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
340 conn->user, conn->connectpath, conn->gid,
341 get_current_username(),
342 current_user_info.domain,
343 lp_comment(params->service));
346 sh501->name = net_name;
347 sh501->type = get_share_type(params);
348 sh501->comment = remark;
349 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
352 /*******************************************************************
353 Fill in a share info level 502 structure.
354 ********************************************************************/
356 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
357 const struct share_params *params)
359 int max_connections = lp_max_connections(params->service);
360 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
361 connection_struct *conn = p->conn;
368 TALLOC_CTX *ctx = p->mem_ctx;
373 net_name = lp_servicename(params->service);
374 count = count_current_connections( net_name, False );
376 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
377 conn->user, conn->connectpath, conn->gid,
378 get_current_username(),
379 current_user_info.domain,
380 lp_comment(params->service));
382 path = talloc_asprintf(p->mem_ctx, "C:%s",
383 lp_pathname(params->service));
386 * Change / to \\ so that win2k will see it as a valid path. This was
387 * added to enable use of browsing in win2k add share dialog.
390 string_replace(path, '/', '\\');
392 sd = get_share_security(ctx, lp_servicename(params->service),
395 sh502->name = net_name;
396 sh502->type = get_share_type(params);
397 sh502->comment = remark;
399 sh502->password = "";
401 sh502->permissions = 0;
402 sh502->max_users = max_uses;
403 sh502->current_users = count;
407 /***************************************************************************
408 Fill in a share info level 1004 structure.
409 ***************************************************************************/
411 static void init_srv_share_info_1004(pipes_struct *p,
412 struct srvsvc_NetShareInfo1004* sh1004,
413 const struct share_params *params)
415 connection_struct *conn = p->conn;
418 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
419 conn->user, conn->connectpath, conn->gid,
420 get_current_username(),
421 current_user_info.domain,
422 lp_comment(params->service));
424 ZERO_STRUCTP(sh1004);
426 sh1004->comment = remark;
429 /***************************************************************************
430 Fill in a share info level 1005 structure.
431 ***************************************************************************/
433 static void init_srv_share_info_1005(pipes_struct *p,
434 struct srvsvc_NetShareInfo1005* sh1005,
435 const struct share_params *params)
437 sh1005->dfs_flags = 0;
439 if(lp_host_msdfs() && lp_msdfs_root(params->service))
441 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
443 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
445 /***************************************************************************
446 Fill in a share info level 1006 structure.
447 ***************************************************************************/
449 static void init_srv_share_info_1006(pipes_struct *p,
450 struct srvsvc_NetShareInfo1006* sh1006,
451 const struct share_params *params)
453 sh1006->max_users = -1;
456 /***************************************************************************
457 Fill in a share info level 1007 structure.
458 ***************************************************************************/
460 static void init_srv_share_info_1007(pipes_struct *p,
461 struct srvsvc_NetShareInfo1007* sh1007,
462 const struct share_params *params)
466 ZERO_STRUCTP(sh1007);
468 sh1007->flags = flags;
469 sh1007->alternate_directory_name = "";
472 /*******************************************************************
473 Fill in a share info level 1501 structure.
474 ********************************************************************/
476 static void init_srv_share_info_1501(pipes_struct *p,
477 struct sec_desc_buf *sh1501,
478 const struct share_params *params)
482 TALLOC_CTX *ctx = p->mem_ctx;
484 ZERO_STRUCTP(sh1501);
486 sd = get_share_security(ctx, lp_servicename(params->service),
492 /*******************************************************************
493 True if it ends in '$'.
494 ********************************************************************/
496 static BOOL is_hidden_share(const struct share_params *params)
498 const char *net_name = lp_servicename(params->service);
500 return (net_name[strlen(net_name) - 1] == '$');
503 /*******************************************************************
504 Fill in a share info structure.
505 ********************************************************************/
507 static WERROR init_srv_share_info_ctr(pipes_struct *p,
508 union srvsvc_NetShareCtr *ctr,
509 uint32 info_level, uint32 *resume_hnd,
510 uint32 *total_entries, BOOL all_shares)
512 TALLOC_CTX *ctx = p->mem_ctx;
513 struct share_iterator *shares;
514 struct share_params *share;
515 WERROR result = WERR_NOMEM;
517 DEBUG(5,("init_srv_share_info_ctr\n"));
525 /* Ensure all the usershares are loaded. */
527 load_usershare_shares();
528 load_registry_shares();
533 if (!(shares = share_list_all(ctx))) {
534 DEBUG(5, ("Could not list shares\n"));
535 return WERR_ACCESS_DENIED;
538 switch (info_level) {
540 if (!(ctr->ctr0 = TALLOC_ZERO_P(
541 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
546 if (!(ctr->ctr1 = TALLOC_ZERO_P(
547 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
552 if (!(ctr->ctr2 = TALLOC_ZERO_P(
553 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
558 if (!(ctr->ctr501 = TALLOC_ZERO_P(
559 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
564 if (!(ctr->ctr502 = TALLOC_ZERO_P(
565 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
570 if (!(ctr->ctr1004 = TALLOC_ZERO_P(
571 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
576 if (!(ctr->ctr1005 = TALLOC_ZERO_P(
577 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
582 if (!(ctr->ctr1006 = TALLOC_ZERO_P(
583 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
588 if (!(ctr->ctr1007 = TALLOC_ZERO_P(
589 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
594 if (!(ctr->ctr1501 = TALLOC_ZERO_P(
595 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
600 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
601 "value %d\n", info_level));
602 return WERR_UNKNOWN_LEVEL;
605 while ((share = next_share(shares)) != NULL) {
606 if (!lp_browseable(share->service)) {
609 if (!all_shares && is_hidden_share(share)) {
613 switch (info_level) {
616 struct srvsvc_NetShareInfo0 i;
617 init_srv_share_info_0(p, &i, share);
618 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
619 &ctr->ctr0->array, &ctr->ctr0->count);
620 if (ctr->ctr0->array == NULL) {
623 *total_entries = ctr->ctr0->count;
629 struct srvsvc_NetShareInfo1 i;
630 init_srv_share_info_1(p, &i, share);
631 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
632 &ctr->ctr1->array, &ctr->ctr1->count);
633 if (ctr->ctr1->array == NULL) {
636 *total_entries = ctr->ctr1->count;
642 struct srvsvc_NetShareInfo2 i;
643 init_srv_share_info_2(p, &i, share);
644 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
645 &ctr->ctr2->array, &ctr->ctr2->count);
646 if (ctr->ctr2->array == NULL) {
649 *total_entries = ctr->ctr2->count;
655 struct srvsvc_NetShareInfo501 i;
656 init_srv_share_info_501(p, &i, share);
657 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
658 &ctr->ctr501->array, &ctr->ctr501->count);
659 if (ctr->ctr501->array == NULL) {
662 *total_entries = ctr->ctr501->count;
668 struct srvsvc_NetShareInfo502 i;
669 init_srv_share_info_502(p, &i, share);
670 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
671 &ctr->ctr502->array, &ctr->ctr502->count);
672 if (ctr->ctr502->array == NULL) {
675 *total_entries = ctr->ctr502->count;
679 /* here for completeness but not currently used with enum
684 struct srvsvc_NetShareInfo1004 i;
685 init_srv_share_info_1004(p, &i, share);
686 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
687 &ctr->ctr1004->array, &ctr->ctr1004->count);
688 if (ctr->ctr1004->array == NULL) {
691 *total_entries = ctr->ctr1004->count;
697 struct srvsvc_NetShareInfo1005 i;
698 init_srv_share_info_1005(p, &i, share);
699 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
700 &ctr->ctr1005->array, &ctr->ctr1005->count);
701 if (ctr->ctr1005->array == NULL) {
704 *total_entries = ctr->ctr1005->count;
710 struct srvsvc_NetShareInfo1006 i;
711 init_srv_share_info_1006(p, &i, share);
712 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
713 &ctr->ctr1006->array, &ctr->ctr1006->count);
714 if (ctr->ctr1006->array == NULL) {
717 *total_entries = ctr->ctr1006->count;
723 struct srvsvc_NetShareInfo1007 i;
724 init_srv_share_info_1007(p, &i, share);
725 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
726 &ctr->ctr1007->array, &ctr->ctr1007->count);
727 if (ctr->ctr1007->array == NULL) {
730 *total_entries = ctr->ctr1007->count;
736 struct sec_desc_buf i;
737 init_srv_share_info_1501(p, &i, share);
738 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
739 &ctr->ctr1501->array, &ctr->ctr1501->count);
740 if (ctr->ctr1501->array == NULL) {
743 *total_entries = ctr->ctr1501->count;
757 /*******************************************************************
758 fill in a sess info level 0 structure.
759 ********************************************************************/
761 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
763 struct sessionid *session_list;
764 uint32 num_entries = 0;
765 (*stot) = list_sessions(p->mem_ctx, &session_list);
774 DEBUG(5,("init_srv_sess_0_ss0\n"));
776 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
779 for (; (*snum) < (*stot); (*snum)++) {
780 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
784 ss0->count = num_entries;
786 if ((*snum) >= (*stot)) {
796 /*******************************************************************
797 ********************************************************************/
799 static void sess_file_fn( const struct share_mode_entry *e,
800 const char *sharepath, const char *fname,
803 struct sess_file_count *sess = (struct sess_file_count *)private_data;
805 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
812 /*******************************************************************
813 ********************************************************************/
815 static int net_count_files( uid_t uid, struct server_id pid )
817 struct sess_file_count s_file_cnt;
819 s_file_cnt.count = 0;
820 s_file_cnt.uid = uid;
821 s_file_cnt.pid = pid;
823 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
825 return s_file_cnt.count;
828 /*******************************************************************
829 fill in a sess info level 1 structure.
830 ********************************************************************/
832 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
834 struct sessionid *session_list;
835 uint32 num_entries = 0;
836 time_t now = time(NULL);
853 (*stot) = list_sessions(p->mem_ctx, &session_list);
855 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
857 for (; (*snum) < (*stot); (*snum)++) {
860 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
864 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
865 session_list[*snum].username));
869 connect_time = (uint32)(now - session_list[*snum].connect_start);
870 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
871 guest = strequal( session_list[*snum].username, lp_guestaccount() );
873 if (!(ss1->array[num_entries].client = talloc_strdup(
874 ss1->array, session_list[*snum].remote_machine))) {
875 ss1->array[num_entries].client = "";
877 if (!(ss1->array[num_entries].user = talloc_strdup(
878 ss1->array, session_list[*snum].username))) {
879 ss1->array[num_entries].user = "";
881 ss1->array[num_entries].num_open = num_files;
882 ss1->array[num_entries].time = connect_time;
883 ss1->array[num_entries].idle_time = 0;
884 ss1->array[num_entries].user_flags = guest;
889 ss1->count = num_entries;
891 if ((*snum) >= (*stot)) {
896 /*******************************************************************
897 makes a SRV_R_NET_SESS_ENUM structure.
898 ********************************************************************/
900 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
901 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
903 WERROR status = WERR_OK;
904 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
906 switch (switch_value) {
908 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
909 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
912 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
913 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
916 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
917 if (resume_hnd != NULL)
919 (*total_entries) = 0;
921 status = WERR_UNKNOWN_LEVEL;
928 /*******************************************************************
929 fill in a conn info level 0 structure.
930 ********************************************************************/
932 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
934 uint32 num_entries = 0;
943 DEBUG(5,("init_srv_conn_0_ss0\n"));
946 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
947 for (; (*snum) < (*stot); (*snum)++) {
949 ss0->array[num_entries].conn_id = (*stot);
951 /* move on to creating next connection */
952 /* move on to creating next conn */
956 ss0->count = num_entries;
958 if ((*snum) >= (*stot)) {
970 /*******************************************************************
971 fill in a conn info level 1 structure.
972 ********************************************************************/
974 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
976 uint32 num_entries = 0;
985 DEBUG(5,("init_srv_conn_1_ss1\n"));
988 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
989 for (; (*snum) < (*stot); (*snum)++) {
990 ss1->array[num_entries].conn_id = (*stot);
991 ss1->array[num_entries].conn_type = 0x3;
992 ss1->array[num_entries].num_open = 1;
993 ss1->array[num_entries].num_users = 1;
994 ss1->array[num_entries].conn_time = 3;
995 ss1->array[num_entries].user = "dummy_user";
996 ss1->array[num_entries].share = "IPC$";
998 /* move on to creating next connection */
999 /* move on to creating next conn */
1003 ss1->count = num_entries;
1005 if ((*snum) >= (*stot)) {
1017 /*******************************************************************
1018 makes a SRV_R_NET_CONN_ENUM structure.
1019 ********************************************************************/
1021 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1022 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1024 WERROR status = WERR_OK;
1025 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1027 switch (switch_value) {
1029 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1032 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1035 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1038 (*total_entries) = 0;
1039 status = WERR_UNKNOWN_LEVEL;
1046 /*******************************************************************
1047 makes a SRV_R_NET_FILE_ENUM structure.
1048 ********************************************************************/
1050 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1054 /* TODO -- Windows enumerates
1056 (c) open directories and files */
1058 ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3);
1060 status = net_enum_files(p->mem_ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1061 if ( !W_ERROR_IS_OK(status))
1064 status = net_enum_pipes(p->mem_ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1065 if ( !W_ERROR_IS_OK(status))
1068 ctr->ctr3->count = *num_entries;
1073 /*******************************************************************
1074 *******************************************************************/
1076 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1078 switch ( *r->in.level ) {
1080 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, r->out.totalentries );
1082 return WERR_UNKNOWN_LEVEL;
1088 /*******************************************************************
1090 ********************************************************************/
1092 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1094 WERROR status = WERR_OK;
1096 ZERO_STRUCTP(r->out.info);
1098 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1100 if (!pipe_access_check(p)) {
1101 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1102 return WERR_ACCESS_DENIED;
1105 switch (r->in.level) {
1107 /* Technically level 102 should only be available to
1108 Administrators but there isn't anything super-secret
1109 here, as most of it is made up. */
1112 r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1114 r->out.info->info102->platform_id = 500;
1115 r->out.info->info102->version_major = lp_major_announce_version();
1116 r->out.info->info102->version_minor = lp_minor_announce_version();
1117 r->out.info->info102->server_name = global_myname();
1118 r->out.info->info102->server_type = lp_default_server_announce();
1119 r->out.info->info102->userpath = "C:\\";
1120 r->out.info->info102->licenses = 10000;
1121 r->out.info->info102->anndelta = 3000;
1122 r->out.info->info102->disc = 0xf;
1123 r->out.info->info102->users = 0xffffffff;
1124 r->out.info->info102->hidden = 0;
1125 r->out.info->info102->announce = 240;
1126 r->out.info->info102->comment = lp_serverstring();
1129 r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1130 r->out.info->info101->platform_id = 500;
1131 r->out.info->info101->server_name = global_myname();
1132 r->out.info->info101->version_major = lp_major_announce_version();
1133 r->out.info->info101->version_minor = lp_minor_announce_version();
1134 r->out.info->info101->server_type = lp_default_server_announce();
1135 r->out.info->info101->comment = lp_serverstring();
1138 r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1139 r->out.info->info100->platform_id = 500;
1140 r->out.info->info100->server_name = global_myname();
1143 return WERR_UNKNOWN_LEVEL;
1147 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1152 /*******************************************************************
1154 ********************************************************************/
1156 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1158 /* Set up the net server set info structure. */
1159 if (r->out.parm_error) {
1160 *r->out.parm_error = 0;
1165 /*******************************************************************
1167 ********************************************************************/
1169 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1171 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1173 ZERO_STRUCTP(r->out.ctr);
1176 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1179 /*******************************************************************
1181 ********************************************************************/
1183 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1185 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1187 ZERO_STRUCTP(r->out.ctr);
1190 return init_srv_sess_info_ctr(p, r->out.ctr,
1192 r->in.resume_handle,
1193 r->out.totalentries);
1196 /*******************************************************************
1198 ********************************************************************/
1200 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1202 struct sessionid *session_list;
1203 int num_sessions, snum;
1206 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1208 /* strip leading backslashes if any */
1209 while (machine[0] == '\\') {
1210 memmove(machine, &machine[1], strlen(machine));
1213 num_sessions = list_sessions(p->mem_ctx, &session_list);
1215 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1217 status = WERR_ACCESS_DENIED;
1219 /* fail out now if you are not root or not a domain admin */
1221 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1222 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1227 for (snum = 0; snum < num_sessions; snum++) {
1229 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1230 strequal(session_list[snum].remote_machine, machine)) {
1233 ntstat = messaging_send(smbd_messaging_context(),
1234 session_list[snum].pid,
1235 MSG_SHUTDOWN, &data_blob_null);
1237 if (NT_STATUS_IS_OK(ntstat))
1242 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1248 /*******************************************************************
1250 ********************************************************************/
1252 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1254 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1256 if (!pipe_access_check(p)) {
1257 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1258 return WERR_ACCESS_DENIED;
1261 /* Create the list of shares for the response. */
1262 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1263 r->in.resume_handle, r->out.totalentries, True);
1266 /*******************************************************************
1268 ********************************************************************/
1270 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
1272 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1274 if (!pipe_access_check(p)) {
1275 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1276 return WERR_ACCESS_DENIED;
1279 /* Create the list of shares for the response. */
1280 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1281 r->in.resume_handle, r->out.totalentries, False);
1284 /*******************************************************************
1286 ********************************************************************/
1288 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1290 const struct share_params *params;
1292 params = get_share_params(p->mem_ctx, r->in.share_name);
1294 if (params != NULL) {
1295 switch (r->in.level) {
1297 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1298 init_srv_share_info_0(p, r->out.info->info0, params);
1301 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1302 init_srv_share_info_1(p, r->out.info->info1, params);
1305 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1306 init_srv_share_info_2(p, r->out.info->info2, params);
1309 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1310 init_srv_share_info_501(p, r->out.info->info501, params);
1313 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1314 init_srv_share_info_502(p, r->out.info->info502, params);
1317 /* here for completeness */
1319 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1320 init_srv_share_info_1004(p, r->out.info->info1004, params);
1323 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1324 init_srv_share_info_1005(p, r->out.info->info1005, params);
1327 /* here for completeness 1006 - 1501 */
1329 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1330 init_srv_share_info_1006(p, r->out.info->info1006,
1334 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1335 init_srv_share_info_1007(p, r->out.info->info1007,
1339 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1340 init_srv_share_info_1501(p, r->out.info->info1501,
1344 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1345 "switch value %d\n", r->in.level));
1346 return WERR_UNKNOWN_LEVEL;
1350 return WERR_INVALID_NAME;
1356 /*******************************************************************
1357 Check a given DOS pathname is valid for a share.
1358 ********************************************************************/
1360 char *valid_share_pathname(char *dos_pathname)
1364 /* Convert any '\' paths to '/' */
1365 unix_format(dos_pathname);
1366 unix_clean_name(dos_pathname);
1368 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1370 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1373 /* Only absolute paths allowed. */
1380 static void setval_helper(struct registry_key *key, const char *name,
1381 const char *value, WERROR *err)
1383 struct registry_value val;
1385 if (!W_ERROR_IS_OK(*err)) {
1391 val.v.sz.str = CONST_DISCARD(char *, value);
1392 val.v.sz.len = strlen(value)+1;
1394 *err = reg_setvalue(key, name, &val);
1397 static WERROR add_share(const char *share_name, const char *path,
1398 const char *comment, uint32 max_connections,
1399 const struct nt_user_token *token,
1402 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1406 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1407 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1408 path, comment, max_connections) == -1) {
1412 DEBUG(10,("add_share: Running [%s]\n", command ));
1414 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1419 if ( (ret = smbrun(command, NULL)) == 0 ) {
1420 /* Tell everyone we updated smb.conf. */
1421 message_send_all(smbd_messaging_context(),
1422 MSG_SMB_CONF_UPDATED,
1429 /********* END SeDiskOperatorPrivilege BLOCK *********/
1431 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1435 * No fallback to registry shares, the user did define a add
1436 * share command, so fail here.
1440 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1443 if (lp_registry_shares()) {
1445 struct registry_key *key;
1446 enum winreg_CreateAction action;
1448 TALLOC_CTX *mem_ctx;
1450 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1455 mem_ctx = (TALLOC_CTX *)keyname;
1457 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1458 is_disk_op ? get_root_nt_token():token,
1461 if (action != REG_CREATED_NEW_KEY) {
1462 err = WERR_ALREADY_EXISTS;
1465 if (!W_ERROR_IS_OK(err)) {
1466 TALLOC_FREE(mem_ctx);
1470 setval_helper(key, "path", path, &err);
1471 if ((comment != NULL) && (comment[0] != '\0')) {
1472 setval_helper(key, "comment", comment, &err);
1474 if (max_connections != 0) {
1476 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1477 setval_helper(key, "max connections", tmp, &err);
1480 if (!W_ERROR_IS_OK(err)) {
1482 * Hmmmm. We'd need transactions on the registry to
1483 * get this right....
1485 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1488 TALLOC_FREE(mem_ctx);
1492 return WERR_ACCESS_DENIED;
1495 static WERROR delete_share(const char *sharename,
1496 const struct nt_user_token *token,
1499 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1503 if (asprintf(&command, "%s \"%s\" \"%s\"",
1504 lp_delete_share_cmd(), dyn_CONFIGFILE,
1509 DEBUG(10,("delete_share: Running [%s]\n", command ));
1511 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1516 if ( (ret = smbrun(command, NULL)) == 0 ) {
1517 /* Tell everyone we updated smb.conf. */
1518 message_send_all(smbd_messaging_context(),
1519 MSG_SMB_CONF_UPDATED,
1526 /********* END SeDiskOperatorPrivilege BLOCK *********/
1530 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1532 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1535 if (lp_registry_shares()) {
1539 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1544 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1550 return WERR_ACCESS_DENIED;
1553 static WERROR change_share(const char *share_name, const char *path,
1554 const char *comment, uint32 max_connections,
1555 const struct nt_user_token *token,
1558 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1562 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1563 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1564 path, comment, max_connections) == -1) {
1568 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1570 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1575 if ( (ret = smbrun(command, NULL)) == 0 ) {
1576 /* Tell everyone we updated smb.conf. */
1577 message_send_all(smbd_messaging_context(),
1578 MSG_SMB_CONF_UPDATED,
1585 /********* END SeDiskOperatorPrivilege BLOCK *********/
1587 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1588 "(%d)\n", command, ret ));
1592 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1595 if (lp_registry_shares()) {
1597 struct registry_key *key;
1599 TALLOC_CTX *mem_ctx;
1601 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1606 mem_ctx = (TALLOC_CTX *)keyname;
1608 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1609 is_disk_op ? get_root_nt_token():token,
1611 if (!W_ERROR_IS_OK(err)) {
1612 TALLOC_FREE(mem_ctx);
1616 setval_helper(key, "path", path, &err);
1618 reg_deletevalue(key, "comment");
1619 if ((comment != NULL) && (comment[0] != '\0')) {
1620 setval_helper(key, "comment", comment, &err);
1623 reg_deletevalue(key, "max connections");
1624 if (max_connections != 0) {
1626 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1627 setval_helper(key, "max connections", tmp, &err);
1630 TALLOC_FREE(mem_ctx);
1634 return WERR_ACCESS_DENIED;
1637 /*******************************************************************
1638 Net share set info. Modify share details.
1639 ********************************************************************/
1641 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1648 SEC_DESC *psd = NULL;
1649 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1650 BOOL is_disk_op = False;
1651 int max_connections = 0;
1652 fstring tmp_share_name;
1654 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1656 if (r->out.parm_error) {
1657 *r->out.parm_error = 0;
1660 if ( strequal(r->in.share_name,"IPC$")
1661 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1662 || strequal(r->in.share_name,"global") )
1664 return WERR_ACCESS_DENIED;
1667 fstrcpy(tmp_share_name, r->in.share_name);
1668 snum = find_service(tmp_share_name);
1670 /* Does this share exist ? */
1672 return WERR_NET_NAME_NOT_FOUND;
1674 /* No change to printer shares. */
1675 if (lp_print_ok(snum))
1676 return WERR_ACCESS_DENIED;
1678 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1681 /* fail out now if you are not root and not a disk op */
1683 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1684 return WERR_ACCESS_DENIED;
1686 switch (r->in.level) {
1688 pstrcpy(pathname, lp_pathname(snum));
1689 pstrcpy(comment, r->in.info.info1->comment);
1690 type = r->in.info.info1->type;
1694 pstrcpy(comment, r->in.info.info2->comment);
1695 pstrcpy(pathname, r->in.info.info2->path);
1696 type = r->in.info.info2->type;
1697 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1698 0 : r->in.info.info2->max_users;
1702 pstrcpy(comment, r->in.info.info502->comment);
1703 pstrcpy(pathname, r->in.info.info502->path);
1704 type = r->in.info.info502->type;
1705 psd = r->in.info.info502->sd;
1706 map_generic_share_sd_bits(psd);
1709 pstrcpy(pathname, lp_pathname(snum));
1710 pstrcpy(comment, r->in.info.info1004->comment);
1711 type = STYPE_DISKTREE;
1714 /* XP re-sets the csc policy even if it wasn't changed by the
1715 user, so we must compare it to see if it's what is set in
1716 smb.conf, so that we can contine other ops like setting
1718 if (((r->in.info.info1005->dfs_flags &
1719 SHARE_1005_CSC_POLICY_MASK) >>
1720 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1723 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1724 "to change csc policy from the network; "
1725 "must be done with smb.conf\n"));
1726 return WERR_ACCESS_DENIED;
1730 return WERR_ACCESS_DENIED;
1732 pstrcpy(pathname, lp_pathname(snum));
1733 pstrcpy(comment, lp_comment(snum));
1734 psd = r->in.info.info1501->sd;
1735 map_generic_share_sd_bits(psd);
1736 type = STYPE_DISKTREE;
1739 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1740 "%d\n", r->in.level));
1741 return WERR_UNKNOWN_LEVEL;
1744 /* We can only modify disk shares. */
1745 if (type != STYPE_DISKTREE)
1746 return WERR_ACCESS_DENIED;
1748 /* Check if the pathname is valid. */
1749 if (!(path = valid_share_pathname( pathname )))
1750 return WERR_OBJECT_PATH_INVALID;
1752 /* Ensure share name, pathname and comment don't contain '"'
1754 string_replace(tmp_share_name, '"', ' ');
1755 string_replace(path, '"', ' ');
1756 string_replace(comment, '"', ' ');
1758 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1759 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1761 /* Only call modify function if something changed. */
1763 if (strcmp(path, lp_pathname(snum))
1764 || strcmp(comment, lp_comment(snum))
1765 || (lp_max_connections(snum) != max_connections) ) {
1768 err = change_share(tmp_share_name, path, comment,
1769 max_connections, p->pipe_user.nt_user_token,
1772 if (!W_ERROR_IS_OK(err)) {
1777 /* Replace SD if changed. */
1782 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1785 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1786 if (!set_share_security(r->in.share_name, psd)) {
1787 DEBUG(0,("_srv_net_share_set_info: Failed to "
1788 "change security info in share %s.\n",
1789 r->in.share_name ));
1794 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1800 /*******************************************************************
1801 Net share add. Call 'add_share_command "sharename" "pathname"
1802 "comment" "max connections = "
1803 ********************************************************************/
1805 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1812 SEC_DESC *psd = NULL;
1813 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1815 uint32 max_connections = 0;
1818 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1820 if (r->out.parm_error) {
1821 *r->out.parm_error = 0;
1824 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1827 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1828 return WERR_ACCESS_DENIED;
1830 switch (r->in.level) {
1832 /* No path. Not enough info in a level 0 to do anything. */
1833 return WERR_ACCESS_DENIED;
1835 /* Not enough info in a level 1 to do anything. */
1836 return WERR_ACCESS_DENIED;
1838 pstrcpy(share_name, r->in.info.info2->name);
1839 pstrcpy(comment, r->in.info.info2->comment);
1840 pstrcpy(pathname, r->in.info.info2->path);
1841 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1842 0 : r->in.info.info2->max_users;
1843 type = r->in.info.info2->type;
1846 /* No path. Not enough info in a level 501 to do anything. */
1847 return WERR_ACCESS_DENIED;
1849 pstrcpy(share_name, r->in.info.info502->name);
1850 pstrcpy(comment, r->in.info.info502->comment);
1851 pstrcpy(pathname, r->in.info.info502->path);
1852 type = r->in.info.info502->type;
1853 psd = r->in.info.info502->sd;
1854 map_generic_share_sd_bits(psd);
1857 /* none of the following contain share names. NetShareAdd
1858 * does not have a separate parameter for the share name */
1864 return WERR_ACCESS_DENIED;
1866 /* DFS only level. */
1867 return WERR_ACCESS_DENIED;
1869 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1871 return WERR_UNKNOWN_LEVEL;
1874 /* check for invalid share names */
1876 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1877 sizeof(share_name) ) ) {
1878 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1880 return WERR_INVALID_NAME;
1883 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1884 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1886 return WERR_ACCESS_DENIED;
1889 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1890 /* Share already exists. */
1891 return WERR_ALREADY_EXISTS;
1894 /* We can only add disk shares. */
1895 if (type != STYPE_DISKTREE)
1896 return WERR_ACCESS_DENIED;
1898 /* Check if the pathname is valid. */
1899 if (!(path = valid_share_pathname( pathname )))
1900 return WERR_OBJECT_PATH_INVALID;
1902 /* Ensure share name, pathname and comment don't contain '"'
1905 string_replace(share_name, '"', ' ');
1906 string_replace(path, '"', ' ');
1907 string_replace(comment, '"', ' ');
1909 err = add_share(share_name, path, comment, max_connections,
1910 p->pipe_user.nt_user_token, is_disk_op);
1912 if (!W_ERROR_IS_OK(err)) {
1917 if (!set_share_security(share_name, psd)) {
1918 DEBUG(0,("_srv_net_share_add: Failed to add security "
1919 "info to share %s.\n", share_name ));
1924 * We don't call reload_services() here, the message will
1925 * cause this to be done before the next packet is read
1926 * from the client. JRA.
1929 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1934 /*******************************************************************
1935 Net share delete. Call "delete share command" with the share name as
1937 ********************************************************************/
1939 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1941 struct share_params *params;
1942 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1946 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1948 if ( strequal(r->in.share_name, "IPC$")
1949 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1950 || strequal(r->in.share_name, "global") )
1952 return WERR_ACCESS_DENIED;
1955 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1956 return WERR_NO_SUCH_SHARE;
1959 /* No change to printer shares. */
1960 if (lp_print_ok(params->service))
1961 return WERR_ACCESS_DENIED;
1963 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1966 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1967 return WERR_ACCESS_DENIED;
1969 err = delete_share(lp_servicename(params->service),
1970 p->pipe_user.nt_user_token, is_disk_op);
1972 if (!W_ERROR_IS_OK(err)) {
1976 /* Delete the SD in the database. */
1977 delete_share_security(params);
1979 lp_killservice(params->service);
1984 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
1986 struct srvsvc_NetShareDel s;
1988 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1990 s.in.server_unc = r->in.server_unc;
1991 s.in.share_name = r->in.share_name;
1992 s.in.reserved = r->in.reserved;
1994 return _srvsvc_NetShareDel(p, &s);
1997 /*******************************************************************
1999 ********************************************************************/
2001 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
2004 time_t unixdate = time(NULL);
2005 WERROR status = WERR_OK;
2007 /* We do this call first as if we do it *after* the gmtime call
2008 it overwrites the pointed-to values. JRA */
2010 uint32 zone = get_time_zone(unixdate)/60;
2012 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2014 t = gmtime(&unixdate);
2017 r->out.info->elapsed = unixdate;
2018 r->out.info->msecs = 0;
2019 r->out.info->hours = t->tm_hour;
2020 r->out.info->mins = t->tm_min;
2021 r->out.info->secs = t->tm_sec;
2022 r->out.info->hunds = 0;
2023 r->out.info->timezone = zone;
2024 r->out.info->tinterval = 10000;
2025 r->out.info->day = t->tm_mday;
2026 r->out.info->month = t->tm_mon + 1;
2027 r->out.info->year = 1900+t->tm_year;
2028 r->out.info->weekday = t->tm_wday;
2030 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2035 /***********************************************************************************
2036 Win9x NT tools get security descriptor.
2037 ***********************************************************************************/
2039 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2041 SEC_DESC *psd = NULL;
2044 files_struct *fsp = NULL;
2047 connection_struct *conn = NULL;
2048 BOOL became_user = False;
2049 WERROR status = WERR_OK;
2050 char *tmp_file = NULL;
2051 TALLOC_CTX *ctx = talloc_tos();
2056 /* Null password is ok - we are already an authenticated user... */
2057 null_pw = data_blob_null;
2060 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2064 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2065 status = ntstatus_to_werror(nt_status);
2069 if (!become_user(conn, conn->vuid)) {
2070 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2071 status = WERR_ACCESS_DENIED;
2077 status = WERR_INVALID_PARAM;
2080 nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st);
2081 if (!NT_STATUS_IS_OK(nt_status)) {
2082 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2083 status = WERR_ACCESS_DENIED;
2087 nt_status = check_name(conn, tmp_file);
2088 if (!NT_STATUS_IS_OK(nt_status)) {
2089 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", tmp_file));
2090 status = WERR_ACCESS_DENIED;
2094 nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
2095 if (!NT_STATUS_IS_OK(nt_status)) {
2096 /* Perhaps it is a directory */
2097 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2098 nt_status = open_directory(conn, NULL, tmp_file, &st,
2099 READ_CONTROL_ACCESS,
2100 FILE_SHARE_READ|FILE_SHARE_WRITE,
2103 FILE_ATTRIBUTE_DIRECTORY,
2106 if (!NT_STATUS_IS_OK(nt_status)) {
2107 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", tmp_file));
2108 status = WERR_ACCESS_DENIED;
2113 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2116 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", tmp_file));
2117 status = WERR_ACCESS_DENIED;
2121 r->out.sd_buf->sd_size= sd_size;
2122 r->out.sd_buf->sd = psd;
2124 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2126 close_file(fsp, NORMAL_CLOSE);
2128 close_cnum(conn, p->pipe_user.vuid);
2134 close_file(fsp, NORMAL_CLOSE);
2141 close_cnum(conn, p->pipe_user.vuid);
2146 /***********************************************************************************
2147 Win9x NT tools set security descriptor.
2148 ***********************************************************************************/
2150 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2153 files_struct *fsp = NULL;
2156 connection_struct *conn = NULL;
2157 BOOL became_user = False;
2158 WERROR status = WERR_OK;
2159 char *tmp_file = NULL;
2160 TALLOC_CTX *ctx = talloc_tos();
2164 /* Null password is ok - we are already an authenticated user... */
2165 null_pw = data_blob_null;
2168 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2172 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2173 status = ntstatus_to_werror(nt_status);
2177 if (!become_user(conn, conn->vuid)) {
2178 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2179 status = WERR_ACCESS_DENIED;
2185 status = WERR_INVALID_PARAM;
2188 nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, 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, tmp_file);
2196 if (!NT_STATUS_IS_OK(nt_status)) {
2197 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", tmp_file));
2198 status = WERR_ACCESS_DENIED;
2203 nt_status = open_file_stat(conn, NULL, tmp_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, NULL, tmp_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", tmp_file));
2218 status = WERR_ACCESS_DENIED;
2223 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2225 if (!NT_STATUS_IS_OK(nt_status)) {
2226 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", tmp_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;