s3:vfs: add create tags to SMB_VFS_CREATEFILE
[Samba.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob7e422724e5c4dd266f3437548151a08690ff6f02
1 /*
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) Guenther Deschner 2008.
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. */
26 #include "includes.h"
27 #include "system/passwd.h"
28 #include "ntdomain.h"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
34 #include "session.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
38 #include "auth.h"
39 #include "messages.h"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping;
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count {
52 TALLOC_CTX *ctx;
53 const char *username;
54 struct srvsvc_NetFileCtr3 *ctr3;
57 struct sess_file_info {
58 struct srvsvc_NetSessCtr1 *ctr;
59 struct sessionid *session_list;
60 uint32_t resume_handle;
61 uint32_t num_entries;
64 struct share_file_stat {
65 struct srvsvc_NetConnInfo1 *netconn_arr;
66 struct server_id *svrid_arr;
67 const char *in_sharepath;
68 uint32_t resp_entries;
69 uint32_t total_entries;
72 struct share_conn_stat {
73 TALLOC_CTX *ctx;
74 const char *sharename;
75 struct server_id *svrid_arr;
76 int count;
79 /*******************************************************************
80 ********************************************************************/
82 static int enum_file_fn(const struct share_mode_entry *e,
83 const char *sharepath, const char *fname,
84 void *private_data)
86 struct file_enum_count *fenum =
87 (struct file_enum_count *)private_data;
89 struct srvsvc_NetFileInfo3 *f;
90 int i = fenum->ctr3->count;
91 files_struct fsp;
92 struct byte_range_lock *brl;
93 int num_locks = 0;
94 char *fullpath = NULL;
95 uint32 permissions;
96 const char *username;
98 /* If the pid was not found delete the entry from connections.tdb */
100 if ( !process_exists(e->pid) ) {
101 return 0;
104 username = uidtoname(e->uid);
106 if ((fenum->username != NULL)
107 && !strequal(username, fenum->username)) {
108 return 0;
111 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
112 struct srvsvc_NetFileInfo3, i+1);
113 if ( !f ) {
114 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
115 return 0;
117 fenum->ctr3->array = f;
119 /* need to count the number of locks on a file */
121 ZERO_STRUCT( fsp );
122 fsp.file_id = e->id;
124 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
125 num_locks = brl_num_locks(brl);
126 TALLOC_FREE(brl);
129 if ( strcmp( fname, "." ) == 0 ) {
130 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
131 } else {
132 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
133 sharepath, fname );
135 if (!fullpath) {
136 return 0;
138 string_replace( fullpath, '/', '\\' );
140 /* mask out create (what ever that is) */
141 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
143 /* now fill in the srvsvc_NetFileInfo3 struct */
145 fenum->ctr3->array[i].fid =
146 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
147 fenum->ctr3->array[i].permissions = permissions;
148 fenum->ctr3->array[i].num_locks = num_locks;
149 fenum->ctr3->array[i].path = fullpath;
150 fenum->ctr3->array[i].user = username;
152 fenum->ctr3->count++;
154 return 0;
157 /*******************************************************************
158 ********************************************************************/
160 static WERROR net_enum_files(TALLOC_CTX *ctx,
161 const char *username,
162 struct srvsvc_NetFileCtr3 **ctr3,
163 uint32_t resume)
165 struct file_enum_count f_enum_cnt;
167 f_enum_cnt.ctx = ctx;
168 f_enum_cnt.username = username;
169 f_enum_cnt.ctr3 = *ctr3;
171 share_entry_forall( enum_file_fn, (void *)&f_enum_cnt );
173 *ctr3 = f_enum_cnt.ctr3;
175 return WERR_OK;
178 /*******************************************************************
179 Utility function to get the 'type' of a share from an snum.
180 ********************************************************************/
181 static enum srvsvc_ShareType get_share_type(int snum)
183 /* work out the share type */
184 enum srvsvc_ShareType type = STYPE_DISKTREE;
186 if (lp_printable(snum)) {
187 type = lp_administrative_share(snum)
188 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
190 if (strequal(lp_fstype(snum), "IPC")) {
191 type = lp_administrative_share(snum)
192 ? STYPE_IPC_HIDDEN : STYPE_IPC;
194 return type;
197 /*******************************************************************
198 Fill in a share info level 0 structure.
199 ********************************************************************/
201 static void init_srv_share_info_0(struct pipes_struct *p,
202 struct srvsvc_NetShareInfo0 *r, int snum)
204 r->name = lp_servicename(talloc_tos(), snum);
207 /*******************************************************************
208 Fill in a share info level 1 structure.
209 ********************************************************************/
211 static void init_srv_share_info_1(struct pipes_struct *p,
212 struct srvsvc_NetShareInfo1 *r,
213 int snum)
215 char *net_name = lp_servicename(talloc_tos(), snum);
216 char *remark = lp_comment(p->mem_ctx, snum);
218 if (remark) {
219 remark = talloc_sub_advanced(
220 p->mem_ctx, lp_servicename(talloc_tos(), snum),
221 get_current_username(), lp_path(talloc_tos(), snum),
222 p->session_info->unix_token->uid, get_current_username(),
223 "", remark);
226 r->name = net_name;
227 r->type = get_share_type(snum);
228 r->comment = remark ? remark : "";
231 /*******************************************************************
232 Fill in a share info level 2 structure.
233 ********************************************************************/
235 static void init_srv_share_info_2(struct pipes_struct *p,
236 struct srvsvc_NetShareInfo2 *r,
237 int snum)
239 char *remark = NULL;
240 char *path = NULL;
241 int max_connections = lp_max_connections(snum);
242 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
243 char *net_name = lp_servicename(talloc_tos(), snum);
245 remark = lp_comment(p->mem_ctx, snum);
246 if (remark) {
247 remark = talloc_sub_advanced(
248 p->mem_ctx, lp_servicename(talloc_tos(), snum),
249 get_current_username(), lp_path(talloc_tos(), snum),
250 p->session_info->unix_token->uid, get_current_username(),
251 "", remark);
253 path = talloc_asprintf(p->mem_ctx,
254 "C:%s", lp_path(talloc_tos(), snum));
256 if (path) {
258 * Change / to \\ so that win2k will see it as a valid path.
259 * This was added to enable use of browsing in win2k add
260 * share dialog.
263 string_replace(path, '/', '\\');
266 r->name = net_name;
267 r->type = get_share_type(snum);
268 r->comment = remark ? remark : "";
269 r->permissions = 0;
270 r->max_users = max_uses;
271 r->current_users = 0; /* computed later */
272 r->path = path ? path : "";
273 r->password = "";
276 /*******************************************************************
277 Map any generic bits to file specific bits.
278 ********************************************************************/
280 static void map_generic_share_sd_bits(struct security_descriptor *psd)
282 int i;
283 struct security_acl *ps_dacl = NULL;
285 if (!psd)
286 return;
288 ps_dacl = psd->dacl;
289 if (!ps_dacl)
290 return;
292 for (i = 0; i < ps_dacl->num_aces; i++) {
293 struct security_ace *psa = &ps_dacl->aces[i];
294 uint32 orig_mask = psa->access_mask;
296 se_map_generic(&psa->access_mask, &file_generic_mapping);
297 psa->access_mask |= orig_mask;
301 /*******************************************************************
302 Fill in a share info level 501 structure.
303 ********************************************************************/
305 static void init_srv_share_info_501(struct pipes_struct *p,
306 struct srvsvc_NetShareInfo501 *r, int snum)
308 const char *net_name = lp_servicename(talloc_tos(), snum);
309 char *remark = lp_comment(p->mem_ctx, snum);
311 if (remark) {
312 remark = talloc_sub_advanced(
313 p->mem_ctx, lp_servicename(talloc_tos(), snum),
314 get_current_username(), lp_path(talloc_tos(), snum),
315 p->session_info->unix_token->uid, get_current_username(),
316 "", remark);
319 r->name = net_name;
320 r->type = get_share_type(snum);
321 r->comment = remark ? remark : "";
324 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
325 * level 1005.
327 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
330 /*******************************************************************
331 Fill in a share info level 502 structure.
332 ********************************************************************/
334 static void init_srv_share_info_502(struct pipes_struct *p,
335 struct srvsvc_NetShareInfo502 *r, int snum)
337 const char *net_name = lp_servicename(talloc_tos(), snum);
338 char *path = NULL;
339 struct security_descriptor *sd = NULL;
340 struct sec_desc_buf *sd_buf = NULL;
341 size_t sd_size = 0;
342 TALLOC_CTX *ctx = p->mem_ctx;
343 char *remark = lp_comment(ctx, snum);
345 if (remark) {
346 remark = talloc_sub_advanced(
347 p->mem_ctx, lp_servicename(talloc_tos(), snum),
348 get_current_username(), lp_path(talloc_tos(), snum),
349 p->session_info->unix_token->uid, get_current_username(),
350 "", remark);
352 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
353 if (path) {
355 * Change / to \\ so that win2k will see it as a valid path. This was added to
356 * enable use of browsing in win2k add share dialog.
358 string_replace(path, '/', '\\');
361 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
363 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
365 r->name = net_name;
366 r->type = get_share_type(snum);
367 r->comment = remark ? remark : "";
368 r->permissions = 0;
369 r->max_users = (uint32_t)-1;
370 r->current_users = 1; /* ??? */
371 r->path = path ? path : "";
372 r->password = "";
373 r->sd_buf = *sd_buf;
376 /***************************************************************************
377 Fill in a share info level 1004 structure.
378 ***************************************************************************/
380 static void init_srv_share_info_1004(struct pipes_struct *p,
381 struct srvsvc_NetShareInfo1004 *r,
382 int snum)
384 char *remark = lp_comment(p->mem_ctx, snum);
386 if (remark) {
387 remark = talloc_sub_advanced(
388 p->mem_ctx, lp_servicename(talloc_tos(), snum),
389 get_current_username(), lp_path(talloc_tos(), snum),
390 p->session_info->unix_token->uid, get_current_username(),
391 "", remark);
394 r->comment = remark ? remark : "";
397 /***************************************************************************
398 Fill in a share info level 1005 structure.
399 ***************************************************************************/
401 static void init_srv_share_info_1005(struct pipes_struct *p,
402 struct srvsvc_NetShareInfo1005 *r,
403 int snum)
405 uint32_t dfs_flags = 0;
407 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
408 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
411 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
413 r->dfs_flags = dfs_flags;
416 /***************************************************************************
417 Fill in a share info level 1006 structure.
418 ***************************************************************************/
420 static void init_srv_share_info_1006(struct pipes_struct *p,
421 struct srvsvc_NetShareInfo1006 *r,
422 int snum)
424 r->max_users = (uint32_t)-1;
427 /***************************************************************************
428 Fill in a share info level 1007 structure.
429 ***************************************************************************/
431 static void init_srv_share_info_1007(struct pipes_struct *p,
432 struct srvsvc_NetShareInfo1007 *r,
433 int snum)
435 r->flags = 0;
436 r->alternate_directory_name = "";
439 /*******************************************************************
440 Fill in a share info level 1501 structure.
441 ********************************************************************/
443 static void init_srv_share_info_1501(struct pipes_struct *p,
444 struct sec_desc_buf **r,
445 int snum)
447 struct security_descriptor *sd;
448 struct sec_desc_buf *sd_buf = NULL;
449 size_t sd_size;
450 TALLOC_CTX *ctx = p->mem_ctx;
452 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
453 if (sd) {
454 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
457 *r = sd_buf;
460 /*******************************************************************
461 True if it ends in '$'.
462 ********************************************************************/
464 static bool is_hidden_share(int snum)
466 const char *net_name = lp_servicename(talloc_tos(), snum);
468 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
471 /*******************************************************************
472 Verify user is allowed to view share, access based enumeration
473 ********************************************************************/
474 static bool is_enumeration_allowed(struct pipes_struct *p,
475 int snum)
477 if (!lp_access_based_share_enum(snum))
478 return true;
480 return share_access_check(p->session_info->security_token,
481 lp_servicename(talloc_tos(), snum),
482 FILE_READ_DATA, NULL);
485 /****************************************************************************
486 Count an entry against the respective service.
487 ****************************************************************************/
489 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
491 union srvsvc_NetShareCtr *ctr = NULL;
492 struct srvsvc_NetShareInfo2 *info2 = NULL;
493 int share_entries = 0;
494 int i = 0;
496 ctr = (union srvsvc_NetShareCtr *) udp;
498 /* for level 2 */
499 share_entries = ctr->ctr2->count;
500 info2 = &ctr->ctr2->array[0];
502 for (i = 0; i < share_entries; i++, info2++) {
503 if (strequal(tcon->share_name, info2->name)) {
504 info2->current_users++;
505 break;
509 return 0;
512 /****************************************************************************
513 Count the entries belonging to all services in the connection db.
514 ****************************************************************************/
516 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
518 NTSTATUS status;
519 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
521 if (!NT_STATUS_IS_OK(status)) {
522 DEBUG(0,("count_connections_for_all_shares: traverse of "
523 "smbXsrv_tcon_global.tdb failed - %s\n",
524 nt_errstr(status)));
528 /*******************************************************************
529 Fill in a share info structure.
530 ********************************************************************/
532 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
533 struct srvsvc_NetShareInfoCtr *info_ctr,
534 uint32_t *resume_handle_p,
535 uint32_t *total_entries,
536 bool all_shares)
538 int num_entries = 0;
539 int alloc_entries = 0;
540 int num_services = 0;
541 int snum;
542 TALLOC_CTX *ctx = p->mem_ctx;
543 int i = 0;
544 int valid_share_count = 0;
545 bool *allowed = 0;
546 union srvsvc_NetShareCtr ctr;
547 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
549 DEBUG(5,("init_srv_share_info_ctr\n"));
551 /* Ensure all the usershares are loaded. */
552 become_root();
553 delete_and_reload_printers(server_event_context(), p->msg_ctx);
554 load_usershare_shares(NULL, connections_snum_used);
555 load_registry_shares();
556 num_services = lp_numservices();
557 unbecome_root();
559 allowed = talloc_zero_array(ctx, bool, num_services);
560 W_ERROR_HAVE_NO_MEMORY(allowed);
562 /* Count the number of entries. */
563 for (snum = 0; snum < num_services; snum++) {
564 if (lp_browseable(snum) && lp_snum_ok(snum) &&
565 is_enumeration_allowed(p, snum) &&
566 (all_shares || !is_hidden_share(snum)) ) {
567 DEBUG(10, ("counting service %s\n",
568 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
569 allowed[snum] = true;
570 num_entries++;
571 } else {
572 DEBUG(10, ("NOT counting service %s\n",
573 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
577 if (!num_entries || (resume_handle >= num_entries)) {
578 return WERR_OK;
581 /* Calculate alloc entries. */
582 alloc_entries = num_entries - resume_handle;
583 switch (info_ctr->level) {
584 case 0:
585 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
586 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
588 ctr.ctr0->count = alloc_entries;
589 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
590 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
592 for (snum = 0; snum < num_services; snum++) {
593 if (allowed[snum] &&
594 (resume_handle <= (i + valid_share_count++)) ) {
595 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
599 break;
601 case 1:
602 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
603 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
605 ctr.ctr1->count = alloc_entries;
606 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
607 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
609 for (snum = 0; snum < num_services; snum++) {
610 if (allowed[snum] &&
611 (resume_handle <= (i + valid_share_count++)) ) {
612 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
616 break;
618 case 2:
619 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
620 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
622 ctr.ctr2->count = alloc_entries;
623 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
624 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
626 for (snum = 0; snum < num_services; snum++) {
627 if (allowed[snum] &&
628 (resume_handle <= (i + valid_share_count++)) ) {
629 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
633 count_connections_for_all_shares(&ctr);
634 break;
636 case 501:
637 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
638 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
640 ctr.ctr501->count = alloc_entries;
641 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
642 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
644 for (snum = 0; snum < num_services; snum++) {
645 if (allowed[snum] &&
646 (resume_handle <= (i + valid_share_count++)) ) {
647 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
651 break;
653 case 502:
654 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
655 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
657 ctr.ctr502->count = alloc_entries;
658 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
659 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
661 for (snum = 0; snum < num_services; snum++) {
662 if (allowed[snum] &&
663 (resume_handle <= (i + valid_share_count++)) ) {
664 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
668 break;
670 case 1004:
671 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
672 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
674 ctr.ctr1004->count = alloc_entries;
675 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
676 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
678 for (snum = 0; snum < num_services; snum++) {
679 if (allowed[snum] &&
680 (resume_handle <= (i + valid_share_count++)) ) {
681 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
685 break;
687 case 1005:
688 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
689 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
691 ctr.ctr1005->count = alloc_entries;
692 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
693 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
695 for (snum = 0; snum < num_services; snum++) {
696 if (allowed[snum] &&
697 (resume_handle <= (i + valid_share_count++)) ) {
698 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
702 break;
704 case 1006:
705 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
706 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
708 ctr.ctr1006->count = alloc_entries;
709 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
710 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
712 for (snum = 0; snum < num_services; snum++) {
713 if (allowed[snum] &&
714 (resume_handle <= (i + valid_share_count++)) ) {
715 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
719 break;
721 case 1007:
722 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
723 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
725 ctr.ctr1007->count = alloc_entries;
726 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
727 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
729 for (snum = 0; snum < num_services; snum++) {
730 if (allowed[snum] &&
731 (resume_handle <= (i + valid_share_count++)) ) {
732 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
736 break;
738 case 1501:
739 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
740 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
742 ctr.ctr1501->count = alloc_entries;
743 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
744 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
746 for (snum = 0; snum < num_services; snum++) {
747 if (allowed[snum] &&
748 (resume_handle <= (i + valid_share_count++)) ) {
749 struct sec_desc_buf *sd_buf = NULL;
750 init_srv_share_info_1501(p, &sd_buf, snum);
751 ctr.ctr1501->array[i++] = *sd_buf;
755 break;
757 default:
758 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
759 info_ctr->level));
760 return WERR_UNKNOWN_LEVEL;
763 *total_entries = alloc_entries;
764 if (resume_handle_p) {
765 if (all_shares) {
766 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
767 } else {
768 *resume_handle_p = num_entries;
772 info_ctr->ctr = ctr;
774 return WERR_OK;
777 /*******************************************************************
778 fill in a sess info level 0 structure.
779 ********************************************************************/
781 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
782 struct srvsvc_NetSessCtr0 *ctr0,
783 uint32_t *resume_handle_p,
784 uint32_t *total_entries)
786 struct sessionid *session_list;
787 uint32_t num_entries = 0;
788 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
789 *total_entries = list_sessions(p->mem_ctx, &session_list);
791 DEBUG(5,("init_srv_sess_info_0\n"));
793 if (ctr0 == NULL) {
794 if (resume_handle_p) {
795 *resume_handle_p = 0;
797 return WERR_OK;
800 for (; resume_handle < *total_entries; resume_handle++) {
802 ctr0->array = talloc_realloc(p->mem_ctx,
803 ctr0->array,
804 struct srvsvc_NetSessInfo0,
805 num_entries+1);
806 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
808 ctr0->array[num_entries].client =
809 session_list[resume_handle].remote_machine;
811 num_entries++;
814 ctr0->count = num_entries;
816 if (resume_handle_p) {
817 if (*resume_handle_p >= *total_entries) {
818 *resume_handle_p = 0;
819 } else {
820 *resume_handle_p = resume_handle;
824 return WERR_OK;
827 /***********************************************************************
828 * find out the session on which this file is open and bump up its count
829 **********************************************************************/
831 static int count_sess_files_fn(const struct share_mode_entry *e,
832 const char *sharepath, const char *fname,
833 void *data)
835 struct sess_file_info *info = data;
836 uint32_t rh = info->resume_handle;
837 int i;
839 for (i=0; i < info->num_entries; i++) {
840 /* rh+info->num_entries is safe, as we've
841 ensured that:
842 *total_entries > resume_handle &&
843 info->num_entries = *total_entries - resume_handle;
844 inside init_srv_sess_info_1() below.
846 struct sessionid *sess = &info->session_list[rh + i];
847 if ((e->uid == sess->uid) &&
848 serverid_equal(&e->pid, &sess->pid)) {
850 info->ctr->array[i].num_open++;
851 return 0;
854 return 0;
857 /*******************************************************************
858 * count the num of open files on all sessions
859 *******************************************************************/
861 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
862 struct sessionid *session_list,
863 uint32_t resume_handle,
864 uint32_t num_entries)
866 struct sess_file_info s_file_info;
868 s_file_info.ctr = ctr1;
869 s_file_info.session_list = session_list;
870 s_file_info.resume_handle = resume_handle;
871 s_file_info.num_entries = num_entries;
873 share_entry_forall(count_sess_files_fn, &s_file_info);
876 /*******************************************************************
877 fill in a sess info level 1 structure.
878 ********************************************************************/
880 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
881 struct srvsvc_NetSessCtr1 *ctr1,
882 uint32_t *resume_handle_p,
883 uint32_t *total_entries)
885 struct sessionid *session_list;
886 uint32_t num_entries = 0;
887 time_t now = time(NULL);
888 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
890 ZERO_STRUCTP(ctr1);
892 if (ctr1 == NULL) {
893 if (resume_handle_p) {
894 *resume_handle_p = 0;
896 return WERR_OK;
899 *total_entries = list_sessions(p->mem_ctx, &session_list);
901 if (resume_handle >= *total_entries) {
902 if (resume_handle_p) {
903 *resume_handle_p = 0;
905 return WERR_OK;
908 /* We know num_entries must be positive, due to
909 the check resume_handle >= *total_entries above. */
911 num_entries = *total_entries - resume_handle;
913 ctr1->array = talloc_zero_array(p->mem_ctx,
914 struct srvsvc_NetSessInfo1,
915 num_entries);
917 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
919 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
920 uint32 connect_time;
921 bool guest;
923 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
924 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
926 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
927 ctr1->array[num_entries].user = session_list[resume_handle].username;
928 ctr1->array[num_entries].num_open = 0;/* computed later */
929 ctr1->array[num_entries].time = connect_time;
930 ctr1->array[num_entries].idle_time = 0;
931 ctr1->array[num_entries].user_flags = guest;
934 ctr1->count = num_entries;
936 /* count open files on all sessions in single tdb traversal */
937 net_count_files_for_all_sess(ctr1, session_list,
938 resume_handle_p ? *resume_handle_p : 0,
939 num_entries);
941 if (resume_handle_p) {
942 if (*resume_handle_p >= *total_entries) {
943 *resume_handle_p = 0;
944 } else {
945 *resume_handle_p = resume_handle;
949 return WERR_OK;
952 /*******************************************************************
953 find the share connection on which this open exists.
954 ********************************************************************/
956 static int share_file_fn(const struct share_mode_entry *e,
957 const char *sharepath, const char *fname,
958 void *data)
960 struct share_file_stat *sfs = data;
961 uint32_t i;
962 uint32_t offset = sfs->total_entries - sfs->resp_entries;
964 if (strequal(sharepath, sfs->in_sharepath)) {
965 for (i=0; i < sfs->resp_entries; i++) {
966 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
967 sfs->netconn_arr[i].num_open ++;
968 return 0;
972 return 0;
975 /*******************************************************************
976 count number of open files on given share connections.
977 ********************************************************************/
979 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
980 struct server_id *svrid_arr, char *sharepath,
981 uint32_t resp_entries, uint32_t total_entries)
983 struct share_file_stat sfs;
985 sfs.netconn_arr = arr;
986 sfs.svrid_arr = svrid_arr;
987 sfs.in_sharepath = sharepath;
988 sfs.resp_entries = resp_entries;
989 sfs.total_entries = total_entries;
991 share_entry_forall(share_file_fn, &sfs);
994 /****************************************************************************
995 process an entry from the connection db.
996 ****************************************************************************/
998 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
999 void *data)
1001 struct share_conn_stat *scs = data;
1003 if (!process_exists(tcon->server_id)) {
1004 return 0;
1007 if (strequal(tcon->share_name, scs->sharename)) {
1008 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1009 struct server_id,
1010 scs->count + 1);
1011 if (!scs->svrid_arr) {
1012 return 0;
1015 scs->svrid_arr[scs->count] = tcon->server_id;
1016 scs->count++;
1019 return 0;
1022 /****************************************************************************
1023 Count the connections to a share. Build an array of serverid's owning these
1024 connections.
1025 ****************************************************************************/
1027 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1028 struct server_id **arr)
1030 struct share_conn_stat scs;
1031 NTSTATUS status;
1033 scs.ctx = ctx;
1034 scs.sharename = sharename;
1035 scs.svrid_arr = NULL;
1036 scs.count = 0;
1038 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1040 if (!NT_STATUS_IS_OK(status)) {
1041 DEBUG(0,("count_share_conns: traverse of "
1042 "smbXsrv_tcon_global.tdb failed - %s\n",
1043 nt_errstr(status)));
1044 return 0;
1047 *arr = scs.svrid_arr;
1048 return scs.count;
1051 /*******************************************************************
1052 fill in a conn info level 0 structure.
1053 ********************************************************************/
1055 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1056 uint32_t *resume_handle_p,
1057 uint32_t *total_entries)
1059 uint32_t num_entries = 0;
1060 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1062 DEBUG(5,("init_srv_conn_info_0\n"));
1064 if (ctr0 == NULL) {
1065 if (resume_handle_p) {
1066 *resume_handle_p = 0;
1068 return WERR_OK;
1071 *total_entries = 1;
1073 ZERO_STRUCTP(ctr0);
1075 for (; resume_handle < *total_entries; resume_handle++) {
1077 ctr0->array = talloc_realloc(talloc_tos(),
1078 ctr0->array,
1079 struct srvsvc_NetConnInfo0,
1080 num_entries+1);
1081 if (!ctr0->array) {
1082 return WERR_NOMEM;
1085 ctr0->array[num_entries].conn_id = *total_entries;
1087 /* move on to creating next connection */
1088 num_entries++;
1091 ctr0->count = num_entries;
1092 *total_entries = num_entries;
1094 if (resume_handle_p) {
1095 if (*resume_handle_p >= *total_entries) {
1096 *resume_handle_p = 0;
1097 } else {
1098 *resume_handle_p = resume_handle;
1102 return WERR_OK;
1105 /*******************************************************************
1106 fill in a conn info level 1 structure.
1107 ********************************************************************/
1109 static WERROR init_srv_conn_info_1(const char *name,
1110 struct srvsvc_NetConnCtr1 *ctr1,
1111 uint32_t *resume_handle_p,
1112 uint32_t *total_entries)
1114 uint32_t num_entries = 0, snum = 0;
1115 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1116 char *share_name = NULL;
1117 struct server_id *svrid_arr = NULL;
1119 DEBUG(5,("init_srv_conn_info_1\n"));
1121 if (ctr1 == NULL) {
1122 if (resume_handle_p) {
1123 *resume_handle_p = 0;
1125 return WERR_OK;
1128 /* check if this is a server name or a share name */
1129 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1130 (name[1] == '\\')) {
1132 /* 'name' is a server name - this part is unimplemented */
1133 *total_entries = 1;
1134 } else {
1135 /* 'name' is a share name */
1136 snum = find_service(talloc_tos(), name, &share_name);
1138 if (!share_name) {
1139 return WERR_NOMEM;
1142 if (snum < 0) {
1143 return WERR_INVALID_NAME;
1147 * count the num of connections to this share. Also,
1148 * build a list of serverid's that own these
1149 * connections. The serverid list is used later to
1150 * identify the share connection on which an open exists.
1153 *total_entries = count_share_conns(talloc_tos(),
1154 share_name,
1155 &svrid_arr);
1158 if (resume_handle >= *total_entries) {
1159 if (resume_handle_p) {
1160 *resume_handle_p = 0;
1162 return WERR_OK;
1166 * We know num_entries must be positive, due to
1167 * the check resume_handle >= *total_entries above.
1170 num_entries = *total_entries - resume_handle;
1172 ZERO_STRUCTP(ctr1);
1174 ctr1->array = talloc_zero_array(talloc_tos(),
1175 struct srvsvc_NetConnInfo1,
1176 num_entries);
1178 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1180 for (num_entries = 0; resume_handle < *total_entries;
1181 num_entries++, resume_handle++) {
1183 ctr1->array[num_entries].conn_id = *total_entries;
1184 ctr1->array[num_entries].conn_type = 0x3;
1187 * if these are connections to a share, we are going to
1188 * compute the opens on them later. If it's for the server,
1189 * it's unimplemented.
1192 if (!share_name) {
1193 ctr1->array[num_entries].num_open = 1;
1196 ctr1->array[num_entries].num_users = 1;
1197 ctr1->array[num_entries].conn_time = 3;
1198 ctr1->array[num_entries].user = "dummy_user";
1199 ctr1->array[num_entries].share = "IPC$";
1202 /* now compute open files on the share connections */
1204 if (share_name) {
1207 * the locking tdb, which has the open files information,
1208 * does not store share name or share (service) number, but
1209 * just the share path. So, we can compute open files only
1210 * on the share path. If more than one shares are defined
1211 * on a share path, open files on all of them are included
1212 * in the count.
1214 * To have the correct behavior in case multiple shares
1215 * are defined on the same path, changes to tdb records
1216 * would be required. That would be lot more effort, so
1217 * this seems a good stopgap fix.
1220 count_share_opens(ctr1->array, svrid_arr,
1221 lp_path(talloc_tos(), snum),
1222 num_entries, *total_entries);
1226 ctr1->count = num_entries;
1227 *total_entries = num_entries;
1229 if (resume_handle_p) {
1230 *resume_handle_p = resume_handle;
1233 return WERR_OK;
1236 /*******************************************************************
1237 _srvsvc_NetFileEnum
1238 *******************************************************************/
1240 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1241 struct srvsvc_NetFileEnum *r)
1243 TALLOC_CTX *ctx = NULL;
1244 struct srvsvc_NetFileCtr3 *ctr3;
1245 uint32_t resume_hnd = 0;
1246 WERROR werr;
1248 switch (r->in.info_ctr->level) {
1249 case 3:
1250 break;
1251 default:
1252 return WERR_UNKNOWN_LEVEL;
1255 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1256 p->session_info->security_token)) {
1257 DEBUG(1, ("Enumerating files only allowed for "
1258 "administrators\n"));
1259 return WERR_ACCESS_DENIED;
1262 ctx = talloc_tos();
1263 ctr3 = r->in.info_ctr->ctr.ctr3;
1264 if (!ctr3) {
1265 werr = WERR_INVALID_PARAM;
1266 goto done;
1269 /* TODO -- Windows enumerates
1270 (b) active pipes
1271 (c) open directories and files */
1273 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1274 if (!W_ERROR_IS_OK(werr)) {
1275 goto done;
1278 *r->out.totalentries = ctr3->count;
1279 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1280 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1282 werr = WERR_OK;
1284 done:
1285 return werr;
1288 /*******************************************************************
1289 _srvsvc_NetSrvGetInfo
1290 ********************************************************************/
1292 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1293 struct srvsvc_NetSrvGetInfo *r)
1295 WERROR status = WERR_OK;
1297 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1299 if (!pipe_access_check(p)) {
1300 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1301 return WERR_ACCESS_DENIED;
1304 switch (r->in.level) {
1306 /* Technically level 102 should only be available to
1307 Administrators but there isn't anything super-secret
1308 here, as most of it is made up. */
1310 case 102: {
1311 struct srvsvc_NetSrvInfo102 *info102;
1313 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1314 if (!info102) {
1315 return WERR_NOMEM;
1318 info102->platform_id = PLATFORM_ID_NT;
1319 info102->server_name = lp_netbios_name();
1320 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1321 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1322 info102->server_type = lp_default_server_announce();
1323 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1324 MAX_SERVER_STRING_LENGTH);
1325 info102->users = 0xffffffff;
1326 info102->disc = 0xf;
1327 info102->hidden = 0;
1328 info102->announce = 240;
1329 info102->anndelta = 3000;
1330 info102->licenses = 100000;
1331 info102->userpath = "C:\\";
1333 r->out.info->info102 = info102;
1334 break;
1336 case 101: {
1337 struct srvsvc_NetSrvInfo101 *info101;
1339 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1340 if (!info101) {
1341 return WERR_NOMEM;
1344 info101->platform_id = PLATFORM_ID_NT;
1345 info101->server_name = lp_netbios_name();
1346 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1347 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1348 info101->server_type = lp_default_server_announce();
1349 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1350 MAX_SERVER_STRING_LENGTH);
1352 r->out.info->info101 = info101;
1353 break;
1355 case 100: {
1356 struct srvsvc_NetSrvInfo100 *info100;
1358 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1359 if (!info100) {
1360 return WERR_NOMEM;
1363 info100->platform_id = PLATFORM_ID_NT;
1364 info100->server_name = lp_netbios_name();
1366 r->out.info->info100 = info100;
1368 break;
1370 default:
1371 status = WERR_UNKNOWN_LEVEL;
1372 break;
1375 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1377 return status;
1380 /*******************************************************************
1381 _srvsvc_NetSrvSetInfo
1382 ********************************************************************/
1384 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1385 struct srvsvc_NetSrvSetInfo *r)
1387 WERROR status = WERR_OK;
1389 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1391 /* Set up the net server set info structure. */
1393 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1395 return status;
1398 /*******************************************************************
1399 _srvsvc_NetConnEnum
1400 ********************************************************************/
1402 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1403 struct srvsvc_NetConnEnum *r)
1405 WERROR werr;
1407 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1409 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1410 p->session_info->security_token)) {
1411 DEBUG(1, ("Enumerating connections only allowed for "
1412 "administrators\n"));
1413 return WERR_ACCESS_DENIED;
1416 switch (r->in.info_ctr->level) {
1417 case 0:
1418 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1419 r->in.resume_handle,
1420 r->out.totalentries);
1421 break;
1422 case 1:
1423 werr = init_srv_conn_info_1(r->in.path,
1424 r->in.info_ctr->ctr.ctr1,
1425 r->in.resume_handle,
1426 r->out.totalentries);
1427 break;
1428 default:
1429 return WERR_UNKNOWN_LEVEL;
1432 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1434 return werr;
1437 /*******************************************************************
1438 _srvsvc_NetSessEnum
1439 ********************************************************************/
1441 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1442 struct srvsvc_NetSessEnum *r)
1444 WERROR werr;
1446 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1448 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1449 p->session_info->security_token)) {
1450 DEBUG(1, ("Enumerating sessions only allowed for "
1451 "administrators\n"));
1452 return WERR_ACCESS_DENIED;
1455 switch (r->in.info_ctr->level) {
1456 case 0:
1457 werr = init_srv_sess_info_0(p,
1458 r->in.info_ctr->ctr.ctr0,
1459 r->in.resume_handle,
1460 r->out.totalentries);
1461 break;
1462 case 1:
1463 werr = init_srv_sess_info_1(p,
1464 r->in.info_ctr->ctr.ctr1,
1465 r->in.resume_handle,
1466 r->out.totalentries);
1467 break;
1468 default:
1469 return WERR_UNKNOWN_LEVEL;
1472 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1474 return werr;
1477 /*******************************************************************
1478 _srvsvc_NetSessDel
1479 ********************************************************************/
1481 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1482 struct srvsvc_NetSessDel *r)
1484 struct sessionid *session_list;
1485 int num_sessions, snum;
1486 const char *username;
1487 const char *machine;
1488 bool not_root = False;
1489 WERROR werr;
1491 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1493 werr = WERR_ACCESS_DENIED;
1495 /* fail out now if you are not root or not a domain admin */
1497 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1498 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1499 DOMAIN_RID_ADMINS))) {
1501 goto done;
1504 username = r->in.user;
1505 machine = r->in.client;
1507 /* strip leading backslashes if any */
1508 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1509 machine += 2;
1512 num_sessions = find_sessions(p->mem_ctx, username, machine,
1513 &session_list);
1515 for (snum = 0; snum < num_sessions; snum++) {
1517 NTSTATUS ntstat;
1519 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1520 not_root = True;
1521 become_root();
1524 ntstat = messaging_send(p->msg_ctx,
1525 session_list[snum].pid,
1526 MSG_SHUTDOWN, &data_blob_null);
1528 if (NT_STATUS_IS_OK(ntstat))
1529 werr = WERR_OK;
1531 if (not_root)
1532 unbecome_root();
1535 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1537 done:
1539 return werr;
1542 /*******************************************************************
1543 _srvsvc_NetShareEnumAll
1544 ********************************************************************/
1546 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1547 struct srvsvc_NetShareEnumAll *r)
1549 WERROR werr;
1551 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1553 if (!pipe_access_check(p)) {
1554 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1555 return WERR_ACCESS_DENIED;
1558 /* Create the list of shares for the response. */
1559 werr = init_srv_share_info_ctr(p,
1560 r->in.info_ctr,
1561 r->in.resume_handle,
1562 r->out.totalentries,
1563 true);
1565 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1567 return werr;
1570 /*******************************************************************
1571 _srvsvc_NetShareEnum
1572 ********************************************************************/
1574 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1575 struct srvsvc_NetShareEnum *r)
1577 WERROR werr;
1579 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1581 if (!pipe_access_check(p)) {
1582 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1583 return WERR_ACCESS_DENIED;
1586 /* Create the list of shares for the response. */
1587 werr = init_srv_share_info_ctr(p,
1588 r->in.info_ctr,
1589 r->in.resume_handle,
1590 r->out.totalentries,
1591 false);
1593 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1595 return werr;
1598 /*******************************************************************
1599 _srvsvc_NetShareGetInfo
1600 ********************************************************************/
1602 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1603 struct srvsvc_NetShareGetInfo *r)
1605 WERROR status = WERR_OK;
1606 char *share_name = NULL;
1607 int snum;
1608 union srvsvc_NetShareInfo *info = r->out.info;
1610 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1612 if (!r->in.share_name) {
1613 return WERR_INVALID_NAME;
1616 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1617 if (!share_name) {
1618 return WERR_NOMEM;
1620 if (snum < 0) {
1621 return WERR_INVALID_NAME;
1624 switch (r->in.level) {
1625 case 0:
1626 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1627 W_ERROR_HAVE_NO_MEMORY(info->info0);
1628 init_srv_share_info_0(p, info->info0, snum);
1629 break;
1630 case 1:
1631 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1632 W_ERROR_HAVE_NO_MEMORY(info->info1);
1633 init_srv_share_info_1(p, info->info1, snum);
1634 break;
1635 case 2:
1636 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1637 W_ERROR_HAVE_NO_MEMORY(info->info2);
1638 init_srv_share_info_2(p, info->info2, snum);
1639 info->info2->current_users =
1640 count_current_connections(info->info2->name, false);
1641 break;
1642 case 501:
1643 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1644 W_ERROR_HAVE_NO_MEMORY(info->info501);
1645 init_srv_share_info_501(p, info->info501, snum);
1646 break;
1647 case 502:
1648 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1649 W_ERROR_HAVE_NO_MEMORY(info->info502);
1650 init_srv_share_info_502(p, info->info502, snum);
1651 break;
1652 case 1004:
1653 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1654 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1655 init_srv_share_info_1004(p, info->info1004, snum);
1656 break;
1657 case 1005:
1658 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1659 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1660 init_srv_share_info_1005(p, info->info1005, snum);
1661 break;
1662 case 1006:
1663 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1664 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1665 init_srv_share_info_1006(p, info->info1006, snum);
1666 break;
1667 case 1007:
1668 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1669 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1670 init_srv_share_info_1007(p, info->info1007, snum);
1671 break;
1672 case 1501:
1673 init_srv_share_info_1501(p, &info->info1501, snum);
1674 break;
1675 default:
1676 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1677 r->in.level));
1678 status = WERR_UNKNOWN_LEVEL;
1679 break;
1682 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1684 return status;
1687 /*******************************************************************
1688 _srvsvc_NetShareSetInfo. Modify share details.
1689 ********************************************************************/
1691 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1692 struct srvsvc_NetShareSetInfo *r)
1694 char *command = NULL;
1695 char *share_name = NULL;
1696 char *comment = NULL;
1697 const char *pathname = NULL;
1698 int type;
1699 int snum;
1700 int ret;
1701 char *path = NULL;
1702 struct security_descriptor *psd = NULL;
1703 bool is_disk_op = False;
1704 const char *csc_policy = NULL;
1705 bool csc_policy_changed = false;
1706 const char *csc_policies[] = {"manual", "documents", "programs",
1707 "disable"};
1708 uint32_t client_csc_policy;
1709 int max_connections = 0;
1710 TALLOC_CTX *ctx = p->mem_ctx;
1711 union srvsvc_NetShareInfo *info = r->in.info;
1713 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1715 if (!r->in.share_name) {
1716 return WERR_INVALID_NAME;
1719 if (r->out.parm_error) {
1720 *r->out.parm_error = 0;
1723 if ( strequal(r->in.share_name,"IPC$")
1724 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1725 || strequal(r->in.share_name,"global") )
1727 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1728 "modified by a remote user.\n",
1729 r->in.share_name ));
1730 return WERR_ACCESS_DENIED;
1733 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1734 if (!share_name) {
1735 return WERR_NOMEM;
1738 /* Does this share exist ? */
1739 if (snum < 0)
1740 return WERR_NET_NAME_NOT_FOUND;
1742 /* No change to printer shares. */
1743 if (lp_printable(snum))
1744 return WERR_ACCESS_DENIED;
1746 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1748 /* fail out now if you are not root and not a disk op */
1750 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1751 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1752 "SeDiskOperatorPrivilege privilege needed to modify "
1753 "share %s\n",
1754 (unsigned int)p->session_info->unix_token->uid,
1755 share_name ));
1756 return WERR_ACCESS_DENIED;
1759 max_connections = lp_max_connections(snum);
1760 csc_policy = csc_policies[lp_csc_policy(snum)];
1762 switch (r->in.level) {
1763 case 1:
1764 pathname = lp_path(ctx, snum);
1765 comment = talloc_strdup(ctx, info->info1->comment);
1766 type = info->info1->type;
1767 psd = NULL;
1768 break;
1769 case 2:
1770 comment = talloc_strdup(ctx, info->info2->comment);
1771 pathname = info->info2->path;
1772 type = info->info2->type;
1773 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1774 0 : info->info2->max_users;
1775 psd = NULL;
1776 break;
1777 #if 0
1778 /* not supported on set but here for completeness */
1779 case 501:
1780 comment = talloc_strdup(ctx, info->info501->comment);
1781 type = info->info501->type;
1782 psd = NULL;
1783 break;
1784 #endif
1785 case 502:
1786 comment = talloc_strdup(ctx, info->info502->comment);
1787 pathname = info->info502->path;
1788 type = info->info502->type;
1789 psd = info->info502->sd_buf.sd;
1790 map_generic_share_sd_bits(psd);
1791 break;
1792 case 1004:
1793 pathname = lp_path(ctx, snum);
1794 comment = talloc_strdup(ctx, info->info1004->comment);
1795 type = STYPE_DISKTREE;
1796 break;
1797 case 1005:
1798 /* XP re-sets the csc policy even if it wasn't changed by the
1799 user, so we must compare it to see if it's what is set in
1800 smb.conf, so that we can contine other ops like setting
1801 ACLs on a share */
1802 client_csc_policy = (info->info1005->dfs_flags &
1803 SHARE_1005_CSC_POLICY_MASK) >>
1804 SHARE_1005_CSC_POLICY_SHIFT;
1806 if (client_csc_policy == lp_csc_policy(snum))
1807 return WERR_OK;
1808 else {
1809 csc_policy = csc_policies[client_csc_policy];
1810 csc_policy_changed = true;
1813 pathname = lp_path(ctx, snum);
1814 comment = lp_comment(ctx, snum);
1815 type = STYPE_DISKTREE;
1816 break;
1817 case 1006:
1818 case 1007:
1819 return WERR_ACCESS_DENIED;
1820 case 1501:
1821 pathname = lp_path(ctx, snum);
1822 comment = lp_comment(ctx, snum);
1823 psd = info->info1501->sd;
1824 map_generic_share_sd_bits(psd);
1825 type = STYPE_DISKTREE;
1826 break;
1827 default:
1828 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1829 r->in.level));
1830 return WERR_UNKNOWN_LEVEL;
1833 /* We can only modify disk shares. */
1834 if (type != STYPE_DISKTREE) {
1835 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1836 "disk share\n",
1837 share_name ));
1838 return WERR_ACCESS_DENIED;
1841 if (comment == NULL) {
1842 return WERR_NOMEM;
1845 /* Check if the pathname is valid. */
1846 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1847 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1848 pathname ));
1849 return WERR_OBJECT_PATH_INVALID;
1852 /* Ensure share name, pathname and comment don't contain '"' characters. */
1853 string_replace(share_name, '"', ' ');
1854 string_replace(path, '"', ' ');
1855 string_replace(comment, '"', ' ');
1857 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1858 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1860 /* Only call modify function if something changed. */
1862 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1863 || (lp_max_connections(snum) != max_connections)
1864 || csc_policy_changed) {
1866 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1867 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1868 return WERR_ACCESS_DENIED;
1871 command = talloc_asprintf(p->mem_ctx,
1872 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1873 lp_change_share_command(talloc_tos()),
1874 get_dyn_CONFIGFILE(),
1875 share_name,
1876 path,
1877 comment ? comment : "",
1878 max_connections,
1879 csc_policy);
1880 if (!command) {
1881 return WERR_NOMEM;
1884 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1886 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1888 if (is_disk_op)
1889 become_root();
1891 if ( (ret = smbrun(command, NULL)) == 0 ) {
1892 /* Tell everyone we updated smb.conf. */
1893 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1894 NULL, 0, NULL);
1897 if ( is_disk_op )
1898 unbecome_root();
1900 /********* END SeDiskOperatorPrivilege BLOCK *********/
1902 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1903 command, ret ));
1905 TALLOC_FREE(command);
1907 if ( ret != 0 )
1908 return WERR_ACCESS_DENIED;
1909 } else {
1910 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1911 share_name ));
1914 /* Replace SD if changed. */
1915 if (psd) {
1916 struct security_descriptor *old_sd;
1917 size_t sd_size;
1919 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1921 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1922 if (!set_share_security(share_name, psd))
1923 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1924 share_name ));
1928 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1930 return WERR_OK;
1933 /*******************************************************************
1934 _srvsvc_NetShareAdd.
1935 Call 'add_share_command "sharename" "pathname"
1936 "comment" "max connections = "
1937 ********************************************************************/
1939 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1940 struct srvsvc_NetShareAdd *r)
1942 char *command = NULL;
1943 char *share_name_in = NULL;
1944 char *share_name = NULL;
1945 char *comment = NULL;
1946 char *pathname = NULL;
1947 int type;
1948 int snum;
1949 int ret;
1950 char *path;
1951 struct security_descriptor *psd = NULL;
1952 bool is_disk_op;
1953 int max_connections = 0;
1954 SMB_STRUCT_STAT st;
1955 TALLOC_CTX *ctx = p->mem_ctx;
1957 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1959 if (r->out.parm_error) {
1960 *r->out.parm_error = 0;
1963 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1965 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1966 return WERR_ACCESS_DENIED;
1968 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1969 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1970 return WERR_ACCESS_DENIED;
1973 switch (r->in.level) {
1974 case 0:
1975 /* No path. Not enough info in a level 0 to do anything. */
1976 return WERR_ACCESS_DENIED;
1977 case 1:
1978 /* Not enough info in a level 1 to do anything. */
1979 return WERR_ACCESS_DENIED;
1980 case 2:
1981 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1982 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1983 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1984 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1985 0 : r->in.info->info2->max_users;
1986 type = r->in.info->info2->type;
1987 break;
1988 case 501:
1989 /* No path. Not enough info in a level 501 to do anything. */
1990 return WERR_ACCESS_DENIED;
1991 case 502:
1992 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1993 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1994 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1995 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1996 0 : r->in.info->info502->max_users;
1997 type = r->in.info->info502->type;
1998 psd = r->in.info->info502->sd_buf.sd;
1999 map_generic_share_sd_bits(psd);
2000 break;
2002 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2004 case 1004:
2005 case 1005:
2006 case 1006:
2007 case 1007:
2008 return WERR_ACCESS_DENIED;
2009 case 1501:
2010 /* DFS only level. */
2011 return WERR_ACCESS_DENIED;
2012 default:
2013 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2014 r->in.level));
2015 return WERR_UNKNOWN_LEVEL;
2018 /* check for invalid share names */
2020 if (!share_name_in || !validate_net_name(share_name_in,
2021 INVALID_SHARENAME_CHARS,
2022 strlen(share_name_in))) {
2023 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2024 share_name_in ? share_name_in : ""));
2025 return WERR_INVALID_NAME;
2028 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2029 || (lp_enable_asu_support() &&
2030 strequal(share_name_in,"ADMIN$"))) {
2031 return WERR_ACCESS_DENIED;
2034 snum = find_service(ctx, share_name_in, &share_name);
2035 if (!share_name) {
2036 return WERR_NOMEM;
2039 /* Share already exists. */
2040 if (snum >= 0) {
2041 return WERR_FILE_EXISTS;
2044 /* We can only add disk shares. */
2045 if (type != STYPE_DISKTREE) {
2046 return WERR_ACCESS_DENIED;
2049 /* Check if the pathname is valid. */
2050 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2051 return WERR_OBJECT_PATH_INVALID;
2054 ret = sys_lstat(path, &st, false);
2055 if (ret == -1 && (errno != EACCES)) {
2057 * If path has any other than permission
2058 * problem, return WERR_BADFILE (as Windows
2059 * does.
2061 return WERR_BADFILE;
2064 /* Ensure share name, pathname and comment don't contain '"' characters. */
2065 string_replace(share_name_in, '"', ' ');
2066 string_replace(share_name, '"', ' ');
2067 string_replace(path, '"', ' ');
2068 if (comment) {
2069 string_replace(comment, '"', ' ');
2072 command = talloc_asprintf(ctx,
2073 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2074 lp_add_share_command(talloc_tos()),
2075 get_dyn_CONFIGFILE(),
2076 share_name_in,
2077 path,
2078 comment ? comment : "",
2079 max_connections);
2080 if (!command) {
2081 return WERR_NOMEM;
2084 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2086 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2088 if ( is_disk_op )
2089 become_root();
2091 /* FIXME: use libnetconf here - gd */
2093 if ( (ret = smbrun(command, NULL)) == 0 ) {
2094 /* Tell everyone we updated smb.conf. */
2095 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2096 NULL);
2099 if ( is_disk_op )
2100 unbecome_root();
2102 /********* END SeDiskOperatorPrivilege BLOCK *********/
2104 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2105 command, ret ));
2107 TALLOC_FREE(command);
2109 if ( ret != 0 )
2110 return WERR_ACCESS_DENIED;
2112 if (psd) {
2113 /* Note we use share_name here, not share_name_in as
2114 we need a canonicalized name for setting security. */
2115 if (!set_share_security(share_name, psd)) {
2116 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2117 share_name ));
2122 * We don't call reload_services() here, the message will
2123 * cause this to be done before the next packet is read
2124 * from the client. JRA.
2127 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2129 return WERR_OK;
2132 /*******************************************************************
2133 _srvsvc_NetShareDel
2134 Call "delete share command" with the share name as
2135 a parameter.
2136 ********************************************************************/
2138 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2139 struct srvsvc_NetShareDel *r)
2141 char *command = NULL;
2142 char *share_name = NULL;
2143 int ret;
2144 int snum;
2145 bool is_disk_op;
2146 TALLOC_CTX *ctx = p->mem_ctx;
2148 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2150 if (!r->in.share_name) {
2151 return WERR_NET_NAME_NOT_FOUND;
2154 if ( strequal(r->in.share_name,"IPC$")
2155 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2156 || strequal(r->in.share_name,"global") )
2158 return WERR_ACCESS_DENIED;
2161 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2162 if (!share_name) {
2163 return WERR_NOMEM;
2166 if (snum < 0) {
2167 return WERR_NO_SUCH_SHARE;
2170 /* No change to printer shares. */
2171 if (lp_printable(snum))
2172 return WERR_ACCESS_DENIED;
2174 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2176 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2177 return WERR_ACCESS_DENIED;
2179 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2180 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2181 return WERR_ACCESS_DENIED;
2184 command = talloc_asprintf(ctx,
2185 "%s \"%s\" \"%s\"",
2186 lp_delete_share_command(talloc_tos()),
2187 get_dyn_CONFIGFILE(),
2188 share_name);
2189 if (!command) {
2190 return WERR_NOMEM;
2193 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2195 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2197 if ( is_disk_op )
2198 become_root();
2200 if ( (ret = smbrun(command, NULL)) == 0 ) {
2201 /* Tell everyone we updated smb.conf. */
2202 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2203 NULL);
2206 if ( is_disk_op )
2207 unbecome_root();
2209 /********* END SeDiskOperatorPrivilege BLOCK *********/
2211 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2213 if ( ret != 0 )
2214 return WERR_ACCESS_DENIED;
2216 /* Delete the SD in the database. */
2217 delete_share_security(share_name);
2219 lp_killservice(snum);
2221 return WERR_OK;
2224 /*******************************************************************
2225 _srvsvc_NetShareDelSticky
2226 ********************************************************************/
2228 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2229 struct srvsvc_NetShareDelSticky *r)
2231 struct srvsvc_NetShareDel q;
2233 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2235 q.in.server_unc = r->in.server_unc;
2236 q.in.share_name = r->in.share_name;
2237 q.in.reserved = r->in.reserved;
2239 return _srvsvc_NetShareDel(p, &q);
2242 /*******************************************************************
2243 _srvsvc_NetRemoteTOD
2244 ********************************************************************/
2246 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2247 struct srvsvc_NetRemoteTOD *r)
2249 struct srvsvc_NetRemoteTODInfo *tod;
2250 struct tm *t;
2251 time_t unixdate = time(NULL);
2253 /* We do this call first as if we do it *after* the gmtime call
2254 it overwrites the pointed-to values. JRA */
2256 uint32 zone = get_time_zone(unixdate)/60;
2258 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2260 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2261 return WERR_NOMEM;
2263 *r->out.info = tod;
2265 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2267 t = gmtime(&unixdate);
2269 /* set up the */
2270 tod->elapsed = unixdate;
2271 tod->msecs = 0;
2272 tod->hours = t->tm_hour;
2273 tod->mins = t->tm_min;
2274 tod->secs = t->tm_sec;
2275 tod->hunds = 0;
2276 tod->timezone = zone;
2277 tod->tinterval = 10000;
2278 tod->day = t->tm_mday;
2279 tod->month = t->tm_mon + 1;
2280 tod->year = 1900+t->tm_year;
2281 tod->weekday = t->tm_wday;
2283 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2285 return WERR_OK;
2288 /***********************************************************************************
2289 _srvsvc_NetGetFileSecurity
2290 Win9x NT tools get security descriptor.
2291 ***********************************************************************************/
2293 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2294 struct srvsvc_NetGetFileSecurity *r)
2296 struct smb_filename *smb_fname = NULL;
2297 size_t sd_size;
2298 char *servicename = NULL;
2299 SMB_STRUCT_STAT st;
2300 NTSTATUS nt_status;
2301 WERROR werr;
2302 connection_struct *conn = NULL;
2303 struct sec_desc_buf *sd_buf = NULL;
2304 files_struct *fsp = NULL;
2305 int snum;
2306 char *oldcwd = NULL;
2308 ZERO_STRUCT(st);
2310 if (!r->in.share) {
2311 werr = WERR_NET_NAME_NOT_FOUND;
2312 goto error_exit;
2314 snum = find_service(talloc_tos(), r->in.share, &servicename);
2315 if (!servicename) {
2316 werr = WERR_NOMEM;
2317 goto error_exit;
2319 if (snum == -1) {
2320 DEBUG(10, ("Could not find service %s\n", servicename));
2321 werr = WERR_NET_NAME_NOT_FOUND;
2322 goto error_exit;
2325 nt_status = create_conn_struct_cwd(talloc_tos(),
2326 server_event_context(),
2327 server_messaging_context(),
2328 &conn,
2329 snum, lp_path(talloc_tos(), snum),
2330 p->session_info, &oldcwd);
2331 if (!NT_STATUS_IS_OK(nt_status)) {
2332 DEBUG(10, ("create_conn_struct failed: %s\n",
2333 nt_errstr(nt_status)));
2334 werr = ntstatus_to_werror(nt_status);
2335 goto error_exit;
2338 nt_status = filename_convert(talloc_tos(),
2339 conn,
2340 false,
2341 r->in.file,
2343 NULL,
2344 &smb_fname);
2345 if (!NT_STATUS_IS_OK(nt_status)) {
2346 werr = ntstatus_to_werror(nt_status);
2347 goto error_exit;
2350 nt_status = SMB_VFS_CREATE_FILE(
2351 conn, /* conn */
2352 NULL, /* req */
2353 0, /* root_dir_fid */
2354 smb_fname, /* fname */
2355 FILE_READ_ATTRIBUTES, /* access_mask */
2356 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2357 FILE_OPEN, /* create_disposition*/
2358 0, /* create_options */
2359 0, /* file_attributes */
2360 INTERNAL_OPEN_ONLY, /* oplock_request */
2361 NULL, /* lease */
2362 0, /* allocation_size */
2363 0, /* private_flags */
2364 NULL, /* sd */
2365 NULL, /* ea_list */
2366 &fsp, /* result */
2367 NULL, /* pinfo */
2368 NULL, NULL); /* create context */
2370 if (!NT_STATUS_IS_OK(nt_status)) {
2371 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2372 smb_fname_str_dbg(smb_fname)));
2373 werr = ntstatus_to_werror(nt_status);
2374 goto error_exit;
2377 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2378 if (!sd_buf) {
2379 werr = WERR_NOMEM;
2380 goto error_exit;
2383 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2384 (SECINFO_OWNER
2385 |SECINFO_GROUP
2386 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2388 if (!NT_STATUS_IS_OK(nt_status)) {
2389 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2390 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2391 werr = ntstatus_to_werror(nt_status);
2392 TALLOC_FREE(sd_buf);
2393 goto error_exit;
2396 if (sd_buf->sd->dacl) {
2397 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2400 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2402 sd_buf->sd_size = sd_size;
2404 *r->out.sd_buf = sd_buf;
2406 close_file(NULL, fsp, NORMAL_CLOSE);
2407 vfs_ChDir(conn, oldcwd);
2408 SMB_VFS_DISCONNECT(conn);
2409 conn_free(conn);
2410 werr = WERR_OK;
2411 goto done;
2413 error_exit:
2415 if (fsp) {
2416 close_file(NULL, fsp, NORMAL_CLOSE);
2419 if (oldcwd) {
2420 vfs_ChDir(conn, oldcwd);
2423 if (conn) {
2424 SMB_VFS_DISCONNECT(conn);
2425 conn_free(conn);
2428 done:
2430 TALLOC_FREE(smb_fname);
2432 return werr;
2435 /***********************************************************************************
2436 _srvsvc_NetSetFileSecurity
2437 Win9x NT tools set security descriptor.
2438 ***********************************************************************************/
2440 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2441 struct srvsvc_NetSetFileSecurity *r)
2443 struct smb_filename *smb_fname = NULL;
2444 char *servicename = NULL;
2445 files_struct *fsp = NULL;
2446 SMB_STRUCT_STAT st;
2447 NTSTATUS nt_status;
2448 WERROR werr;
2449 connection_struct *conn = NULL;
2450 int snum;
2451 char *oldcwd = NULL;
2452 struct security_descriptor *psd = NULL;
2453 uint32_t security_info_sent = 0;
2455 ZERO_STRUCT(st);
2457 if (!r->in.share) {
2458 werr = WERR_NET_NAME_NOT_FOUND;
2459 goto error_exit;
2462 snum = find_service(talloc_tos(), r->in.share, &servicename);
2463 if (!servicename) {
2464 werr = WERR_NOMEM;
2465 goto error_exit;
2468 if (snum == -1) {
2469 DEBUG(10, ("Could not find service %s\n", servicename));
2470 werr = WERR_NET_NAME_NOT_FOUND;
2471 goto error_exit;
2474 nt_status = create_conn_struct_cwd(talloc_tos(),
2475 server_event_context(),
2476 server_messaging_context(),
2477 &conn,
2478 snum, lp_path(talloc_tos(), snum),
2479 p->session_info, &oldcwd);
2480 if (!NT_STATUS_IS_OK(nt_status)) {
2481 DEBUG(10, ("create_conn_struct failed: %s\n",
2482 nt_errstr(nt_status)));
2483 werr = ntstatus_to_werror(nt_status);
2484 goto error_exit;
2487 nt_status = filename_convert(talloc_tos(),
2488 conn,
2489 false,
2490 r->in.file,
2492 NULL,
2493 &smb_fname);
2494 if (!NT_STATUS_IS_OK(nt_status)) {
2495 werr = ntstatus_to_werror(nt_status);
2496 goto error_exit;
2499 nt_status = SMB_VFS_CREATE_FILE(
2500 conn, /* conn */
2501 NULL, /* req */
2502 0, /* root_dir_fid */
2503 smb_fname, /* fname */
2504 FILE_WRITE_ATTRIBUTES, /* access_mask */
2505 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2506 FILE_OPEN, /* create_disposition*/
2507 0, /* create_options */
2508 0, /* file_attributes */
2509 INTERNAL_OPEN_ONLY, /* oplock_request */
2510 NULL, /* lease */
2511 0, /* allocation_size */
2512 0, /* private_flags */
2513 NULL, /* sd */
2514 NULL, /* ea_list */
2515 &fsp, /* result */
2516 NULL, /* pinfo */
2517 NULL, NULL); /* create context */
2519 if (!NT_STATUS_IS_OK(nt_status)) {
2520 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2521 smb_fname_str_dbg(smb_fname)));
2522 werr = ntstatus_to_werror(nt_status);
2523 goto error_exit;
2526 psd = r->in.sd_buf->sd;
2527 security_info_sent = r->in.securityinformation;
2529 nt_status = set_sd(fsp, psd, security_info_sent);
2531 if (!NT_STATUS_IS_OK(nt_status) ) {
2532 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2533 "on file %s\n", r->in.share));
2534 werr = WERR_ACCESS_DENIED;
2535 goto error_exit;
2538 close_file(NULL, fsp, NORMAL_CLOSE);
2539 vfs_ChDir(conn, oldcwd);
2540 SMB_VFS_DISCONNECT(conn);
2541 conn_free(conn);
2542 werr = WERR_OK;
2543 goto done;
2545 error_exit:
2547 if (fsp) {
2548 close_file(NULL, fsp, NORMAL_CLOSE);
2551 if (oldcwd) {
2552 vfs_ChDir(conn, oldcwd);
2555 if (conn) {
2556 SMB_VFS_DISCONNECT(conn);
2557 conn_free(conn);
2560 done:
2561 TALLOC_FREE(smb_fname);
2563 return werr;
2566 /***********************************************************************************
2567 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2568 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2569 These disks would the disks listed by this function.
2570 Users could then create shares relative to these disks. Watch out for moving these disks around.
2571 "Nigel Williams" <nigel@veritas.com>.
2572 ***********************************************************************************/
2574 static const char *server_disks[] = {"C:"};
2576 static uint32 get_server_disk_count(void)
2578 return sizeof(server_disks)/sizeof(server_disks[0]);
2581 static uint32 init_server_disk_enum(uint32 *resume)
2583 uint32 server_disk_count = get_server_disk_count();
2585 /*resume can be an offset into the list for now*/
2587 if(*resume & 0x80000000)
2588 *resume = 0;
2590 if(*resume > server_disk_count)
2591 *resume = server_disk_count;
2593 return server_disk_count - *resume;
2596 static const char *next_server_disk_enum(uint32 *resume)
2598 const char *disk;
2600 if(init_server_disk_enum(resume) == 0)
2601 return NULL;
2603 disk = server_disks[*resume];
2605 (*resume)++;
2607 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2609 return disk;
2612 /********************************************************************
2613 _srvsvc_NetDiskEnum
2614 ********************************************************************/
2616 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2617 struct srvsvc_NetDiskEnum *r)
2619 uint32 i;
2620 const char *disk_name;
2621 TALLOC_CTX *ctx = p->mem_ctx;
2622 WERROR werr;
2623 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2625 werr = WERR_OK;
2627 *r->out.totalentries = init_server_disk_enum(&resume);
2629 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2630 MAX_SERVER_DISK_ENTRIES);
2631 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2633 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2635 r->out.info->count = 0;
2637 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2639 r->out.info->count++;
2641 /*copy disk name into a unicode string*/
2643 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2644 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2647 /* add a terminating null string. Is this there if there is more data to come? */
2649 r->out.info->count++;
2651 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2652 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2654 if (r->out.resume_handle) {
2655 *r->out.resume_handle = resume;
2658 return werr;
2661 /********************************************************************
2662 _srvsvc_NetNameValidate
2663 ********************************************************************/
2665 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2666 struct srvsvc_NetNameValidate *r)
2668 switch (r->in.name_type) {
2669 case 0x9:
2670 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2671 strlen_m(r->in.name)))
2673 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2674 r->in.name));
2675 return WERR_INVALID_NAME;
2677 break;
2679 default:
2680 return WERR_UNKNOWN_LEVEL;
2683 return WERR_OK;
2686 /*******************************************************************
2687 ********************************************************************/
2689 struct enum_file_close_state {
2690 struct srvsvc_NetFileClose *r;
2691 struct messaging_context *msg_ctx;
2694 static int enum_file_close_fn(const struct share_mode_entry *e,
2695 const char *sharepath, const char *fname,
2696 void *private_data)
2698 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2699 struct enum_file_close_state *state =
2700 (struct enum_file_close_state *)private_data;
2701 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2703 if (fid != state->r->in.fid) {
2704 return 0; /* Not this file. */
2707 if (!process_exists(e->pid) ) {
2708 return 0;
2711 /* Ok - send the close message. */
2712 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2713 sharepath,
2714 share_mode_str(talloc_tos(), 0, e) ));
2716 share_mode_entry_to_message(msg, e);
2718 state->r->out.result = ntstatus_to_werror(
2719 messaging_send_buf(state->msg_ctx,
2720 e->pid, MSG_SMB_CLOSE_FILE,
2721 (uint8 *)msg, sizeof(msg)));
2723 return 0;
2726 /********************************************************************
2727 Close a file given a 32-bit file id.
2728 ********************************************************************/
2730 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2731 struct srvsvc_NetFileClose *r)
2733 struct enum_file_close_state state;
2734 bool is_disk_op;
2736 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2738 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2740 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2741 return WERR_ACCESS_DENIED;
2744 /* enum_file_close_fn sends the close message to
2745 * the relevant smbd process. */
2747 r->out.result = WERR_BADFILE;
2748 state.r = r;
2749 state.msg_ctx = p->msg_ctx;
2750 share_entry_forall(enum_file_close_fn, &state);
2751 return r->out.result;
2754 /********************************************************************
2755 ********************************************************************/
2757 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2758 struct srvsvc_NetCharDevEnum *r)
2760 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2761 return WERR_NOT_SUPPORTED;
2764 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2765 struct srvsvc_NetCharDevGetInfo *r)
2767 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2768 return WERR_NOT_SUPPORTED;
2771 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2772 struct srvsvc_NetCharDevControl *r)
2774 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2775 return WERR_NOT_SUPPORTED;
2778 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2779 struct srvsvc_NetCharDevQEnum *r)
2781 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2782 return WERR_NOT_SUPPORTED;
2785 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2786 struct srvsvc_NetCharDevQGetInfo *r)
2788 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2789 return WERR_NOT_SUPPORTED;
2792 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2793 struct srvsvc_NetCharDevQSetInfo *r)
2795 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2796 return WERR_NOT_SUPPORTED;
2799 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2800 struct srvsvc_NetCharDevQPurge *r)
2802 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2803 return WERR_NOT_SUPPORTED;
2806 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2807 struct srvsvc_NetCharDevQPurgeSelf *r)
2809 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2810 return WERR_NOT_SUPPORTED;
2813 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2814 struct srvsvc_NetFileGetInfo *r)
2816 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2817 return WERR_NOT_SUPPORTED;
2820 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2821 struct srvsvc_NetShareCheck *r)
2823 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2824 return WERR_NOT_SUPPORTED;
2827 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2828 struct srvsvc_NetServerStatisticsGet *r)
2830 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2831 return WERR_NOT_SUPPORTED;
2834 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2835 struct srvsvc_NetTransportAdd *r)
2837 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2838 return WERR_NOT_SUPPORTED;
2841 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2842 struct srvsvc_NetTransportEnum *r)
2844 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2845 return WERR_NOT_SUPPORTED;
2848 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2849 struct srvsvc_NetTransportDel *r)
2851 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2852 return WERR_NOT_SUPPORTED;
2855 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2856 struct srvsvc_NetSetServiceBits *r)
2858 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2859 return WERR_NOT_SUPPORTED;
2862 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2863 struct srvsvc_NetPathType *r)
2865 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2866 return WERR_NOT_SUPPORTED;
2869 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2870 struct srvsvc_NetPathCanonicalize *r)
2872 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2873 return WERR_NOT_SUPPORTED;
2876 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2877 struct srvsvc_NetPathCompare *r)
2879 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2880 return WERR_NOT_SUPPORTED;
2883 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2884 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2886 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2887 return WERR_NOT_SUPPORTED;
2890 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2891 struct srvsvc_NetPRNameCompare *r)
2893 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2894 return WERR_NOT_SUPPORTED;
2897 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2898 struct srvsvc_NetShareDelStart *r)
2900 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2901 return WERR_NOT_SUPPORTED;
2904 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2905 struct srvsvc_NetShareDelCommit *r)
2907 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2908 return WERR_NOT_SUPPORTED;
2911 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2912 struct srvsvc_NetServerTransportAddEx *r)
2914 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2915 return WERR_NOT_SUPPORTED;
2918 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2919 struct srvsvc_NetServerSetServiceBitsEx *r)
2921 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2922 return WERR_NOT_SUPPORTED;
2925 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2926 struct srvsvc_NETRDFSGETVERSION *r)
2928 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2929 return WERR_NOT_SUPPORTED;
2932 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2933 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2935 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2936 return WERR_NOT_SUPPORTED;
2939 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2940 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2942 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2943 return WERR_NOT_SUPPORTED;
2946 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2947 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2949 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2950 return WERR_NOT_SUPPORTED;
2953 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2954 struct srvsvc_NETRDFSSETSERVERINFO *r)
2956 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2957 return WERR_NOT_SUPPORTED;
2960 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2961 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2963 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2964 return WERR_NOT_SUPPORTED;
2967 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2968 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2970 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2971 return WERR_NOT_SUPPORTED;
2974 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2975 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2977 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2978 return WERR_NOT_SUPPORTED;
2981 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2982 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2984 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2985 return WERR_NOT_SUPPORTED;
2988 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2989 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2991 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2992 return WERR_NOT_SUPPORTED;
2995 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2996 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2998 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2999 return WERR_NOT_SUPPORTED;