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.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 /* This is the implementation of the srvsvc pipe. */
27 extern const struct generic_mapping file_generic_mapping;
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /* Use for enumerating connections, pipes, & files */
34 struct file_enum_count {
37 struct srvsvc_NetFileCtr3 *ctr3;
40 struct sess_file_count {
46 /****************************************************************************
47 Count the entries belonging to a service in the connection db.
48 ****************************************************************************/
50 static int pipe_enum_fn( struct db_record *rec, void *p)
52 struct pipe_open_rec prec;
53 struct file_enum_count *fenum = (struct file_enum_count *)p;
54 struct srvsvc_NetFileInfo3 *f;
55 int i = fenum->ctr3->count;
56 char *fullpath = NULL;
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) ) {
68 username = uidtoname(prec.uid);
70 if ((fenum->username != NULL)
71 && !strequal(username, fenum->username)) {
75 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
80 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
81 struct srvsvc_NetFileInfo3, i+1);
83 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
86 fenum->ctr3->array = f;
88 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
89 (uint32_t)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
90 (FILE_READ_DATA|FILE_WRITE_DATA),
100 /*******************************************************************
101 ********************************************************************/
103 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
104 const char *username,
105 struct srvsvc_NetFileCtr3 **ctr3,
108 struct file_enum_count fenum;
111 fenum.username = username;
114 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
115 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
125 /*******************************************************************
126 ********************************************************************/
128 static void enum_file_fn( const struct share_mode_entry *e,
129 const char *sharepath, const char *fname,
132 struct file_enum_count *fenum =
133 (struct file_enum_count *)private_data;
135 struct srvsvc_NetFileInfo3 *f;
136 int i = fenum->ctr3->count;
138 struct byte_range_lock *brl;
140 char *fullpath = NULL;
142 const char *username;
144 /* If the pid was not found delete the entry from connections.tdb */
146 if ( !process_exists(e->pid) ) {
150 username = uidtoname(e->uid);
152 if ((fenum->username != NULL)
153 && !strequal(username, fenum->username)) {
157 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
158 struct srvsvc_NetFileInfo3, i+1);
160 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
163 fenum->ctr3->array = f;
165 /* need to count the number of locks on a file */
170 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
171 num_locks = brl->num_locks;
175 if ( strcmp( fname, "." ) == 0 ) {
176 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
178 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
184 string_replace( fullpath, '/', '\\' );
186 /* mask out create (what ever that is) */
187 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
189 /* now fill in the srvsvc_NetFileInfo3 struct */
190 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
196 fenum->ctr3->count++;
199 /*******************************************************************
200 ********************************************************************/
202 static WERROR net_enum_files(TALLOC_CTX *ctx,
203 const char *username,
204 struct srvsvc_NetFileCtr3 **ctr3,
207 struct file_enum_count f_enum_cnt;
209 f_enum_cnt.ctx = ctx;
210 f_enum_cnt.username = username;
211 f_enum_cnt.ctr3 = *ctr3;
213 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
215 *ctr3 = f_enum_cnt.ctr3;
220 /*******************************************************************
221 Utility function to get the 'type' of a share from an snum.
222 ********************************************************************/
223 static uint32 get_share_type(int snum)
225 /* work out the share type */
226 uint32 type = STYPE_DISKTREE;
228 if (lp_print_ok(snum))
230 if (strequal(lp_fstype(snum), "IPC"))
232 if (lp_administrative_share(snum))
233 type |= STYPE_HIDDEN;
238 /*******************************************************************
239 Fill in a share info level 0 structure.
240 ********************************************************************/
242 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
244 const char *net_name = lp_servicename(snum);
246 init_srvsvc_NetShareInfo0(r, net_name);
249 /*******************************************************************
250 Fill in a share info level 1 structure.
251 ********************************************************************/
253 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
255 char *net_name = lp_servicename(snum);
256 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
259 remark = standard_sub_conn(p->mem_ctx,
264 init_srvsvc_NetShareInfo1(r, net_name,
265 get_share_type(snum),
266 remark ? remark : "");
269 /*******************************************************************
270 Fill in a share info level 2 structure.
271 ********************************************************************/
273 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
277 int max_connections = lp_max_connections(snum);
278 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
280 char *net_name = lp_servicename(snum);
282 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
284 remark = standard_sub_conn(p->mem_ctx,
288 path = talloc_asprintf(p->mem_ctx,
289 "C:%s", lp_pathname(snum));
293 * Change / to \\ so that win2k will see it as a valid path.
294 * This was added to enable use of browsing in win2k add
298 string_replace(path, '/', '\\');
301 count = count_current_connections(net_name, false);
303 init_srvsvc_NetShareInfo2(r, net_name,
304 get_share_type(snum),
305 remark ? remark : "",
313 /*******************************************************************
314 Map any generic bits to file specific bits.
315 ********************************************************************/
317 static void map_generic_share_sd_bits(SEC_DESC *psd)
320 SEC_ACL *ps_dacl = NULL;
329 for (i = 0; i < ps_dacl->num_aces; i++) {
330 SEC_ACE *psa = &ps_dacl->aces[i];
331 uint32 orig_mask = psa->access_mask;
333 se_map_generic(&psa->access_mask, &file_generic_mapping);
334 psa->access_mask |= orig_mask;
338 /*******************************************************************
339 Fill in a share info level 501 structure.
340 ********************************************************************/
342 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
344 const char *net_name = lp_servicename(snum);
345 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
348 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
351 init_srvsvc_NetShareInfo501(r, net_name,
352 get_share_type(snum),
353 remark ? remark : "",
354 (lp_csc_policy(snum) << 4));
357 /*******************************************************************
358 Fill in a share info level 502 structure.
359 ********************************************************************/
361 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
363 const char *net_name = lp_servicename(snum);
367 TALLOC_CTX *ctx = p->mem_ctx;
368 char *remark = talloc_strdup(ctx, lp_comment(snum));;
371 remark = standard_sub_conn(ctx, p->conn, remark);
373 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
376 * Change / to \\ so that win2k will see it as a valid path. This was added to
377 * enable use of browsing in win2k add share dialog.
379 string_replace(path, '/', '\\');
382 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
384 init_srvsvc_NetShareInfo502(r, net_name,
385 get_share_type(snum),
386 remark ? remark : "",
396 /***************************************************************************
397 Fill in a share info level 1004 structure.
398 ***************************************************************************/
400 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
402 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
405 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
408 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
411 /***************************************************************************
412 Fill in a share info level 1005 structure.
413 ***************************************************************************/
415 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
417 uint32_t dfs_flags = 0;
419 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
420 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
423 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
425 init_srvsvc_NetShareInfo1005(r, dfs_flags);
428 /***************************************************************************
429 Fill in a share info level 1006 structure.
430 ***************************************************************************/
432 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
434 init_srvsvc_NetShareInfo1006(r, 0xffffffff);
437 /***************************************************************************
438 Fill in a share info level 1007 structure.
439 ***************************************************************************/
441 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
445 init_srvsvc_NetShareInfo1007(r, flags, "");
448 /*******************************************************************
449 Fill in a share info level 1501 structure.
450 ********************************************************************/
452 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
456 TALLOC_CTX *ctx = p->mem_ctx;
458 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
460 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
463 /*******************************************************************
464 True if it ends in '$'.
465 ********************************************************************/
467 static bool is_hidden_share(int snum)
469 const char *net_name = lp_servicename(snum);
471 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
474 /*******************************************************************
475 Fill in a share info structure.
476 ********************************************************************/
478 static WERROR init_srv_share_info_ctr(pipes_struct *p,
479 struct srvsvc_NetShareInfoCtr *info_ctr,
480 uint32_t *resume_handle_p,
481 uint32_t *total_entries,
485 int alloc_entries = 0;
486 int num_services = 0;
488 TALLOC_CTX *ctx = p->mem_ctx;
490 int valid_share_count = 0;
491 union srvsvc_NetShareCtr ctr;
492 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
494 DEBUG(5,("init_srv_share_info_ctr\n"));
496 /* Ensure all the usershares are loaded. */
498 load_usershare_shares();
499 load_registry_shares();
500 num_services = lp_numservices();
503 /* Count the number of entries. */
504 for (snum = 0; snum < num_services; snum++) {
505 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
506 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
509 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
513 if (!num_entries || (resume_handle >= num_entries)) {
517 /* Calculate alloc entries. */
518 alloc_entries = num_entries - resume_handle;
519 switch (info_ctr->level) {
521 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
522 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
524 ctr.ctr0->count = alloc_entries;
525 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
526 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
528 for (snum = 0; snum < num_services; snum++) {
529 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
530 (resume_handle <= (i + valid_share_count++)) ) {
531 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
538 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
539 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
541 ctr.ctr1->count = alloc_entries;
542 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
543 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
545 for (snum = 0; snum < num_services; snum++) {
546 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
547 (resume_handle <= (i + valid_share_count++)) ) {
548 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
555 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
556 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
558 ctr.ctr2->count = alloc_entries;
559 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
560 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
562 for (snum = 0; snum < num_services; snum++) {
563 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
564 (resume_handle <= (i + valid_share_count++)) ) {
565 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
572 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
573 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
575 ctr.ctr501->count = alloc_entries;
576 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
577 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
579 for (snum = 0; snum < num_services; snum++) {
580 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
581 (resume_handle <= (i + valid_share_count++)) ) {
582 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
589 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
590 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
592 ctr.ctr502->count = alloc_entries;
593 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
594 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
596 for (snum = 0; snum < num_services; snum++) {
597 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
598 (resume_handle <= (i + valid_share_count++)) ) {
599 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
606 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
607 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
609 ctr.ctr1004->count = alloc_entries;
610 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
611 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
613 for (snum = 0; snum < num_services; snum++) {
614 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
615 (resume_handle <= (i + valid_share_count++)) ) {
616 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
623 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
624 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
626 ctr.ctr1005->count = alloc_entries;
627 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
628 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
630 for (snum = 0; snum < num_services; snum++) {
631 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
632 (resume_handle <= (i + valid_share_count++)) ) {
633 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
640 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
641 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
643 ctr.ctr1006->count = alloc_entries;
644 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
645 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
647 for (snum = 0; snum < num_services; snum++) {
648 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
649 (resume_handle <= (i + valid_share_count++)) ) {
650 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
657 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
658 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
660 ctr.ctr1007->count = alloc_entries;
661 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
662 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
664 for (snum = 0; snum < num_services; snum++) {
665 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
666 (resume_handle <= (i + valid_share_count++)) ) {
667 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
674 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
675 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
677 ctr.ctr1501->count = alloc_entries;
678 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
679 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
681 for (snum = 0; snum < num_services; snum++) {
682 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
683 (resume_handle <= (i + valid_share_count++)) ) {
684 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
691 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
693 return WERR_UNKNOWN_LEVEL;
696 *total_entries = alloc_entries;
697 if (resume_handle_p) {
699 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
701 *resume_handle_p = num_entries;
710 /*******************************************************************
711 fill in a sess info level 0 structure.
712 ********************************************************************/
714 static WERROR init_srv_sess_info_0(pipes_struct *p,
715 struct srvsvc_NetSessCtr0 *ctr0,
716 uint32_t *resume_handle_p,
717 uint32_t *total_entries)
719 struct sessionid *session_list;
720 uint32_t num_entries = 0;
721 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
722 *total_entries = list_sessions(p->mem_ctx, &session_list);
724 DEBUG(5,("init_srv_sess_info_0\n"));
727 if (resume_handle_p) {
728 *resume_handle_p = 0;
733 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
735 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
737 struct srvsvc_NetSessInfo0,
739 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
741 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
742 session_list[resume_handle].remote_machine);
746 ctr0->count = num_entries;
748 if (resume_handle_p) {
749 if (*resume_handle_p >= *total_entries) {
750 *resume_handle_p = 0;
752 *resume_handle_p = resume_handle;
759 /*******************************************************************
760 ********************************************************************/
762 static void sess_file_fn( const struct share_mode_entry *e,
763 const char *sharepath, const char *fname,
766 struct sess_file_count *sess = (struct sess_file_count *)data;
768 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
775 /*******************************************************************
776 ********************************************************************/
778 static int net_count_files( uid_t uid, struct server_id pid )
780 struct sess_file_count s_file_cnt;
782 s_file_cnt.count = 0;
783 s_file_cnt.uid = uid;
784 s_file_cnt.pid = pid;
786 share_mode_forall( sess_file_fn, &s_file_cnt );
788 return s_file_cnt.count;
791 /*******************************************************************
792 fill in a sess info level 1 structure.
793 ********************************************************************/
795 static WERROR init_srv_sess_info_1(pipes_struct *p,
796 struct srvsvc_NetSessCtr1 *ctr1,
797 uint32_t *resume_handle_p,
798 uint32_t *total_entries)
800 struct sessionid *session_list;
801 uint32_t num_entries = 0;
802 time_t now = time(NULL);
803 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
808 if (resume_handle_p) {
809 *resume_handle_p = 0;
814 *total_entries = list_sessions(p->mem_ctx, &session_list);
816 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
819 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
823 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
824 session_list[resume_handle].username));
828 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
829 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
830 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
832 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
834 struct srvsvc_NetSessInfo1,
836 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
838 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
839 session_list[resume_handle].remote_machine,
840 session_list[resume_handle].username,
848 ctr1->count = num_entries;
850 if (resume_handle_p) {
851 if (*resume_handle_p >= *total_entries) {
852 *resume_handle_p = 0;
854 *resume_handle_p = resume_handle;
861 /*******************************************************************
862 fill in a conn info level 0 structure.
863 ********************************************************************/
865 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
866 uint32_t *resume_handle_p,
867 uint32_t *total_entries)
869 uint32_t num_entries = 0;
870 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
872 DEBUG(5,("init_srv_conn_info_0\n"));
875 if (resume_handle_p) {
876 *resume_handle_p = 0;
885 for (; resume_handle < *total_entries && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
887 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
889 struct srvsvc_NetConnInfo0,
895 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
898 /* move on to creating next connection */
902 ctr0->count = num_entries;
903 *total_entries = num_entries;
905 if (resume_handle_p) {
906 if (*resume_handle_p >= *total_entries) {
907 *resume_handle_p = 0;
909 *resume_handle_p = resume_handle;
916 /*******************************************************************
917 fill in a conn info level 1 structure.
918 ********************************************************************/
920 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
921 uint32_t *resume_handle_p,
922 uint32_t *total_entries)
924 uint32_t num_entries = 0;
925 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
927 DEBUG(5,("init_srv_conn_info_1\n"));
930 if (resume_handle_p) {
931 *resume_handle_p = 0;
940 for (; (resume_handle < *total_entries) && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
942 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
944 struct srvsvc_NetConnInfo1,
950 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
959 /* move on to creating next connection */
963 ctr1->count = num_entries;
964 *total_entries = num_entries;
966 if (resume_handle_p) {
967 if (*resume_handle_p >= *total_entries) {
968 *resume_handle_p = 0;
970 *resume_handle_p = resume_handle;
977 /*******************************************************************
979 *******************************************************************/
981 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
982 struct srvsvc_NetFileEnum *r)
984 TALLOC_CTX *ctx = NULL;
985 struct srvsvc_NetFileCtr3 *ctr3;
986 uint32_t resume_hnd = 0;
989 switch (r->in.info_ctr->level) {
993 return WERR_UNKNOWN_LEVEL;
997 ctr3 = r->in.info_ctr->ctr.ctr3;
999 werr = WERR_INVALID_PARAM;
1003 /* TODO -- Windows enumerates
1005 (c) open directories and files */
1007 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1008 if (!W_ERROR_IS_OK(werr)) {
1012 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1013 if (!W_ERROR_IS_OK(werr)) {
1017 *r->out.totalentries = ctr3->count;
1018 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1019 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1027 /*******************************************************************
1028 _srvsvc_NetSrvGetInfo
1029 ********************************************************************/
1031 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1032 struct srvsvc_NetSrvGetInfo *r)
1034 WERROR status = WERR_OK;
1036 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1038 if (!pipe_access_check(p)) {
1039 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1040 return WERR_ACCESS_DENIED;
1043 switch (r->in.level) {
1045 /* Technically level 102 should only be available to
1046 Administrators but there isn't anything super-secret
1047 here, as most of it is made up. */
1050 struct srvsvc_NetSrvInfo102 *info102;
1052 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1057 init_srvsvc_NetSrvInfo102(info102,
1060 lp_major_announce_version(),
1061 lp_minor_announce_version(),
1062 lp_default_server_announce(),
1063 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1064 0xffffffff, /* users */
1068 3000, /* announce delta */
1069 100000, /* licenses */
1070 "c:\\"); /* user path */
1071 r->out.info->info102 = info102;
1075 struct srvsvc_NetSrvInfo101 *info101;
1077 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1082 init_srvsvc_NetSrvInfo101(info101,
1085 lp_major_announce_version(),
1086 lp_minor_announce_version(),
1087 lp_default_server_announce(),
1088 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1089 r->out.info->info101 = info101;
1093 struct srvsvc_NetSrvInfo100 *info100;
1095 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1100 init_srvsvc_NetSrvInfo100(info100,
1103 r->out.info->info100 = info100;
1108 status = WERR_UNKNOWN_LEVEL;
1112 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1117 /*******************************************************************
1118 _srvsvc_NetSrvSetInfo
1119 ********************************************************************/
1121 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1122 struct srvsvc_NetSrvSetInfo *r)
1124 WERROR status = WERR_OK;
1126 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1128 /* Set up the net server set info structure. */
1130 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1135 /*******************************************************************
1137 ********************************************************************/
1139 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1140 struct srvsvc_NetConnEnum *r)
1144 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1146 switch (r->in.info_ctr->level) {
1148 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1149 r->in.resume_handle,
1150 r->out.totalentries);
1153 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1154 r->in.resume_handle,
1155 r->out.totalentries);
1158 return WERR_UNKNOWN_LEVEL;
1161 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1166 /*******************************************************************
1168 ********************************************************************/
1170 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1171 struct srvsvc_NetSessEnum *r)
1175 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1177 switch (r->in.info_ctr->level) {
1179 werr = init_srv_sess_info_0(p,
1180 r->in.info_ctr->ctr.ctr0,
1181 r->in.resume_handle,
1182 r->out.totalentries);
1185 werr = init_srv_sess_info_1(p,
1186 r->in.info_ctr->ctr.ctr1,
1187 r->in.resume_handle,
1188 r->out.totalentries);
1191 return WERR_UNKNOWN_LEVEL;
1194 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1199 /*******************************************************************
1201 ********************************************************************/
1203 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1204 struct srvsvc_NetSessDel *r)
1206 struct sessionid *session_list;
1207 struct current_user user;
1208 int num_sessions, snum;
1209 const char *username;
1210 const char *machine;
1211 bool not_root = False;
1214 username = r->in.user;
1215 machine = r->in.client;
1217 /* strip leading backslashes if any */
1218 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1222 num_sessions = list_sessions(p->mem_ctx, &session_list);
1224 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1226 werr = WERR_ACCESS_DENIED;
1228 get_current_user(&user, p);
1230 /* fail out now if you are not root or not a domain admin */
1232 if ((user.ut.uid != sec_initial_uid()) &&
1233 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1238 for (snum = 0; snum < num_sessions; snum++) {
1240 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1241 strequal(session_list[snum].remote_machine, machine)) {
1245 if (user.ut.uid != sec_initial_uid()) {
1250 ntstat = messaging_send(smbd_messaging_context(),
1251 session_list[snum].pid,
1252 MSG_SHUTDOWN, &data_blob_null);
1254 if (NT_STATUS_IS_OK(ntstat))
1262 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1269 /*******************************************************************
1270 _srvsvc_NetShareEnumAll
1271 ********************************************************************/
1273 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1274 struct srvsvc_NetShareEnumAll *r)
1278 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1280 if (!pipe_access_check(p)) {
1281 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1282 return WERR_ACCESS_DENIED;
1285 /* Create the list of shares for the response. */
1286 werr = init_srv_share_info_ctr(p,
1288 r->in.resume_handle,
1289 r->out.totalentries,
1292 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1297 /*******************************************************************
1298 _srvsvc_NetShareEnum
1299 ********************************************************************/
1301 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1302 struct srvsvc_NetShareEnum *r)
1306 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1308 if (!pipe_access_check(p)) {
1309 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1310 return WERR_ACCESS_DENIED;
1313 /* Create the list of shares for the response. */
1314 werr = init_srv_share_info_ctr(p,
1316 r->in.resume_handle,
1317 r->out.totalentries,
1320 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1325 /*******************************************************************
1326 _srvsvc_NetShareGetInfo
1327 ********************************************************************/
1329 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1330 struct srvsvc_NetShareGetInfo *r)
1332 WERROR status = WERR_OK;
1335 union srvsvc_NetShareInfo *info = r->out.info;
1337 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1339 fstrcpy(share_name, r->in.share_name);
1341 snum = find_service(share_name);
1343 return WERR_INVALID_NAME;
1346 switch (r->in.level) {
1348 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1349 W_ERROR_HAVE_NO_MEMORY(info->info0);
1350 init_srv_share_info_0(p, info->info0, snum);
1353 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1354 W_ERROR_HAVE_NO_MEMORY(info->info1);
1355 init_srv_share_info_1(p, info->info1, snum);
1358 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1359 W_ERROR_HAVE_NO_MEMORY(info->info2);
1360 init_srv_share_info_2(p, info->info2, snum);
1363 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1364 W_ERROR_HAVE_NO_MEMORY(info->info501);
1365 init_srv_share_info_501(p, info->info501, snum);
1368 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1369 W_ERROR_HAVE_NO_MEMORY(info->info502);
1370 init_srv_share_info_502(p, info->info502, snum);
1373 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1374 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1375 init_srv_share_info_1004(p, info->info1004, snum);
1378 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1379 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1380 init_srv_share_info_1005(p, info->info1005, snum);
1383 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1384 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1385 init_srv_share_info_1006(p, info->info1006, snum);
1388 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1389 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1390 init_srv_share_info_1007(p, info->info1007, snum);
1393 init_srv_share_info_1501(p, info->info1501, snum);
1396 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1398 status = WERR_UNKNOWN_LEVEL;
1402 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1407 /*******************************************************************
1408 Check a given DOS pathname is valid for a share.
1409 ********************************************************************/
1411 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1415 if (!dos_pathname) {
1419 ptr = talloc_strdup(ctx, dos_pathname);
1423 /* Convert any '\' paths to '/' */
1425 ptr = unix_clean_name(ctx, ptr);
1430 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1431 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1434 /* Only absolute paths allowed. */
1441 /*******************************************************************
1442 _srvsvc_NetShareSetInfo. Modify share details.
1443 ********************************************************************/
1445 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1446 struct srvsvc_NetShareSetInfo *r)
1448 struct current_user user;
1449 char *command = NULL;
1450 char *share_name = NULL;
1451 char *comment = NULL;
1452 const char *pathname = NULL;
1457 SEC_DESC *psd = NULL;
1458 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1459 bool is_disk_op = False;
1460 int max_connections = 0;
1461 TALLOC_CTX *ctx = p->mem_ctx;
1462 union srvsvc_NetShareInfo *info = r->in.info;
1464 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1466 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1471 *r->out.parm_error = 0;
1473 if ( strequal(share_name,"IPC$")
1474 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1475 || strequal(share_name,"global") )
1477 return WERR_ACCESS_DENIED;
1480 snum = find_service(share_name);
1482 /* Does this share exist ? */
1484 return WERR_NET_NAME_NOT_FOUND;
1486 /* No change to printer shares. */
1487 if (lp_print_ok(snum))
1488 return WERR_ACCESS_DENIED;
1490 get_current_user(&user,p);
1492 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1494 /* fail out now if you are not root and not a disk op */
1496 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1497 return WERR_ACCESS_DENIED;
1499 switch (r->in.level) {
1501 pathname = talloc_strdup(ctx, lp_pathname(snum));
1502 comment = talloc_strdup(ctx, info->info2->comment);
1503 type = info->info2->type;
1507 comment = talloc_strdup(ctx, info->info2->comment);
1508 pathname = info->info2->path;
1509 type = info->info2->type;
1510 max_connections = (info->info2->max_users == 0xffffffff) ?
1511 0 : info->info2->max_users;
1515 /* not supported on set but here for completeness */
1517 comment = talloc_strdup(ctx, info->info501->comment);
1518 type = info->info501->type;
1523 comment = talloc_strdup(ctx, info->info502->comment);
1524 pathname = info->info502->path;
1525 type = info->info502->type;
1526 psd = info->info502->sd;
1527 map_generic_share_sd_bits(psd);
1530 pathname = talloc_strdup(ctx, lp_pathname(snum));
1531 comment = talloc_strdup(ctx, info->info1004->comment);
1532 type = STYPE_DISKTREE;
1535 /* XP re-sets the csc policy even if it wasn't changed by the
1536 user, so we must compare it to see if it's what is set in
1537 smb.conf, so that we can contine other ops like setting
1539 if (((info->info1005->dfs_flags &
1540 SHARE_1005_CSC_POLICY_MASK) >>
1541 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1544 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1545 return WERR_ACCESS_DENIED;
1549 return WERR_ACCESS_DENIED;
1551 pathname = talloc_strdup(ctx, lp_pathname(snum));
1552 comment = talloc_strdup(ctx, lp_comment(snum));
1553 psd = info->info1501->sd;
1554 map_generic_share_sd_bits(psd);
1555 type = STYPE_DISKTREE;
1558 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1560 return WERR_UNKNOWN_LEVEL;
1563 /* We can only modify disk shares. */
1564 if (type != STYPE_DISKTREE)
1565 return WERR_ACCESS_DENIED;
1567 /* Check if the pathname is valid. */
1568 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1569 return WERR_OBJECT_PATH_INVALID;
1571 /* Ensure share name, pathname and comment don't contain '"' characters. */
1572 string_replace(share_name, '"', ' ');
1573 string_replace(path, '"', ' ');
1575 string_replace(comment, '"', ' ');
1578 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1579 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1581 /* Only call modify function if something changed. */
1583 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1584 || (lp_max_connections(snum) != max_connections)) {
1585 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1586 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1587 return WERR_ACCESS_DENIED;
1590 command = talloc_asprintf(p->mem_ctx,
1591 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1592 lp_change_share_cmd(),
1593 get_dyn_CONFIGFILE(),
1596 comment ? comment : "",
1602 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1604 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1609 if ( (ret = smbrun(command, NULL)) == 0 ) {
1610 /* Tell everyone we updated smb.conf. */
1611 message_send_all(smbd_messaging_context(),
1612 MSG_SMB_CONF_UPDATED, NULL, 0,
1619 /********* END SeDiskOperatorPrivilege BLOCK *********/
1621 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1624 TALLOC_FREE(command);
1627 return WERR_ACCESS_DENIED;
1629 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1633 /* Replace SD if changed. */
1638 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1640 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1641 if (!set_share_security(share_name, psd))
1642 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1647 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1652 /*******************************************************************
1653 _srvsvc_NetShareAdd.
1654 Call 'add_share_command "sharename" "pathname"
1655 "comment" "max connections = "
1656 ********************************************************************/
1658 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1659 struct srvsvc_NetShareAdd *r)
1661 struct current_user user;
1662 char *command = NULL;
1663 char *share_name = NULL;
1664 char *comment = NULL;
1665 char *pathname = NULL;
1670 SEC_DESC *psd = NULL;
1671 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1673 int max_connections = 0;
1674 TALLOC_CTX *ctx = p->mem_ctx;
1676 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1678 *r->out.parm_error = 0;
1680 get_current_user(&user,p);
1682 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1684 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1685 return WERR_ACCESS_DENIED;
1687 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1688 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1689 return WERR_ACCESS_DENIED;
1692 switch (r->in.level) {
1694 /* No path. Not enough info in a level 0 to do anything. */
1695 return WERR_ACCESS_DENIED;
1697 /* Not enough info in a level 1 to do anything. */
1698 return WERR_ACCESS_DENIED;
1700 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1701 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1702 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1703 max_connections = (r->in.info->info2->max_users == 0xffffffff) ?
1704 0 : r->in.info->info2->max_users;
1705 type = r->in.info->info2->type;
1708 /* No path. Not enough info in a level 501 to do anything. */
1709 return WERR_ACCESS_DENIED;
1711 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1712 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1713 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1714 max_connections = (r->in.info->info502->max_users == 0xffffffff) ?
1715 0 : r->in.info->info502->max_users;
1716 type = r->in.info->info502->type;
1717 psd = r->in.info->info502->sd;
1718 map_generic_share_sd_bits(psd);
1721 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1727 return WERR_ACCESS_DENIED;
1729 /* DFS only level. */
1730 return WERR_ACCESS_DENIED;
1732 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1734 return WERR_UNKNOWN_LEVEL;
1737 /* check for invalid share names */
1739 if (!share_name || !validate_net_name(share_name,
1740 INVALID_SHARENAME_CHARS,
1741 strlen(share_name))) {
1742 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1743 share_name ? share_name : ""));
1744 return WERR_INVALID_NAME;
1747 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1748 || (lp_enable_asu_support() &&
1749 strequal(share_name,"ADMIN$"))) {
1750 return WERR_ACCESS_DENIED;
1753 snum = find_service(share_name);
1755 /* Share already exists. */
1757 return WERR_ALREADY_EXISTS;
1760 /* We can only add disk shares. */
1761 if (type != STYPE_DISKTREE) {
1762 return WERR_ACCESS_DENIED;
1765 /* Check if the pathname is valid. */
1766 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1767 return WERR_OBJECT_PATH_INVALID;
1770 /* Ensure share name, pathname and comment don't contain '"' characters. */
1771 string_replace(share_name, '"', ' ');
1772 string_replace(path, '"', ' ');
1774 string_replace(comment, '"', ' ');
1777 command = talloc_asprintf(ctx,
1778 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1780 get_dyn_CONFIGFILE(),
1783 comment ? comment : "",
1789 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1791 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1796 /* FIXME: use libnetconf here - gd */
1798 if ( (ret = smbrun(command, NULL)) == 0 ) {
1799 /* Tell everyone we updated smb.conf. */
1800 message_send_all(smbd_messaging_context(),
1801 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1807 /********* END SeDiskOperatorPrivilege BLOCK *********/
1809 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1812 TALLOC_FREE(command);
1815 return WERR_ACCESS_DENIED;
1818 if (!set_share_security(share_name, psd)) {
1819 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1825 * We don't call reload_services() here, the message will
1826 * cause this to be done before the next packet is read
1827 * from the client. JRA.
1830 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1835 /*******************************************************************
1837 Call "delete share command" with the share name as
1839 ********************************************************************/
1841 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1842 struct srvsvc_NetShareDel *r)
1844 struct current_user user;
1845 char *command = NULL;
1846 char *share_name = NULL;
1849 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1851 struct share_params *params;
1852 TALLOC_CTX *ctx = p->mem_ctx;
1854 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1856 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1858 return WERR_NET_NAME_NOT_FOUND;
1860 if ( strequal(share_name,"IPC$")
1861 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1862 || strequal(share_name,"global") )
1864 return WERR_ACCESS_DENIED;
1867 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1868 return WERR_NO_SUCH_SHARE;
1871 snum = find_service(share_name);
1873 /* No change to printer shares. */
1874 if (lp_print_ok(snum))
1875 return WERR_ACCESS_DENIED;
1877 get_current_user(&user,p);
1879 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1881 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1882 return WERR_ACCESS_DENIED;
1884 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1885 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1886 return WERR_ACCESS_DENIED;
1889 command = talloc_asprintf(ctx,
1891 lp_delete_share_cmd(),
1892 get_dyn_CONFIGFILE(),
1893 lp_servicename(snum));
1898 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1900 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1905 if ( (ret = smbrun(command, NULL)) == 0 ) {
1906 /* Tell everyone we updated smb.conf. */
1907 message_send_all(smbd_messaging_context(),
1908 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1914 /********* END SeDiskOperatorPrivilege BLOCK *********/
1916 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1919 return WERR_ACCESS_DENIED;
1921 /* Delete the SD in the database. */
1922 delete_share_security(lp_servicename(params->service));
1924 lp_killservice(params->service);
1929 /*******************************************************************
1930 _srvsvc_NetShareDelSticky
1931 ********************************************************************/
1933 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1934 struct srvsvc_NetShareDelSticky *r)
1936 struct srvsvc_NetShareDel q;
1938 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1940 q.in.server_unc = r->in.server_unc;
1941 q.in.share_name = r->in.share_name;
1942 q.in.reserved = r->in.reserved;
1944 return _srvsvc_NetShareDel(p, &q);
1947 /*******************************************************************
1948 _srvsvc_NetRemoteTOD
1949 ********************************************************************/
1951 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1952 struct srvsvc_NetRemoteTOD *r)
1954 struct srvsvc_NetRemoteTODInfo *tod;
1956 time_t unixdate = time(NULL);
1958 /* We do this call first as if we do it *after* the gmtime call
1959 it overwrites the pointed-to values. JRA */
1961 uint32 zone = get_time_zone(unixdate)/60;
1963 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1965 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1970 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1972 t = gmtime(&unixdate);
1975 init_srvsvc_NetRemoteTODInfo(tod,
1989 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1994 /***********************************************************************************
1995 _srvsvc_NetGetFileSecurity
1996 Win9x NT tools get security descriptor.
1997 ***********************************************************************************/
1999 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2000 struct srvsvc_NetGetFileSecurity *r)
2002 SEC_DESC *psd = NULL;
2005 char *filename_in = NULL;
2006 char *filename = NULL;
2007 char *qualname = NULL;
2011 struct current_user user;
2012 connection_struct *conn = NULL;
2013 bool became_user = False;
2014 TALLOC_CTX *ctx = p->mem_ctx;
2015 struct sec_desc_buf *sd_buf;
2021 qualname = talloc_strdup(ctx, r->in.share);
2023 werr = WERR_ACCESS_DENIED;
2027 /* Null password is ok - we are already an authenticated user... */
2028 null_pw = data_blob_null;
2030 get_current_user(&user, p);
2033 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2037 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2039 werr = ntstatus_to_werror(nt_status);
2043 if (!become_user(conn, conn->vuid)) {
2044 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2045 werr = WERR_ACCESS_DENIED;
2050 filename_in = talloc_strdup(ctx, r->in.file);
2052 werr = WERR_ACCESS_DENIED;
2056 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2057 if (!NT_STATUS_IS_OK(nt_status)) {
2058 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2060 werr = WERR_ACCESS_DENIED;
2064 nt_status = check_name(conn, filename);
2065 if (!NT_STATUS_IS_OK(nt_status)) {
2066 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2068 werr = WERR_ACCESS_DENIED;
2072 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2073 (OWNER_SECURITY_INFORMATION
2074 |GROUP_SECURITY_INFORMATION
2075 |DACL_SECURITY_INFORMATION), &psd);
2077 if (!NT_STATUS_IS_OK(nt_status)) {
2078 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2080 werr = ntstatus_to_werror(nt_status);
2084 sd_size = ndr_size_security_descriptor(psd, 0);
2086 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2092 sd_buf->sd_size = sd_size;
2095 *r->out.sd_buf = sd_buf;
2097 psd->dacl->revision = NT4_ACL_REVISION;
2100 close_cnum(conn, user.vuid);
2109 close_cnum(conn, user.vuid);
2114 /***********************************************************************************
2115 _srvsvc_NetSetFileSecurity
2116 Win9x NT tools set security descriptor.
2117 ***********************************************************************************/
2119 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2120 struct srvsvc_NetSetFileSecurity *r)
2122 char *filename_in = NULL;
2123 char *filename = NULL;
2124 char *qualname = NULL;
2126 files_struct *fsp = NULL;
2130 struct current_user user;
2131 connection_struct *conn = NULL;
2132 bool became_user = False;
2133 TALLOC_CTX *ctx = p->mem_ctx;
2139 qualname = talloc_strdup(ctx, r->in.share);
2141 werr = WERR_ACCESS_DENIED;
2145 /* Null password is ok - we are already an authenticated user... */
2146 null_pw = data_blob_null;
2148 get_current_user(&user, p);
2151 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2155 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2156 werr = ntstatus_to_werror(nt_status);
2160 if (!become_user(conn, conn->vuid)) {
2161 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2162 werr = WERR_ACCESS_DENIED;
2167 filename_in = talloc_strdup(ctx, r->in.file);
2169 werr = WERR_ACCESS_DENIED;
2173 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2174 if (!NT_STATUS_IS_OK(nt_status)) {
2175 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2176 werr = WERR_ACCESS_DENIED;
2180 nt_status = check_name(conn, filename);
2181 if (!NT_STATUS_IS_OK(nt_status)) {
2182 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2183 werr = WERR_ACCESS_DENIED;
2187 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2189 if ( !NT_STATUS_IS_OK(nt_status) ) {
2190 /* Perhaps it is a directory */
2191 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2192 nt_status = open_directory(conn, NULL, filename, &st,
2193 FILE_READ_ATTRIBUTES,
2194 FILE_SHARE_READ|FILE_SHARE_WRITE,
2197 FILE_ATTRIBUTE_DIRECTORY,
2200 if ( !NT_STATUS_IS_OK(nt_status) ) {
2201 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2202 werr = ntstatus_to_werror(nt_status);
2207 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2208 r->in.securityinformation,
2211 if (!NT_STATUS_IS_OK(nt_status) ) {
2212 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2213 werr = WERR_ACCESS_DENIED;
2217 close_file(fsp, NORMAL_CLOSE);
2219 close_cnum(conn, user.vuid);
2225 close_file(fsp, NORMAL_CLOSE);
2233 close_cnum(conn, user.vuid);
2239 /***********************************************************************************
2240 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2241 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2242 These disks would the disks listed by this function.
2243 Users could then create shares relative to these disks. Watch out for moving these disks around.
2244 "Nigel Williams" <nigel@veritas.com>.
2245 ***********************************************************************************/
2247 static const char *server_disks[] = {"C:"};
2249 static uint32 get_server_disk_count(void)
2251 return sizeof(server_disks)/sizeof(server_disks[0]);
2254 static uint32 init_server_disk_enum(uint32 *resume)
2256 uint32 server_disk_count = get_server_disk_count();
2258 /*resume can be an offset into the list for now*/
2260 if(*resume & 0x80000000)
2263 if(*resume > server_disk_count)
2264 *resume = server_disk_count;
2266 return server_disk_count - *resume;
2269 static const char *next_server_disk_enum(uint32 *resume)
2273 if(init_server_disk_enum(resume) == 0)
2276 disk = server_disks[*resume];
2280 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2285 /********************************************************************
2287 ********************************************************************/
2289 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2290 struct srvsvc_NetDiskEnum *r)
2293 const char *disk_name;
2294 TALLOC_CTX *ctx = p->mem_ctx;
2296 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2300 *r->out.totalentries = init_server_disk_enum(&resume);
2302 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2303 MAX_SERVER_DISK_ENTRIES);
2304 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2306 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2308 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2310 r->out.info->count++;
2312 /*copy disk name into a unicode string*/
2314 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2315 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2318 /* add a terminating null string. Is this there if there is more data to come? */
2320 r->out.info->count++;
2322 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2323 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2325 if (r->out.resume_handle) {
2326 *r->out.resume_handle = resume;
2332 /********************************************************************
2333 _srvsvc_NetNameValidate
2334 ********************************************************************/
2336 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2337 struct srvsvc_NetNameValidate *r)
2339 switch (r->in.name_type) {
2341 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2342 strlen_m(r->in.name)))
2344 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2346 return WERR_INVALID_NAME;
2351 return WERR_UNKNOWN_LEVEL;
2357 /********************************************************************
2358 ********************************************************************/
2360 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2362 return WERR_ACCESS_DENIED;
2366 /********************************************************************
2367 ********************************************************************/
2369 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2371 p->rng_fault_state = True;
2372 return WERR_NOT_SUPPORTED;
2375 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2377 p->rng_fault_state = True;
2378 return WERR_NOT_SUPPORTED;
2381 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2383 p->rng_fault_state = True;
2384 return WERR_NOT_SUPPORTED;
2387 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2389 p->rng_fault_state = True;
2390 return WERR_NOT_SUPPORTED;
2393 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2395 p->rng_fault_state = True;
2396 return WERR_NOT_SUPPORTED;
2399 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2401 p->rng_fault_state = True;
2402 return WERR_NOT_SUPPORTED;
2405 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2407 p->rng_fault_state = True;
2408 return WERR_NOT_SUPPORTED;
2411 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2413 p->rng_fault_state = True;
2414 return WERR_NOT_SUPPORTED;
2417 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2419 p->rng_fault_state = True;
2420 return WERR_NOT_SUPPORTED;
2423 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2425 p->rng_fault_state = True;
2426 return WERR_NOT_SUPPORTED;
2429 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2431 p->rng_fault_state = True;
2432 return WERR_NOT_SUPPORTED;
2435 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2437 p->rng_fault_state = True;
2438 return WERR_NOT_SUPPORTED;
2441 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2443 p->rng_fault_state = True;
2444 return WERR_NOT_SUPPORTED;
2447 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2449 p->rng_fault_state = True;
2450 return WERR_NOT_SUPPORTED;
2453 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2455 p->rng_fault_state = True;
2456 return WERR_NOT_SUPPORTED;
2459 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2461 p->rng_fault_state = True;
2462 return WERR_NOT_SUPPORTED;
2465 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2467 p->rng_fault_state = True;
2468 return WERR_NOT_SUPPORTED;
2471 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2473 p->rng_fault_state = True;
2474 return WERR_NOT_SUPPORTED;
2477 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2479 p->rng_fault_state = True;
2480 return WERR_NOT_SUPPORTED;
2483 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2485 p->rng_fault_state = True;
2486 return WERR_NOT_SUPPORTED;
2489 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2491 p->rng_fault_state = True;
2492 return WERR_NOT_SUPPORTED;
2495 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2497 p->rng_fault_state = True;
2498 return WERR_NOT_SUPPORTED;
2501 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2503 p->rng_fault_state = True;
2504 return WERR_NOT_SUPPORTED;
2507 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2509 p->rng_fault_state = True;
2510 return WERR_NOT_SUPPORTED;
2513 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2515 p->rng_fault_state = True;
2516 return WERR_NOT_SUPPORTED;
2519 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2521 p->rng_fault_state = True;
2522 return WERR_NOT_SUPPORTED;
2525 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2527 p->rng_fault_state = True;
2528 return WERR_NOT_SUPPORTED;
2531 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2533 p->rng_fault_state = True;
2534 return WERR_NOT_SUPPORTED;
2537 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2539 p->rng_fault_state = True;
2540 return WERR_NOT_SUPPORTED;
2543 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2545 p->rng_fault_state = True;
2546 return WERR_NOT_SUPPORTED;
2549 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2555 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2557 p->rng_fault_state = True;
2558 return WERR_NOT_SUPPORTED;
2561 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2563 p->rng_fault_state = True;
2564 return WERR_NOT_SUPPORTED;
2567 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2569 p->rng_fault_state = True;
2570 return WERR_NOT_SUPPORTED;
2573 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2575 p->rng_fault_state = True;
2576 return WERR_NOT_SUPPORTED;