docs-xml/manpages: 'ceph_new' prefix for config-param of vfs_ceph_new
[Samba.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob1129576f751ec5d4060401d416ae02ce536d3e30
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 "lib/util/server_id.h"
29 #include "ntdomain.h"
30 #include "librpc/rpc/dcesrv_core.h"
31 #include "librpc/gen_ndr/ndr_srvsvc.h"
32 #include "librpc/gen_ndr/ndr_srvsvc_scompat.h"
33 #include "librpc/gen_ndr/ndr_open_files.h"
34 #include "../libcli/security/security.h"
35 #include "../librpc/gen_ndr/ndr_security.h"
36 #include "../librpc/gen_ndr/open_files.h"
37 #include "dbwrap/dbwrap.h"
38 #include "session.h"
39 #include "../lib/util/util_pw.h"
40 #include "locking/share_mode_lock.h"
41 #include "smbd/smbd.h"
42 #include "smbd/globals.h"
43 #include "auth.h"
44 #include "messages.h"
45 #include "serverid.h"
46 #include "lib/global_contexts.h"
47 #include "source3/lib/substitute.h"
48 #include "lib/tsocket/tsocket.h"
49 #include "librpc/rpc/dcesrv_core.h"
51 extern const struct generic_mapping file_generic_mapping;
53 #undef DBGC_CLASS
54 #define DBGC_CLASS DBGC_RPC_SRV
56 #define MAX_SERVER_DISK_ENTRIES 15
58 /* Use for enumerating connections, pipes, & files */
60 struct file_enum_count {
61 TALLOC_CTX *ctx;
62 const char *username;
63 struct srvsvc_NetFileCtr3 *ctr3;
64 struct file_id *fids;
67 struct sess_file_info {
68 struct srvsvc_NetSessCtr1 *ctr;
69 struct sessionid *session_list;
70 uint32_t resume_handle;
71 uint32_t num_entries;
74 struct share_file_stat {
75 struct srvsvc_NetConnInfo1 *netconn_arr;
76 struct server_id *svrid_arr;
77 const char *in_sharepath;
78 uint32_t resp_entries;
79 uint32_t total_entries;
82 struct share_conn_stat {
83 TALLOC_CTX *ctx;
84 const char *sharename;
85 struct server_id *svrid_arr;
86 int count;
89 /*******************************************************************
90 ********************************************************************/
92 static int enum_file_fn(struct file_id id,
93 const struct share_mode_data *d,
94 const struct share_mode_entry *e,
95 void *private_data)
97 struct file_enum_count *fenum =
98 (struct file_enum_count *)private_data;
99 struct srvsvc_NetFileCtr3 *ctr3 = fenum->ctr3;
100 struct srvsvc_NetFileInfo3 *f;
101 struct file_id *fids = NULL;
102 char *fullpath = NULL;
103 uint32_t permissions;
104 const char *username;
106 /* If the pid was not found delete the entry from connections.tdb */
108 if ( !process_exists(e->pid) ) {
109 return 0;
112 username = uidtoname(e->uid);
114 if ((fenum->username != NULL)
115 && !strequal(username, fenum->username)) {
116 return 0;
119 f = talloc_realloc(
120 fenum->ctx,
121 ctr3->array,
122 struct srvsvc_NetFileInfo3,
123 ctr3->count+1);
124 if ( !f ) {
125 DBG_ERR("realloc failed for %"PRIu32" items\n", ctr3->count+1);
126 return 0;
128 ctr3->array = f;
130 fids = talloc_realloc(
131 fenum->ctx, fenum->fids, struct file_id, ctr3->count+1);
132 if (fids == NULL) {
133 DBG_ERR("realloc failed for %"PRIu32" items\n", ctr3->count+1);
134 return 0;
136 fids[ctr3->count] = id;
137 fenum->fids = fids;
139 if ( strcmp(d->base_name, "." ) == 0 ) {
140 fullpath = talloc_asprintf(
141 fenum->ctx,
142 "C:%s",
143 d->servicepath);
144 } else {
145 fullpath = talloc_asprintf(
146 fenum->ctx,
147 "C:%s/%s%s",
148 d->servicepath,
149 d->base_name,
150 (d->stream_name != NULL) ? d->stream_name : "");
152 if (!fullpath) {
153 return 0;
155 string_replace( fullpath, '/', '\\' );
157 /* mask out create (what ever that is) */
158 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
160 /* now fill in the srvsvc_NetFileInfo3 struct */
162 ctr3->array[ctr3->count] = (struct srvsvc_NetFileInfo3) {
163 .fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) |
164 e->share_file_id),
165 .permissions = permissions,
166 .path = fullpath,
167 .user = username,
170 ctr3->count++;
172 return 0;
175 /*******************************************************************
176 ********************************************************************/
178 static WERROR net_enum_files(TALLOC_CTX *ctx,
179 const char *username,
180 struct srvsvc_NetFileCtr3 **ctr3,
181 uint32_t resume)
183 struct file_enum_count f_enum_cnt = {
184 .ctx = ctx, .username = username, .ctr3 = *ctr3,
186 uint32_t i;
188 share_entry_forall(enum_file_fn, (void *)&f_enum_cnt );
190 *ctr3 = f_enum_cnt.ctr3;
192 /* need to count the number of locks on a file */
194 for (i=0; i<(*ctr3)->count; i++) {
195 struct files_struct fsp = { .file_id = f_enum_cnt.fids[i], };
196 struct byte_range_lock *brl = NULL;
198 brl = brl_get_locks(ctx, &fsp);
199 if (brl == NULL) {
200 continue;
203 (*ctr3)->array[i].num_locks = brl_num_locks(brl);
205 TALLOC_FREE(brl);
208 return WERR_OK;
211 /*******************************************************************
212 Utility function to get the 'type' of a share from an snum.
213 ********************************************************************/
214 static enum srvsvc_ShareType get_share_type(int snum)
216 /* work out the share type */
217 enum srvsvc_ShareType type = STYPE_DISKTREE;
219 if (lp_printable(snum)) {
220 type = lp_administrative_share(snum)
221 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
223 if (strequal(lp_fstype(snum), "IPC")) {
224 type = lp_administrative_share(snum)
225 ? STYPE_IPC_HIDDEN : STYPE_IPC;
227 return type;
230 /*******************************************************************
231 Fill in a share info level 0 structure.
232 ********************************************************************/
234 static void init_srv_share_info_0(struct pipes_struct *p,
235 struct srvsvc_NetShareInfo0 *r, int snum)
237 const struct loadparm_substitution *lp_sub =
238 loadparm_s3_global_substitution();
240 r->name = lp_servicename(talloc_tos(), lp_sub, snum);
243 /*******************************************************************
244 Fill in a share info level 1 structure.
245 ********************************************************************/
247 static void init_srv_share_info_1(struct pipes_struct *p,
248 struct srvsvc_NetShareInfo1 *r,
249 int snum)
251 struct dcesrv_call_state *dce_call = p->dce_call;
252 struct auth_session_info *session_info =
253 dcesrv_call_session_info(dce_call);
254 const struct loadparm_substitution *lp_sub =
255 loadparm_s3_global_substitution();
256 char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
257 char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
259 if (remark) {
260 remark = talloc_sub_full(
261 p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
262 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
263 session_info->unix_token->uid, get_current_username(),
264 "", remark);
267 r->name = net_name;
268 r->type = get_share_type(snum);
269 r->comment = remark ? remark : "";
272 /*******************************************************************
273 Fill in a share info level 2 structure.
274 ********************************************************************/
276 static void init_srv_share_info_2(struct pipes_struct *p,
277 struct srvsvc_NetShareInfo2 *r,
278 int snum)
280 struct dcesrv_call_state *dce_call = p->dce_call;
281 struct auth_session_info *session_info =
282 dcesrv_call_session_info(dce_call);
283 const struct loadparm_substitution *lp_sub =
284 loadparm_s3_global_substitution();
285 char *remark = NULL;
286 char *path = NULL;
287 int max_connections = lp_max_connections(snum);
288 uint32_t max_uses = UINT32_MAX;
289 char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
291 if (max_connections > 0) {
292 max_uses = MIN(max_connections, UINT32_MAX);
295 remark = lp_comment(p->mem_ctx, lp_sub, snum);
296 if (remark) {
297 remark = talloc_sub_full(
298 p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
299 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
300 session_info->unix_token->uid, get_current_username(),
301 "", remark);
303 path = talloc_asprintf(p->mem_ctx,
304 "C:%s", lp_path(talloc_tos(), lp_sub, snum));
306 if (path) {
308 * Change / to \\ so that win2k will see it as a valid path.
309 * This was added to enable use of browsing in win2k add
310 * share dialog.
313 string_replace(path, '/', '\\');
316 r->name = net_name;
317 r->type = get_share_type(snum);
318 r->comment = remark ? remark : "";
319 r->permissions = 0;
320 r->max_users = max_uses;
321 r->current_users = 0; /* computed later */
322 r->path = path ? path : "";
323 r->password = "";
326 /*******************************************************************
327 Map any generic bits to file specific bits.
328 ********************************************************************/
330 static void map_generic_share_sd_bits(struct security_descriptor *psd)
332 uint32_t i;
333 struct security_acl *ps_dacl = NULL;
335 if (!psd)
336 return;
338 ps_dacl = psd->dacl;
339 if (!ps_dacl)
340 return;
342 for (i = 0; i < ps_dacl->num_aces; i++) {
343 struct security_ace *psa = &ps_dacl->aces[i];
344 uint32_t orig_mask = psa->access_mask;
346 se_map_generic(&psa->access_mask, &file_generic_mapping);
347 psa->access_mask |= orig_mask;
351 /*******************************************************************
352 Fill in a share info level 501 structure.
353 ********************************************************************/
355 static void init_srv_share_info_501(struct pipes_struct *p,
356 struct srvsvc_NetShareInfo501 *r, int snum)
358 struct dcesrv_call_state *dce_call = p->dce_call;
359 struct auth_session_info *session_info =
360 dcesrv_call_session_info(dce_call);
361 const struct loadparm_substitution *lp_sub =
362 loadparm_s3_global_substitution();
363 const char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
364 char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
366 if (remark) {
367 remark = talloc_sub_full(
368 p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
369 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
370 session_info->unix_token->uid, get_current_username(),
371 "", remark);
374 r->name = net_name;
375 r->type = get_share_type(snum);
376 r->comment = remark ? remark : "";
379 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
380 * level 1005.
382 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
385 /*******************************************************************
386 Fill in a share info level 502 structure.
387 ********************************************************************/
389 static void init_srv_share_info_502(struct pipes_struct *p,
390 struct srvsvc_NetShareInfo502 *r, int snum)
392 struct dcesrv_call_state *dce_call = p->dce_call;
393 struct auth_session_info *session_info =
394 dcesrv_call_session_info(dce_call);
395 const struct loadparm_substitution *lp_sub =
396 loadparm_s3_global_substitution();
397 const char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
398 char *path = NULL;
399 struct security_descriptor *sd = NULL;
400 struct sec_desc_buf *sd_buf = NULL;
401 size_t sd_size = 0;
402 TALLOC_CTX *ctx = p->mem_ctx;
403 char *remark = lp_comment(ctx, lp_sub, snum);
405 if (remark) {
406 remark = talloc_sub_full(
407 p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
408 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
409 session_info->unix_token->uid, get_current_username(),
410 "", remark);
412 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), lp_sub, snum));
413 if (path) {
415 * Change / to \\ so that win2k will see it as a valid path. This was added to
416 * enable use of browsing in win2k add share dialog.
418 string_replace(path, '/', '\\');
421 sd = get_share_security(ctx, lp_servicename(talloc_tos(), lp_sub, snum), &sd_size);
423 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
425 r->name = net_name;
426 r->type = get_share_type(snum);
427 r->comment = remark ? remark : "";
428 r->permissions = 0;
429 r->max_users = (uint32_t)-1;
430 r->current_users = 1; /* ??? */
431 r->path = path ? path : "";
432 r->password = "";
433 r->sd_buf = *sd_buf;
436 /***************************************************************************
437 Fill in a share info level 1004 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1004(struct pipes_struct *p,
441 struct srvsvc_NetShareInfo1004 *r,
442 int snum)
444 struct dcesrv_call_state *dce_call = p->dce_call;
445 struct auth_session_info *session_info =
446 dcesrv_call_session_info(dce_call);
447 const struct loadparm_substitution *lp_sub =
448 loadparm_s3_global_substitution();
449 char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
451 if (remark) {
452 remark = talloc_sub_full(
453 p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
454 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
455 session_info->unix_token->uid, get_current_username(),
456 "", remark);
459 r->comment = remark ? remark : "";
462 /***************************************************************************
463 Fill in a share info level 1005 structure.
464 ***************************************************************************/
466 static void init_srv_share_info_1005(struct pipes_struct *p,
467 struct srvsvc_NetShareInfo1005 *r,
468 int snum)
470 uint32_t dfs_flags = 0;
472 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
473 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
476 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
478 r->dfs_flags = dfs_flags;
481 /***************************************************************************
482 Fill in a share info level 1006 structure.
483 ***************************************************************************/
485 static void init_srv_share_info_1006(struct pipes_struct *p,
486 struct srvsvc_NetShareInfo1006 *r,
487 int snum)
489 r->max_users = (uint32_t)-1;
492 /***************************************************************************
493 Fill in a share info level 1007 structure.
494 ***************************************************************************/
496 static void init_srv_share_info_1007(struct pipes_struct *p,
497 struct srvsvc_NetShareInfo1007 *r,
498 int snum)
500 r->flags = 0;
501 r->alternate_directory_name = "";
504 /*******************************************************************
505 Fill in a share info level 1501 structure.
506 ********************************************************************/
508 static void init_srv_share_info_1501(struct pipes_struct *p,
509 struct sec_desc_buf **r,
510 int snum)
512 const struct loadparm_substitution *lp_sub =
513 loadparm_s3_global_substitution();
514 struct security_descriptor *sd;
515 struct sec_desc_buf *sd_buf = NULL;
516 size_t sd_size;
517 TALLOC_CTX *ctx = p->mem_ctx;
519 sd = get_share_security(ctx, lp_servicename(talloc_tos(), lp_sub, snum), &sd_size);
520 if (sd) {
521 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
524 *r = sd_buf;
527 /*******************************************************************
528 True if it ends in '$'.
529 ********************************************************************/
531 static bool is_hidden_share(int snum)
533 const struct loadparm_substitution *lp_sub =
534 loadparm_s3_global_substitution();
535 const char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
537 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
540 /*******************************************************************
541 Verify user is allowed to view share, access based enumeration
542 ********************************************************************/
543 static bool is_enumeration_allowed(struct pipes_struct *p,
544 int snum)
546 struct dcesrv_call_state *dce_call = p->dce_call;
547 struct auth_session_info *session_info =
548 dcesrv_call_session_info(dce_call);
549 const struct loadparm_substitution *lp_sub =
550 loadparm_s3_global_substitution();
552 if (!lp_access_based_share_enum(snum)) {
553 return true;
556 if (!user_ok_token(session_info->unix_info->unix_name,
557 session_info->info->domain_name,
558 session_info->security_token, snum)) {
559 return false;
562 return share_access_check(session_info->security_token,
563 lp_servicename(talloc_tos(), lp_sub, snum),
564 FILE_READ_DATA, NULL);
567 /****************************************************************************
568 Count an entry against the respective service.
569 ****************************************************************************/
571 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
573 union srvsvc_NetShareCtr *ctr = udp;
575 /* Only called for level2 */
576 struct srvsvc_NetShareCtr2 *ctr2 = ctr->ctr2;
578 uint32_t share_entries = ctr2->count;
579 struct srvsvc_NetShareInfo2 *info2 = ctr2->array;
580 uint32_t i = 0;
582 for (i = 0; i < share_entries; i++, info2++) {
583 if (strequal(tcon->share_name, info2->name)) {
584 info2->current_users++;
585 break;
589 return 0;
592 /****************************************************************************
593 Count the entries belonging to all services in the connection db.
594 ****************************************************************************/
596 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
598 NTSTATUS status;
599 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
601 if (!NT_STATUS_IS_OK(status)) {
602 DEBUG(0,("count_connections_for_all_shares: traverse of "
603 "smbXsrv_tcon_global.tdb failed - %s\n",
604 nt_errstr(status)));
608 /*******************************************************************
609 Fill in a share info structure.
610 ********************************************************************/
612 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
613 struct srvsvc_NetShareInfoCtr *info_ctr,
614 uint32_t *resume_handle_p,
615 uint32_t *total_entries,
616 bool all_shares)
618 struct dcesrv_call_state *dce_call = p->dce_call;
619 struct auth_session_info *session_info =
620 dcesrv_call_session_info(dce_call);
621 struct dcesrv_connection *dcesrv_conn = dce_call->conn;
622 const struct tsocket_address *local_address =
623 dcesrv_connection_get_local_address(dcesrv_conn);
624 const struct loadparm_substitution *lp_sub =
625 loadparm_s3_global_substitution();
626 uint32_t num_entries = 0;
627 uint32_t alloc_entries = 0;
628 int num_services = 0;
629 int snum;
630 TALLOC_CTX *ctx = p->mem_ctx;
631 uint32_t i = 0;
632 uint32_t valid_share_count = 0;
633 bool *allowed = 0;
634 union srvsvc_NetShareCtr ctr;
635 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
636 const char *unix_name = session_info->unix_info->unix_name;
637 int existing_home = -1;
638 int added_home = -1;
639 WERROR ret = WERR_OK;
641 DEBUG(5,("init_srv_share_info_ctr\n"));
644 * We need to make sure to reload the services for the connecting user.
645 * It is possible that we have includes with substitutions.
647 * include = /etc/samba/%U.conf
649 * We also need all printers and usershares.
651 * We need to be root in order to have access to registry shares
652 * and root only smb.conf files.
654 become_root();
655 lp_kill_all_services();
656 lp_load_with_shares(get_dyn_CONFIGFILE());
657 delete_and_reload_printers();
658 load_usershare_shares(NULL, connections_snum_used);
659 load_registry_shares();
660 existing_home = lp_servicenumber(unix_name);
661 if (existing_home == -1) {
662 added_home = register_homes_share(unix_name);
664 unbecome_root();
666 num_services = lp_numservices();
668 allowed = talloc_zero_array(ctx, bool, num_services);
669 if (allowed == NULL) {
670 goto nomem;
673 /* Count the number of entries. */
674 for (snum = 0; snum < num_services; snum++) {
675 if (lp_browseable(snum) && lp_snum_ok(snum) &&
676 lp_allow_local_address(snum, local_address) &&
677 is_enumeration_allowed(p, snum) &&
678 (all_shares || !is_hidden_share(snum))) {
679 DEBUG(10, ("counting service %s\n",
680 lp_servicename(talloc_tos(), lp_sub, snum) ? lp_servicename(talloc_tos(), lp_sub, snum) : "(null)"));
681 allowed[snum] = true;
682 num_entries++;
683 } else {
684 DEBUG(10, ("NOT counting service %s\n",
685 lp_servicename(talloc_tos(), lp_sub, snum) ? lp_servicename(talloc_tos(), lp_sub, snum) : "(null)"));
689 if (!num_entries || (resume_handle >= num_entries)) {
690 goto done;
693 /* Calculate alloc entries. */
694 alloc_entries = num_entries - resume_handle;
695 switch (info_ctr->level) {
696 case 0:
697 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
698 if (ctr.ctr0 == NULL) {
699 goto nomem;
702 ctr.ctr0->count = alloc_entries;
703 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
704 if (ctr.ctr0->array == NULL) {
705 goto nomem;
708 for (snum = 0; snum < num_services; snum++) {
709 if (allowed[snum] &&
710 (resume_handle <= (i + valid_share_count++)) ) {
711 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
715 break;
717 case 1:
718 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
719 if (ctr.ctr1 == NULL) {
720 goto nomem;
723 ctr.ctr1->count = alloc_entries;
724 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
725 if (ctr.ctr1->array == NULL) {
726 goto nomem;
729 for (snum = 0; snum < num_services; snum++) {
730 if (allowed[snum] &&
731 (resume_handle <= (i + valid_share_count++)) ) {
732 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
736 break;
738 case 2:
739 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
740 if (ctr.ctr2 == NULL) {
741 goto nomem;
744 ctr.ctr2->count = alloc_entries;
745 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
746 if (ctr.ctr2->array == NULL) {
747 goto nomem;
750 for (snum = 0; snum < num_services; snum++) {
751 if (allowed[snum] &&
752 (resume_handle <= (i + valid_share_count++)) ) {
753 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
757 count_connections_for_all_shares(&ctr);
758 break;
760 case 501:
761 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
762 if (ctr.ctr501 == NULL) {
763 goto nomem;
766 ctr.ctr501->count = alloc_entries;
767 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
768 if (ctr.ctr501->array == NULL) {
769 goto nomem;
772 for (snum = 0; snum < num_services; snum++) {
773 if (allowed[snum] &&
774 (resume_handle <= (i + valid_share_count++)) ) {
775 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
779 break;
781 case 502:
782 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
783 if (ctr.ctr502 == NULL) {
784 goto nomem;
787 ctr.ctr502->count = alloc_entries;
788 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
789 if (ctr.ctr502->array == NULL) {
790 goto nomem;
793 for (snum = 0; snum < num_services; snum++) {
794 if (allowed[snum] &&
795 (resume_handle <= (i + valid_share_count++)) ) {
796 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
800 break;
802 case 1004:
803 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
804 if (ctr.ctr1004 == NULL) {
805 goto nomem;
808 ctr.ctr1004->count = alloc_entries;
809 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
810 if (ctr.ctr1004->array == NULL) {
811 goto nomem;
814 for (snum = 0; snum < num_services; snum++) {
815 if (allowed[snum] &&
816 (resume_handle <= (i + valid_share_count++)) ) {
817 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
821 break;
823 case 1005:
824 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
825 if (ctr.ctr1005 == NULL) {
826 goto nomem;
829 ctr.ctr1005->count = alloc_entries;
830 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
831 if (ctr.ctr1005->array == NULL) {
832 goto nomem;
835 for (snum = 0; snum < num_services; snum++) {
836 if (allowed[snum] &&
837 (resume_handle <= (i + valid_share_count++)) ) {
838 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
842 break;
844 case 1006:
845 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
846 if (ctr.ctr1006 == NULL) {
847 goto nomem;
850 ctr.ctr1006->count = alloc_entries;
851 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
852 if (ctr.ctr1006->array == NULL) {
853 goto nomem;
856 for (snum = 0; snum < num_services; snum++) {
857 if (allowed[snum] &&
858 (resume_handle <= (i + valid_share_count++)) ) {
859 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
863 break;
865 case 1007:
866 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
867 if (ctr.ctr1007 == NULL) {
868 goto nomem;
871 ctr.ctr1007->count = alloc_entries;
872 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
873 if (ctr.ctr1007->array == NULL) {
874 goto nomem;
877 for (snum = 0; snum < num_services; snum++) {
878 if (allowed[snum] &&
879 (resume_handle <= (i + valid_share_count++)) ) {
880 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
884 break;
886 case 1501:
887 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
888 if (ctr.ctr1501 == NULL) {
889 goto nomem;
892 ctr.ctr1501->count = alloc_entries;
893 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
894 if (ctr.ctr1501->array == NULL) {
895 goto nomem;
898 for (snum = 0; snum < num_services; snum++) {
899 if (allowed[snum] &&
900 (resume_handle <= (i + valid_share_count++)) ) {
901 struct sec_desc_buf *sd_buf = NULL;
902 init_srv_share_info_1501(p, &sd_buf, snum);
903 ctr.ctr1501->array[i++] = *sd_buf;
907 break;
909 default:
910 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
911 info_ctr->level));
912 ret = WERR_INVALID_LEVEL;
913 goto done;
916 *total_entries = alloc_entries;
917 if (resume_handle_p) {
918 if (all_shares) {
919 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
920 } else {
921 *resume_handle_p = num_entries;
925 info_ctr->ctr = ctr;
926 ret = WERR_OK;
927 goto done;
928 nomem:
929 ret = WERR_NOT_ENOUGH_MEMORY;
930 done:
931 if (added_home != -1) {
932 lp_killservice(added_home);
934 return ret;
937 /*******************************************************************
938 fill in a sess info level 0 structure.
939 ********************************************************************/
941 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
942 struct srvsvc_NetSessCtr0 *ctr0,
943 uint32_t *resume_handle_p,
944 uint32_t *total_entries)
946 struct sessionid *session_list;
947 uint32_t num_entries = 0;
948 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
949 *total_entries = list_sessions(p->mem_ctx, &session_list);
951 DEBUG(5,("init_srv_sess_info_0\n"));
953 if (ctr0 == NULL) {
954 if (resume_handle_p) {
955 *resume_handle_p = 0;
957 return WERR_OK;
960 for (; resume_handle < *total_entries; resume_handle++) {
962 ctr0->array = talloc_realloc(p->mem_ctx,
963 ctr0->array,
964 struct srvsvc_NetSessInfo0,
965 num_entries+1);
966 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
968 ctr0->array[num_entries].client =
969 session_list[resume_handle].remote_machine;
971 num_entries++;
974 ctr0->count = num_entries;
976 if (resume_handle_p) {
977 if (*resume_handle_p >= *total_entries) {
978 *resume_handle_p = 0;
979 } else {
980 *resume_handle_p = resume_handle;
984 return WERR_OK;
987 /***********************************************************************
988 * find out the session on which this file is open and bump up its count
989 **********************************************************************/
991 static int count_sess_files_fn(struct file_id fid,
992 const struct share_mode_data *d,
993 const struct share_mode_entry *e,
994 void *data)
996 struct sess_file_info *info = data;
997 uint32_t rh = info->resume_handle;
998 uint32_t i;
1000 for (i=0; i < info->num_entries; i++) {
1001 /* rh+info->num_entries is safe, as we've
1002 ensured that:
1003 *total_entries > resume_handle &&
1004 info->num_entries = *total_entries - resume_handle;
1005 inside init_srv_sess_info_1() below.
1007 struct sessionid *sess = &info->session_list[rh + i];
1008 if ((e->uid == sess->uid) &&
1009 server_id_equal(&e->pid, &sess->pid)) {
1011 info->ctr->array[i].num_open++;
1012 return 0;
1015 return 0;
1018 /*******************************************************************
1019 * count the num of open files on all sessions
1020 *******************************************************************/
1022 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
1023 struct sessionid *session_list,
1024 uint32_t resume_handle,
1025 uint32_t num_entries)
1027 struct sess_file_info s_file_info;
1029 s_file_info.ctr = ctr1;
1030 s_file_info.session_list = session_list;
1031 s_file_info.resume_handle = resume_handle;
1032 s_file_info.num_entries = num_entries;
1034 share_entry_forall(count_sess_files_fn, &s_file_info);
1037 /*******************************************************************
1038 fill in a sess info level 1 structure.
1039 ********************************************************************/
1041 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
1042 struct srvsvc_NetSessCtr1 *ctr1,
1043 uint32_t *resume_handle_p,
1044 uint32_t *total_entries)
1046 struct sessionid *session_list;
1047 uint32_t num_entries = 0;
1048 time_t now = time(NULL);
1049 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1051 ZERO_STRUCTP(ctr1);
1053 if (ctr1 == NULL) {
1054 if (resume_handle_p) {
1055 *resume_handle_p = 0;
1057 return WERR_OK;
1060 *total_entries = list_sessions(p->mem_ctx, &session_list);
1062 if (resume_handle >= *total_entries) {
1063 if (resume_handle_p) {
1064 *resume_handle_p = 0;
1066 return WERR_OK;
1069 /* We know num_entries must be positive, due to
1070 the check resume_handle >= *total_entries above. */
1072 num_entries = *total_entries - resume_handle;
1074 ctr1->array = talloc_zero_array(p->mem_ctx,
1075 struct srvsvc_NetSessInfo1,
1076 num_entries);
1078 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1080 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
1081 uint32_t connect_time;
1082 bool guest;
1084 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
1085 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
1087 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
1088 ctr1->array[num_entries].user = session_list[resume_handle].username;
1089 ctr1->array[num_entries].num_open = 0;/* computed later */
1090 ctr1->array[num_entries].time = connect_time;
1091 ctr1->array[num_entries].idle_time = 0;
1092 ctr1->array[num_entries].user_flags = guest;
1095 ctr1->count = num_entries;
1097 /* count open files on all sessions in single tdb traversal */
1098 net_count_files_for_all_sess(ctr1, session_list,
1099 resume_handle_p ? *resume_handle_p : 0,
1100 num_entries);
1102 if (resume_handle_p) {
1103 if (*resume_handle_p >= *total_entries) {
1104 *resume_handle_p = 0;
1105 } else {
1106 *resume_handle_p = resume_handle;
1110 return WERR_OK;
1113 /*******************************************************************
1114 find the share connection on which this open exists.
1115 ********************************************************************/
1117 static int share_file_fn(struct file_id fid,
1118 const struct share_mode_data *d,
1119 const struct share_mode_entry *e,
1120 void *data)
1122 struct share_file_stat *sfs = data;
1123 uint32_t i;
1124 uint32_t offset = sfs->total_entries - sfs->resp_entries;
1126 if (strequal(d->servicepath, sfs->in_sharepath)) {
1127 for (i=0; i < sfs->resp_entries; i++) {
1128 if (server_id_equal(
1129 &e->pid, &sfs->svrid_arr[offset + i])) {
1130 sfs->netconn_arr[i].num_open ++;
1131 return 0;
1135 return 0;
1138 /*******************************************************************
1139 count number of open files on given share connections.
1140 ********************************************************************/
1142 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
1143 struct server_id *svrid_arr, char *sharepath,
1144 uint32_t resp_entries, uint32_t total_entries)
1146 struct share_file_stat sfs;
1148 sfs.netconn_arr = arr;
1149 sfs.svrid_arr = svrid_arr;
1150 sfs.in_sharepath = sharepath;
1151 sfs.resp_entries = resp_entries;
1152 sfs.total_entries = total_entries;
1154 share_entry_forall(share_file_fn, &sfs);
1157 /****************************************************************************
1158 process an entry from the connection db.
1159 ****************************************************************************/
1161 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
1162 void *data)
1164 struct share_conn_stat *scs = data;
1166 if (!process_exists(tcon->server_id)) {
1167 return 0;
1170 if (strequal(tcon->share_name, scs->sharename)) {
1171 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1172 struct server_id,
1173 scs->count + 1);
1174 if (!scs->svrid_arr) {
1175 return 0;
1178 scs->svrid_arr[scs->count] = tcon->server_id;
1179 scs->count++;
1182 return 0;
1185 /****************************************************************************
1186 Count the connections to a share. Build an array of serverid's owning these
1187 connections.
1188 ****************************************************************************/
1190 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1191 struct server_id **arr)
1193 struct share_conn_stat scs;
1194 NTSTATUS status;
1196 scs.ctx = ctx;
1197 scs.sharename = sharename;
1198 scs.svrid_arr = NULL;
1199 scs.count = 0;
1201 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 DEBUG(0,("count_share_conns: traverse of "
1205 "smbXsrv_tcon_global.tdb failed - %s\n",
1206 nt_errstr(status)));
1207 return 0;
1210 *arr = scs.svrid_arr;
1211 return scs.count;
1214 /*******************************************************************
1215 fill in a conn info level 0 structure.
1216 ********************************************************************/
1218 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1219 uint32_t *resume_handle_p,
1220 uint32_t *total_entries)
1222 uint32_t num_entries = 0;
1223 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1225 DEBUG(5,("init_srv_conn_info_0\n"));
1227 if (ctr0 == NULL) {
1228 if (resume_handle_p) {
1229 *resume_handle_p = 0;
1231 return WERR_OK;
1234 *total_entries = 1;
1236 ZERO_STRUCTP(ctr0);
1238 for (; resume_handle < *total_entries; resume_handle++) {
1240 ctr0->array = talloc_realloc(talloc_tos(),
1241 ctr0->array,
1242 struct srvsvc_NetConnInfo0,
1243 num_entries+1);
1244 if (!ctr0->array) {
1245 return WERR_NOT_ENOUGH_MEMORY;
1248 ctr0->array[num_entries].conn_id = *total_entries;
1250 /* move on to creating next connection */
1251 num_entries++;
1254 ctr0->count = num_entries;
1255 *total_entries = num_entries;
1257 if (resume_handle_p) {
1258 if (*resume_handle_p >= *total_entries) {
1259 *resume_handle_p = 0;
1260 } else {
1261 *resume_handle_p = resume_handle;
1265 return WERR_OK;
1268 /*******************************************************************
1269 fill in a conn info level 1 structure.
1270 ********************************************************************/
1272 static WERROR init_srv_conn_info_1(const char *name,
1273 struct srvsvc_NetConnCtr1 *ctr1,
1274 uint32_t *resume_handle_p,
1275 uint32_t *total_entries)
1277 const struct loadparm_substitution *lp_sub =
1278 loadparm_s3_global_substitution();
1279 uint32_t num_entries = 0;
1280 int snum = 0;
1281 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1282 char *share_name = NULL;
1283 struct server_id *svrid_arr = NULL;
1285 DEBUG(5,("init_srv_conn_info_1\n"));
1287 if (ctr1 == NULL) {
1288 if (resume_handle_p) {
1289 *resume_handle_p = 0;
1291 return WERR_OK;
1294 /* check if this is a server name or a share name */
1295 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1296 (name[1] == '\\')) {
1298 /* 'name' is a server name - this part is unimplemented */
1299 *total_entries = 1;
1300 } else {
1301 /* 'name' is a share name */
1302 snum = find_service(talloc_tos(), name, &share_name);
1304 if (!share_name) {
1305 return WERR_NOT_ENOUGH_MEMORY;
1308 if (snum < 0) {
1309 return WERR_INVALID_NAME;
1313 * count the num of connections to this share. Also,
1314 * build a list of serverid's that own these
1315 * connections. The serverid list is used later to
1316 * identify the share connection on which an open exists.
1319 *total_entries = count_share_conns(talloc_tos(),
1320 share_name,
1321 &svrid_arr);
1324 if (resume_handle >= *total_entries) {
1325 if (resume_handle_p) {
1326 *resume_handle_p = 0;
1328 return WERR_OK;
1332 * We know num_entries must be positive, due to
1333 * the check resume_handle >= *total_entries above.
1336 num_entries = *total_entries - resume_handle;
1338 ZERO_STRUCTP(ctr1);
1340 ctr1->array = talloc_zero_array(talloc_tos(),
1341 struct srvsvc_NetConnInfo1,
1342 num_entries);
1344 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1346 for (num_entries = 0; resume_handle < *total_entries;
1347 num_entries++, resume_handle++) {
1349 ctr1->array[num_entries].conn_id = *total_entries;
1350 ctr1->array[num_entries].conn_type = 0x3;
1353 * if these are connections to a share, we are going to
1354 * compute the opens on them later. If it's for the server,
1355 * it's unimplemented.
1358 if (!share_name) {
1359 ctr1->array[num_entries].num_open = 1;
1362 ctr1->array[num_entries].num_users = 1;
1363 ctr1->array[num_entries].conn_time = 3;
1364 ctr1->array[num_entries].user = "dummy_user";
1365 ctr1->array[num_entries].share = "IPC$";
1368 /* now compute open files on the share connections */
1370 if (share_name) {
1373 * the locking tdb, which has the open files information,
1374 * does not store share name or share (service) number, but
1375 * just the share path. So, we can compute open files only
1376 * on the share path. If more than one shares are defined
1377 * on a share path, open files on all of them are included
1378 * in the count.
1380 * To have the correct behavior in case multiple shares
1381 * are defined on the same path, changes to tdb records
1382 * would be required. That would be lot more effort, so
1383 * this seems a good stopgap fix.
1386 count_share_opens(ctr1->array, svrid_arr,
1387 lp_path(talloc_tos(), lp_sub, snum),
1388 num_entries, *total_entries);
1392 ctr1->count = num_entries;
1393 *total_entries = num_entries;
1395 if (resume_handle_p) {
1396 *resume_handle_p = resume_handle;
1399 return WERR_OK;
1402 /*******************************************************************
1403 _srvsvc_NetFileEnum
1404 *******************************************************************/
1406 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1407 struct srvsvc_NetFileEnum *r)
1409 struct dcesrv_call_state *dce_call = p->dce_call;
1410 struct auth_session_info *session_info =
1411 dcesrv_call_session_info(dce_call);
1412 TALLOC_CTX *ctx = NULL;
1413 struct srvsvc_NetFileCtr3 *ctr3;
1414 uint32_t resume_hnd = 0;
1415 WERROR werr;
1417 switch (r->in.info_ctr->level) {
1418 case 3:
1419 break;
1420 default:
1421 return WERR_INVALID_LEVEL;
1424 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1425 session_info->security_token)) {
1426 DEBUG(1, ("Enumerating files only allowed for "
1427 "administrators\n"));
1428 return WERR_ACCESS_DENIED;
1431 ctx = talloc_tos();
1432 ctr3 = r->in.info_ctr->ctr.ctr3;
1433 if (!ctr3) {
1434 werr = WERR_INVALID_PARAMETER;
1435 goto done;
1438 /* TODO -- Windows enumerates
1439 (b) active pipes
1440 (c) open directories and files */
1442 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1443 if (!W_ERROR_IS_OK(werr)) {
1444 goto done;
1447 *r->out.totalentries = ctr3->count;
1448 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1449 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1451 werr = WERR_OK;
1453 done:
1454 return werr;
1457 /*******************************************************************
1458 _srvsvc_NetSrvGetInfo
1459 ********************************************************************/
1461 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1462 struct srvsvc_NetSrvGetInfo *r)
1464 const struct loadparm_substitution *lp_sub =
1465 loadparm_s3_global_substitution();
1466 WERROR status = WERR_OK;
1468 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1470 if (!pipe_access_check(p)) {
1471 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1472 return WERR_ACCESS_DENIED;
1475 switch (r->in.level) {
1477 /* Technically level 102 should only be available to
1478 Administrators but there isn't anything super-secret
1479 here, as most of it is made up. */
1481 case 102: {
1482 struct srvsvc_NetSrvInfo102 *info102;
1484 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1485 if (!info102) {
1486 return WERR_NOT_ENOUGH_MEMORY;
1489 info102->platform_id = PLATFORM_ID_NT;
1490 info102->server_name = lp_netbios_name();
1491 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1492 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1493 info102->server_type = lp_default_server_announce();
1494 info102->comment =
1495 string_truncate(lp_server_string(info102, lp_sub),
1496 MAX_SERVER_STRING_LENGTH);
1497 info102->users = 0xffffffff;
1498 info102->disc = 0xf;
1499 info102->hidden = 0;
1500 info102->announce = 240;
1501 info102->anndelta = 3000;
1502 info102->licenses = 100000;
1503 info102->userpath = "C:\\";
1505 r->out.info->info102 = info102;
1506 break;
1508 case 101: {
1509 struct srvsvc_NetSrvInfo101 *info101;
1511 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1512 if (!info101) {
1513 return WERR_NOT_ENOUGH_MEMORY;
1516 info101->platform_id = PLATFORM_ID_NT;
1517 info101->server_name = lp_netbios_name();
1518 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1519 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1520 info101->server_type = lp_default_server_announce();
1521 info101->comment =
1522 string_truncate(lp_server_string(info101, lp_sub),
1523 MAX_SERVER_STRING_LENGTH);
1525 r->out.info->info101 = info101;
1526 break;
1528 case 100: {
1529 struct srvsvc_NetSrvInfo100 *info100;
1531 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1532 if (!info100) {
1533 return WERR_NOT_ENOUGH_MEMORY;
1536 info100->platform_id = PLATFORM_ID_NT;
1537 info100->server_name = lp_netbios_name();
1539 r->out.info->info100 = info100;
1541 break;
1543 default:
1544 status = WERR_INVALID_LEVEL;
1545 break;
1548 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1550 return status;
1553 /*******************************************************************
1554 _srvsvc_NetSrvSetInfo
1555 ********************************************************************/
1557 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1558 struct srvsvc_NetSrvSetInfo *r)
1560 WERROR status = WERR_OK;
1562 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1564 /* Set up the net server set info structure. */
1566 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1568 return status;
1571 /*******************************************************************
1572 _srvsvc_NetConnEnum
1573 ********************************************************************/
1575 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1576 struct srvsvc_NetConnEnum *r)
1578 struct dcesrv_call_state *dce_call = p->dce_call;
1579 struct auth_session_info *session_info =
1580 dcesrv_call_session_info(dce_call);
1581 WERROR werr;
1583 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1585 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1586 session_info->security_token)) {
1587 DEBUG(1, ("Enumerating connections only allowed for "
1588 "administrators\n"));
1589 return WERR_ACCESS_DENIED;
1592 switch (r->in.info_ctr->level) {
1593 case 0:
1594 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1595 r->in.resume_handle,
1596 r->out.totalentries);
1597 break;
1598 case 1:
1599 werr = init_srv_conn_info_1(r->in.path,
1600 r->in.info_ctr->ctr.ctr1,
1601 r->in.resume_handle,
1602 r->out.totalentries);
1603 break;
1604 default:
1605 return WERR_INVALID_LEVEL;
1608 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1610 return werr;
1613 /*******************************************************************
1614 _srvsvc_NetSessEnum
1615 ********************************************************************/
1617 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1618 struct srvsvc_NetSessEnum *r)
1620 struct dcesrv_call_state *dce_call = p->dce_call;
1621 struct auth_session_info *session_info =
1622 dcesrv_call_session_info(dce_call);
1623 WERROR werr;
1625 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1627 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1628 session_info->security_token)) {
1629 DEBUG(1, ("Enumerating sessions only allowed for "
1630 "administrators\n"));
1631 return WERR_ACCESS_DENIED;
1634 switch (r->in.info_ctr->level) {
1635 case 0:
1636 werr = init_srv_sess_info_0(p,
1637 r->in.info_ctr->ctr.ctr0,
1638 r->in.resume_handle,
1639 r->out.totalentries);
1640 break;
1641 case 1:
1642 werr = init_srv_sess_info_1(p,
1643 r->in.info_ctr->ctr.ctr1,
1644 r->in.resume_handle,
1645 r->out.totalentries);
1646 break;
1647 default:
1648 return WERR_INVALID_LEVEL;
1651 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1653 return werr;
1656 /*******************************************************************
1657 _srvsvc_NetSessDel
1658 ********************************************************************/
1660 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1661 struct srvsvc_NetSessDel *r)
1663 struct dcesrv_call_state *dce_call = p->dce_call;
1664 struct auth_session_info *session_info =
1665 dcesrv_call_session_info(dce_call);
1666 struct sessionid *session_list;
1667 int num_sessions, snum;
1668 const char *username;
1669 const char *machine;
1670 bool not_root = False;
1671 WERROR werr;
1673 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1675 werr = WERR_ACCESS_DENIED;
1677 /* fail out now if you are not root or not a domain admin */
1679 if ((session_info->unix_token->uid != sec_initial_uid()) &&
1680 ( ! nt_token_check_domain_rid(session_info->security_token,
1681 DOMAIN_RID_ADMINS))) {
1683 goto done;
1686 username = r->in.user;
1687 machine = r->in.client;
1689 /* strip leading backslashes if any */
1690 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1691 machine += 2;
1694 num_sessions = find_sessions(p->mem_ctx, username, machine,
1695 &session_list);
1697 for (snum = 0; snum < num_sessions; snum++) {
1699 NTSTATUS ntstat;
1701 if (session_info->unix_token->uid != sec_initial_uid()) {
1702 not_root = True;
1703 become_root();
1706 ntstat = messaging_send(p->msg_ctx,
1707 session_list[snum].pid,
1708 MSG_SHUTDOWN, &data_blob_null);
1710 if (NT_STATUS_IS_OK(ntstat))
1711 werr = WERR_OK;
1713 if (not_root)
1714 unbecome_root();
1717 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1719 done:
1721 return werr;
1724 /*******************************************************************
1725 _srvsvc_NetShareEnumAll
1726 ********************************************************************/
1728 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1729 struct srvsvc_NetShareEnumAll *r)
1731 WERROR werr;
1733 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1735 if (!pipe_access_check(p)) {
1736 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1737 return WERR_ACCESS_DENIED;
1740 /* Create the list of shares for the response. */
1741 werr = init_srv_share_info_ctr(p,
1742 r->in.info_ctr,
1743 r->in.resume_handle,
1744 r->out.totalentries,
1745 true);
1747 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1749 return werr;
1752 /*******************************************************************
1753 _srvsvc_NetShareEnum
1754 ********************************************************************/
1756 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1757 struct srvsvc_NetShareEnum *r)
1759 WERROR werr;
1761 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1763 if (!pipe_access_check(p)) {
1764 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1765 return WERR_ACCESS_DENIED;
1768 /* Create the list of shares for the response. */
1769 werr = init_srv_share_info_ctr(p,
1770 r->in.info_ctr,
1771 r->in.resume_handle,
1772 r->out.totalentries,
1773 false);
1775 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1777 return werr;
1780 /*******************************************************************
1781 _srvsvc_NetShareGetInfo
1782 ********************************************************************/
1784 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1785 struct srvsvc_NetShareGetInfo *r)
1787 WERROR status = WERR_OK;
1788 char *share_name = NULL;
1789 int snum;
1790 union srvsvc_NetShareInfo *info = r->out.info;
1792 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1794 if (!r->in.share_name) {
1795 return WERR_INVALID_NAME;
1798 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1799 if (!share_name) {
1800 return WERR_NOT_ENOUGH_MEMORY;
1802 if (snum < 0) {
1803 return WERR_INVALID_NAME;
1806 switch (r->in.level) {
1807 case 0:
1808 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1809 W_ERROR_HAVE_NO_MEMORY(info->info0);
1810 init_srv_share_info_0(p, info->info0, snum);
1811 break;
1812 case 1:
1813 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1814 W_ERROR_HAVE_NO_MEMORY(info->info1);
1815 init_srv_share_info_1(p, info->info1, snum);
1816 break;
1817 case 2:
1818 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1819 W_ERROR_HAVE_NO_MEMORY(info->info2);
1820 init_srv_share_info_2(p, info->info2, snum);
1821 info->info2->current_users =
1822 count_current_connections(info->info2->name, false);
1823 break;
1824 case 501:
1825 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1826 W_ERROR_HAVE_NO_MEMORY(info->info501);
1827 init_srv_share_info_501(p, info->info501, snum);
1828 break;
1829 case 502:
1830 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1831 W_ERROR_HAVE_NO_MEMORY(info->info502);
1832 init_srv_share_info_502(p, info->info502, snum);
1833 break;
1834 case 1004:
1835 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1836 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1837 init_srv_share_info_1004(p, info->info1004, snum);
1838 break;
1839 case 1005:
1840 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1841 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1842 init_srv_share_info_1005(p, info->info1005, snum);
1843 break;
1844 case 1006:
1845 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1846 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1847 init_srv_share_info_1006(p, info->info1006, snum);
1848 break;
1849 case 1007:
1850 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1851 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1852 init_srv_share_info_1007(p, info->info1007, snum);
1853 break;
1854 case 1501:
1855 init_srv_share_info_1501(p, &info->info1501, snum);
1856 break;
1857 default:
1858 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1859 r->in.level));
1860 status = WERR_INVALID_LEVEL;
1861 break;
1864 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1866 return status;
1869 /*******************************************************************
1870 _srvsvc_NetShareSetInfo. Modify share details.
1871 ********************************************************************/
1873 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1874 struct srvsvc_NetShareSetInfo *r)
1876 struct dcesrv_call_state *dce_call = p->dce_call;
1877 struct auth_session_info *session_info =
1878 dcesrv_call_session_info(dce_call);
1879 const struct loadparm_substitution *lp_sub =
1880 loadparm_s3_global_substitution();
1881 char *command = NULL;
1882 char *share_name = NULL;
1883 char *comment = NULL;
1884 const char *pathname = NULL;
1885 int type;
1886 int snum;
1887 int ret;
1888 char *path = NULL;
1889 struct security_descriptor *psd = NULL;
1890 bool is_disk_op = False;
1891 const char *csc_policy = NULL;
1892 bool csc_policy_changed = false;
1893 const char *csc_policies[] = {"manual", "documents", "programs",
1894 "disable"};
1895 uint32_t client_csc_policy;
1896 int max_connections = 0;
1897 TALLOC_CTX *ctx = p->mem_ctx;
1898 union srvsvc_NetShareInfo *info = r->in.info;
1900 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1902 if (!r->in.share_name) {
1903 return WERR_INVALID_NAME;
1906 if (r->out.parm_error) {
1907 *r->out.parm_error = 0;
1910 if ( strequal(r->in.share_name,"IPC$")
1911 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1912 || strequal(r->in.share_name,"global") )
1914 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1915 "modified by a remote user.\n",
1916 r->in.share_name ));
1917 return WERR_ACCESS_DENIED;
1920 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1921 if (!share_name) {
1922 return WERR_NOT_ENOUGH_MEMORY;
1925 /* Does this share exist ? */
1926 if (snum < 0)
1927 return WERR_NERR_NETNAMENOTFOUND;
1929 /* No change to printer shares. */
1930 if (lp_printable(snum))
1931 return WERR_ACCESS_DENIED;
1933 is_disk_op = security_token_has_privilege(
1934 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1936 /* fail out now if you are not root and not a disk op */
1938 if (session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
1939 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1940 "SeDiskOperatorPrivilege privilege needed to modify "
1941 "share %s\n",
1942 (unsigned int)session_info->unix_token->uid,
1943 share_name ));
1944 return WERR_ACCESS_DENIED;
1947 max_connections = lp_max_connections(snum);
1948 csc_policy = csc_policies[lp_csc_policy(snum)];
1950 switch (r->in.level) {
1951 case 1:
1952 pathname = lp_path(ctx, lp_sub, snum);
1953 comment = talloc_strdup(ctx, info->info1->comment);
1954 type = info->info1->type;
1955 psd = NULL;
1956 break;
1957 case 2:
1958 comment = talloc_strdup(ctx, info->info2->comment);
1959 pathname = info->info2->path;
1960 type = info->info2->type;
1961 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1962 0 : info->info2->max_users;
1963 psd = NULL;
1964 break;
1965 #if 0
1966 /* not supported on set but here for completeness */
1967 case 501:
1968 comment = talloc_strdup(ctx, info->info501->comment);
1969 type = info->info501->type;
1970 psd = NULL;
1971 break;
1972 #endif
1973 case 502:
1974 comment = talloc_strdup(ctx, info->info502->comment);
1975 pathname = info->info502->path;
1976 type = info->info502->type;
1977 psd = info->info502->sd_buf.sd;
1978 map_generic_share_sd_bits(psd);
1979 break;
1980 case 1004:
1981 pathname = lp_path(ctx, lp_sub, snum);
1982 comment = talloc_strdup(ctx, info->info1004->comment);
1983 type = STYPE_DISKTREE;
1984 break;
1985 case 1005:
1986 /* XP re-sets the csc policy even if it wasn't changed by the
1987 user, so we must compare it to see if it's what is set in
1988 smb.conf, so that we can continue other ops like setting
1989 ACLs on a share */
1990 client_csc_policy = (info->info1005->dfs_flags &
1991 SHARE_1005_CSC_POLICY_MASK) >>
1992 SHARE_1005_CSC_POLICY_SHIFT;
1994 if (client_csc_policy == (uint32_t)lp_csc_policy(snum)) {
1995 return WERR_OK;
1998 csc_policy = csc_policies[client_csc_policy];
1999 csc_policy_changed = true;
2001 pathname = lp_path(ctx, lp_sub, snum);
2002 comment = lp_comment(ctx, lp_sub, snum);
2003 type = STYPE_DISKTREE;
2004 break;
2005 case 1006:
2006 case 1007:
2007 return WERR_ACCESS_DENIED;
2008 case 1501:
2009 pathname = lp_path(ctx, lp_sub, snum);
2010 comment = lp_comment(ctx, lp_sub, snum);
2011 psd = info->info1501->sd;
2012 map_generic_share_sd_bits(psd);
2013 type = STYPE_DISKTREE;
2014 break;
2015 default:
2016 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
2017 r->in.level));
2018 return WERR_INVALID_LEVEL;
2021 /* We can only modify disk shares. */
2022 if (type != STYPE_DISKTREE) {
2023 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
2024 "disk share\n",
2025 share_name ));
2026 return WERR_ACCESS_DENIED;
2029 if (comment == NULL) {
2030 return WERR_NOT_ENOUGH_MEMORY;
2033 /* Check if the pathname is valid. */
2034 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
2035 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
2036 pathname ));
2037 return WERR_BAD_PATHNAME;
2040 /* Ensure share name, pathname and comment don't contain '"' characters. */
2041 string_replace(share_name, '"', ' ');
2042 string_replace(path, '"', ' ');
2043 string_replace(comment, '"', ' ');
2045 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
2046 lp_change_share_command(talloc_tos(), lp_sub) ? lp_change_share_command(talloc_tos(), lp_sub) : "NULL" ));
2048 /* Only call modify function if something changed. */
2050 if (strcmp(path, lp_path(talloc_tos(), lp_sub, snum))
2051 || strcmp(comment, lp_comment(talloc_tos(), lp_sub, snum))
2052 || (lp_max_connections(snum) != max_connections)
2053 || csc_policy_changed) {
2055 if (!lp_change_share_command(talloc_tos(), lp_sub) || !*lp_change_share_command(talloc_tos(), lp_sub)) {
2056 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
2057 return WERR_ACCESS_DENIED;
2060 command = talloc_asprintf(p->mem_ctx,
2061 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
2062 lp_change_share_command(talloc_tos(), lp_sub),
2063 get_dyn_CONFIGFILE(),
2064 share_name,
2065 path,
2066 comment,
2067 max_connections,
2068 csc_policy);
2069 if (!command) {
2070 return WERR_NOT_ENOUGH_MEMORY;
2073 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
2075 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2077 if (is_disk_op)
2078 become_root();
2080 ret = smbrun(command, NULL, NULL);
2081 if (ret == 0) {
2082 reload_services(NULL, NULL, false);
2084 /* Tell everyone we updated smb.conf. */
2085 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
2086 NULL, 0);
2089 if ( is_disk_op )
2090 unbecome_root();
2092 /********* END SeDiskOperatorPrivilege BLOCK *********/
2094 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
2095 command, ret ));
2097 TALLOC_FREE(command);
2099 if ( ret != 0 )
2100 return WERR_ACCESS_DENIED;
2101 } else {
2102 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
2103 share_name ));
2106 /* Replace SD if changed. */
2107 if (psd) {
2108 struct security_descriptor *old_sd;
2109 size_t sd_size;
2110 NTSTATUS status;
2112 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum), &sd_size);
2114 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
2115 status = set_share_security(share_name, psd);
2116 if (!NT_STATUS_IS_OK(status)) {
2117 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
2118 share_name ));
2123 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
2125 return WERR_OK;
2128 /*******************************************************************
2129 _srvsvc_NetShareAdd.
2130 Call 'add_share_command "sharename" "pathname"
2131 "comment" "max connections = "
2132 ********************************************************************/
2134 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
2135 struct srvsvc_NetShareAdd *r)
2137 struct dcesrv_call_state *dce_call = p->dce_call;
2138 struct auth_session_info *session_info =
2139 dcesrv_call_session_info(dce_call);
2140 char *command = NULL;
2141 char *share_name_in = NULL;
2142 char *share_name = NULL;
2143 char *comment = NULL;
2144 char *pathname = NULL;
2145 int type;
2146 int snum;
2147 int ret;
2148 char *path;
2149 struct security_descriptor *psd = NULL;
2150 bool is_disk_op;
2151 int max_connections = 0;
2152 SMB_STRUCT_STAT st;
2153 TALLOC_CTX *ctx = p->mem_ctx;
2154 const struct loadparm_substitution *lp_sub =
2155 loadparm_s3_global_substitution();
2157 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2159 if (r->out.parm_error) {
2160 *r->out.parm_error = 0;
2163 is_disk_op = security_token_has_privilege(
2164 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2166 if (session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2167 return WERR_ACCESS_DENIED;
2170 if (!lp_add_share_command(talloc_tos(), lp_sub) || !*lp_add_share_command(talloc_tos(), lp_sub)) {
2171 DBG_WARNING("_srvsvc_NetShareAdd: No \"add share command\" parameter set in smb.conf.\n");
2172 return WERR_ACCESS_DENIED;
2175 switch (r->in.level) {
2176 case 0:
2177 /* No path. Not enough info in a level 0 to do anything. */
2178 return WERR_ACCESS_DENIED;
2179 case 1:
2180 /* Not enough info in a level 1 to do anything. */
2181 return WERR_ACCESS_DENIED;
2182 case 2:
2183 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
2184 comment = talloc_strdup(ctx, r->in.info->info2->comment);
2185 pathname = talloc_strdup(ctx, r->in.info->info2->path);
2186 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
2187 0 : r->in.info->info2->max_users;
2188 type = r->in.info->info2->type;
2189 break;
2190 case 501:
2191 /* No path. Not enough info in a level 501 to do anything. */
2192 return WERR_ACCESS_DENIED;
2193 case 502:
2194 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2195 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2196 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2197 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2198 0 : r->in.info->info502->max_users;
2199 type = r->in.info->info502->type;
2200 psd = r->in.info->info502->sd_buf.sd;
2201 map_generic_share_sd_bits(psd);
2202 break;
2204 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2206 case 1004:
2207 case 1005:
2208 case 1006:
2209 case 1007:
2210 return WERR_ACCESS_DENIED;
2211 case 1501:
2212 /* DFS only level. */
2213 return WERR_ACCESS_DENIED;
2214 default:
2215 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2216 r->in.level));
2217 return WERR_INVALID_LEVEL;
2220 /* check for invalid share names */
2222 if (!share_name_in || !validate_net_name(share_name_in,
2223 INVALID_SHARENAME_CHARS,
2224 strlen(share_name_in))) {
2225 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2226 share_name_in ? share_name_in : ""));
2227 return WERR_INVALID_NAME;
2230 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2231 || (lp_enable_asu_support() &&
2232 strequal(share_name_in,"ADMIN$"))) {
2233 return WERR_ACCESS_DENIED;
2236 snum = find_service(ctx, share_name_in, &share_name);
2237 if (!share_name) {
2238 return WERR_NOT_ENOUGH_MEMORY;
2241 /* Share already exists. */
2242 if (snum >= 0) {
2243 return WERR_FILE_EXISTS;
2246 /* We can only add disk shares. */
2247 if (type != STYPE_DISKTREE) {
2248 return WERR_ACCESS_DENIED;
2251 /* Check if the pathname is valid. */
2252 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2253 return WERR_BAD_PATHNAME;
2256 ret = sys_lstat(path, &st, false);
2257 if (ret == -1 && (errno != EACCES)) {
2259 * If path has any other than permission
2260 * problem, return WERR_FILE_NOT_FOUND (as Windows
2261 * does.
2263 return WERR_FILE_NOT_FOUND;
2266 /* Ensure share name, pathname and comment don't contain '"' characters. */
2267 string_replace(share_name_in, '"', ' ');
2268 string_replace(share_name, '"', ' ');
2269 string_replace(path, '"', ' ');
2270 if (comment) {
2271 string_replace(comment, '"', ' ');
2274 command = talloc_asprintf(ctx,
2275 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2276 lp_add_share_command(talloc_tos(), lp_sub),
2277 get_dyn_CONFIGFILE(),
2278 share_name_in,
2279 path,
2280 comment ? comment : "",
2281 max_connections);
2282 if (!command) {
2283 return WERR_NOT_ENOUGH_MEMORY;
2286 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2288 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2290 if ( is_disk_op )
2291 become_root();
2293 /* FIXME: use libnetconf here - gd */
2295 ret = smbrun(command, NULL, NULL);
2296 if (ret == 0) {
2297 /* Tell everyone we updated smb.conf. */
2298 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
2301 if ( is_disk_op )
2302 unbecome_root();
2304 /********* END SeDiskOperatorPrivilege BLOCK *********/
2306 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2307 command, ret ));
2309 TALLOC_FREE(command);
2311 if ( ret != 0 )
2312 return WERR_ACCESS_DENIED;
2314 if (psd) {
2315 NTSTATUS status;
2316 /* Note we use share_name here, not share_name_in as
2317 we need a canonicalized name for setting security. */
2318 status = set_share_security(share_name, psd);
2319 if (!NT_STATUS_IS_OK(status)) {
2320 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2321 share_name ));
2326 * We don't call reload_services() here, the message will
2327 * cause this to be done before the next packet is read
2328 * from the client. JRA.
2331 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2333 return WERR_OK;
2336 /*******************************************************************
2337 _srvsvc_NetShareDel
2338 Call "delete share command" with the share name as
2339 a parameter.
2340 ********************************************************************/
2342 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2343 struct srvsvc_NetShareDel *r)
2345 struct dcesrv_call_state *dce_call = p->dce_call;
2346 struct auth_session_info *session_info =
2347 dcesrv_call_session_info(dce_call);
2348 char *command = NULL;
2349 char *share_name = NULL;
2350 int ret;
2351 int snum;
2352 bool is_disk_op;
2353 TALLOC_CTX *ctx = p->mem_ctx;
2354 const struct loadparm_substitution *lp_sub =
2355 loadparm_s3_global_substitution();
2357 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2359 if (!r->in.share_name) {
2360 return WERR_NERR_NETNAMENOTFOUND;
2363 if ( strequal(r->in.share_name,"IPC$")
2364 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2365 || strequal(r->in.share_name,"global") )
2367 return WERR_ACCESS_DENIED;
2370 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2371 if (!share_name) {
2372 return WERR_NOT_ENOUGH_MEMORY;
2375 if (snum < 0) {
2376 return WERR_BAD_NET_NAME;
2379 /* No change to printer shares. */
2380 if (lp_printable(snum))
2381 return WERR_ACCESS_DENIED;
2383 is_disk_op = security_token_has_privilege(
2384 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2386 if (session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2387 return WERR_ACCESS_DENIED;
2390 if (!lp_delete_share_command(talloc_tos(), lp_sub) || !*lp_delete_share_command(talloc_tos(), lp_sub)) {
2391 DBG_WARNING("_srvsvc_NetShareDel: No \"delete share command\" parameter set in smb.conf.\n");
2392 return WERR_ACCESS_DENIED;
2395 command = talloc_asprintf(ctx,
2396 "%s \"%s\" \"%s\"",
2397 lp_delete_share_command(talloc_tos(), lp_sub),
2398 get_dyn_CONFIGFILE(),
2399 share_name);
2400 if (!command) {
2401 return WERR_NOT_ENOUGH_MEMORY;
2404 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2406 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2408 if ( is_disk_op )
2409 become_root();
2411 ret = smbrun(command, NULL, NULL);
2412 if (ret == 0) {
2413 /* Tell everyone we updated smb.conf. */
2414 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
2417 if ( is_disk_op )
2418 unbecome_root();
2420 /********* END SeDiskOperatorPrivilege BLOCK *********/
2422 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2424 if ( ret != 0 )
2425 return WERR_ACCESS_DENIED;
2427 /* Delete the SD in the database. */
2428 delete_share_security(share_name);
2430 lp_killservice(snum);
2432 return WERR_OK;
2435 /*******************************************************************
2436 _srvsvc_NetShareDelSticky
2437 ********************************************************************/
2439 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2440 struct srvsvc_NetShareDelSticky *r)
2442 struct srvsvc_NetShareDel q;
2444 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2446 q.in.server_unc = r->in.server_unc;
2447 q.in.share_name = r->in.share_name;
2448 q.in.reserved = r->in.reserved;
2450 return _srvsvc_NetShareDel(p, &q);
2453 /*******************************************************************
2454 _srvsvc_NetRemoteTOD
2455 ********************************************************************/
2457 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2458 struct srvsvc_NetRemoteTOD *r)
2460 struct srvsvc_NetRemoteTODInfo *tod;
2461 struct tm *t;
2462 time_t unixdate = time(NULL);
2464 /* We do this call first as if we do it *after* the gmtime call
2465 it overwrites the pointed-to values. JRA */
2467 uint32_t zone = get_time_zone(unixdate)/60;
2469 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2471 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2472 return WERR_NOT_ENOUGH_MEMORY;
2474 *r->out.info = tod;
2476 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2478 t = gmtime(&unixdate);
2480 /* set up the */
2481 tod->elapsed = unixdate;
2482 tod->msecs = 0;
2483 tod->hours = t->tm_hour;
2484 tod->mins = t->tm_min;
2485 tod->secs = t->tm_sec;
2486 tod->hunds = 0;
2487 tod->timezone = zone;
2488 tod->tinterval = 10000;
2489 tod->day = t->tm_mday;
2490 tod->month = t->tm_mon + 1;
2491 tod->year = 1900+t->tm_year;
2492 tod->weekday = t->tm_wday;
2494 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2496 return WERR_OK;
2499 /***********************************************************************************
2500 _srvsvc_NetGetFileSecurity
2501 Win9x NT tools get security descriptor.
2502 ***********************************************************************************/
2504 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2505 struct srvsvc_NetGetFileSecurity *r)
2507 struct dcesrv_call_state *dce_call = p->dce_call;
2508 struct auth_session_info *session_info =
2509 dcesrv_call_session_info(dce_call);
2510 TALLOC_CTX *frame = talloc_stackframe();
2511 const struct loadparm_substitution *lp_sub =
2512 loadparm_s3_global_substitution();
2513 struct smb_filename *smb_fname = NULL;
2514 size_t sd_size;
2515 char *servicename = NULL;
2516 SMB_STRUCT_STAT st;
2517 NTSTATUS nt_status;
2518 WERROR werr;
2519 struct conn_struct_tos *c = NULL;
2520 connection_struct *conn = NULL;
2521 struct sec_desc_buf *sd_buf = NULL;
2522 struct files_struct *dirfsp = NULL;
2523 files_struct *fsp = NULL;
2524 int snum;
2525 uint32_t ucf_flags = 0;
2526 NTTIME twrp = 0;
2528 ZERO_STRUCT(st);
2530 if (!r->in.share) {
2531 werr = WERR_NERR_NETNAMENOTFOUND;
2532 goto error_exit;
2534 snum = find_service(frame, r->in.share, &servicename);
2535 if (!servicename) {
2536 werr = WERR_NOT_ENOUGH_MEMORY;
2537 goto error_exit;
2539 if (snum == -1) {
2540 DEBUG(10, ("Could not find service %s\n", servicename));
2541 werr = WERR_NERR_NETNAMENOTFOUND;
2542 goto error_exit;
2545 nt_status = create_conn_struct_tos_cwd(global_messaging_context(),
2546 snum,
2547 lp_path(frame, lp_sub, snum),
2548 session_info,
2549 &c);
2550 if (!NT_STATUS_IS_OK(nt_status)) {
2551 DEBUG(10, ("create_conn_struct failed: %s\n",
2552 nt_errstr(nt_status)));
2553 werr = ntstatus_to_werror(nt_status);
2554 goto error_exit;
2556 conn = c->conn;
2558 nt_status = filename_convert_dirfsp(frame,
2559 conn,
2560 r->in.file,
2561 ucf_flags,
2562 twrp,
2563 &dirfsp,
2564 &smb_fname);
2565 if (!NT_STATUS_IS_OK(nt_status)) {
2566 werr = ntstatus_to_werror(nt_status);
2567 goto error_exit;
2570 nt_status = SMB_VFS_CREATE_FILE(
2571 conn, /* conn */
2572 NULL, /* req */
2573 dirfsp, /* dirfsp */
2574 smb_fname, /* fname */
2575 FILE_READ_ATTRIBUTES, /* access_mask */
2576 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2577 FILE_OPEN, /* create_disposition*/
2578 0, /* create_options */
2579 0, /* file_attributes */
2580 INTERNAL_OPEN_ONLY, /* oplock_request */
2581 NULL, /* lease */
2582 0, /* allocation_size */
2583 0, /* private_flags */
2584 NULL, /* sd */
2585 NULL, /* ea_list */
2586 &fsp, /* result */
2587 NULL, /* pinfo */
2588 NULL, NULL); /* create context */
2590 if (!NT_STATUS_IS_OK(nt_status)) {
2591 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2592 smb_fname_str_dbg(smb_fname)));
2593 werr = ntstatus_to_werror(nt_status);
2594 goto error_exit;
2597 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2598 if (!sd_buf) {
2599 werr = WERR_NOT_ENOUGH_MEMORY;
2600 goto error_exit;
2603 nt_status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
2604 (SECINFO_OWNER
2605 |SECINFO_GROUP
2606 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2608 if (!NT_STATUS_IS_OK(nt_status)) {
2609 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2610 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2611 werr = ntstatus_to_werror(nt_status);
2612 TALLOC_FREE(sd_buf);
2613 goto error_exit;
2616 if (sd_buf->sd->dacl) {
2617 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2620 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2622 sd_buf->sd_size = sd_size;
2624 *r->out.sd_buf = sd_buf;
2626 werr = WERR_OK;
2628 error_exit:
2630 if (fsp) {
2631 close_file_free(NULL, &fsp, NORMAL_CLOSE);
2634 TALLOC_FREE(frame);
2635 return werr;
2638 /***********************************************************************************
2639 _srvsvc_NetSetFileSecurity
2640 Win9x NT tools set security descriptor.
2641 ***********************************************************************************/
2643 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2644 struct srvsvc_NetSetFileSecurity *r)
2646 struct dcesrv_call_state *dce_call = p->dce_call;
2647 struct auth_session_info *session_info =
2648 dcesrv_call_session_info(dce_call);
2649 TALLOC_CTX *frame = talloc_stackframe();
2650 const struct loadparm_substitution *lp_sub =
2651 loadparm_s3_global_substitution();
2652 struct smb_filename *smb_fname = NULL;
2653 char *servicename = NULL;
2654 struct files_struct *dirfsp = NULL;
2655 files_struct *fsp = NULL;
2656 SMB_STRUCT_STAT st;
2657 NTSTATUS nt_status;
2658 WERROR werr;
2659 struct conn_struct_tos *c = NULL;
2660 connection_struct *conn = NULL;
2661 int snum;
2662 struct security_descriptor *psd = NULL;
2663 uint32_t security_info_sent = 0;
2664 uint32_t ucf_flags = 0;
2665 NTTIME twrp = 0;
2667 ZERO_STRUCT(st);
2669 if (!r->in.share) {
2670 werr = WERR_NERR_NETNAMENOTFOUND;
2671 goto error_exit;
2674 snum = find_service(frame, r->in.share, &servicename);
2675 if (!servicename) {
2676 werr = WERR_NOT_ENOUGH_MEMORY;
2677 goto error_exit;
2680 if (snum == -1) {
2681 DEBUG(10, ("Could not find service %s\n", servicename));
2682 werr = WERR_NERR_NETNAMENOTFOUND;
2683 goto error_exit;
2686 nt_status = create_conn_struct_tos_cwd(global_messaging_context(),
2687 snum,
2688 lp_path(frame, lp_sub, snum),
2689 session_info,
2690 &c);
2691 if (!NT_STATUS_IS_OK(nt_status)) {
2692 DEBUG(10, ("create_conn_struct failed: %s\n",
2693 nt_errstr(nt_status)));
2694 werr = ntstatus_to_werror(nt_status);
2695 goto error_exit;
2697 conn = c->conn;
2699 nt_status = filename_convert_dirfsp(frame,
2700 conn,
2701 r->in.file,
2702 ucf_flags,
2703 twrp,
2704 &dirfsp,
2705 &smb_fname);
2706 if (!NT_STATUS_IS_OK(nt_status)) {
2707 werr = ntstatus_to_werror(nt_status);
2708 goto error_exit;
2711 nt_status = SMB_VFS_CREATE_FILE(
2712 conn, /* conn */
2713 NULL, /* req */
2714 dirfsp, /* dirfsp */
2715 smb_fname, /* fname */
2716 FILE_WRITE_ATTRIBUTES, /* access_mask */
2717 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2718 FILE_OPEN, /* create_disposition*/
2719 0, /* create_options */
2720 0, /* file_attributes */
2721 INTERNAL_OPEN_ONLY, /* oplock_request */
2722 NULL, /* lease */
2723 0, /* allocation_size */
2724 0, /* private_flags */
2725 NULL, /* sd */
2726 NULL, /* ea_list */
2727 &fsp, /* result */
2728 NULL, /* pinfo */
2729 NULL, NULL); /* create context */
2731 if (!NT_STATUS_IS_OK(nt_status)) {
2732 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2733 smb_fname_str_dbg(smb_fname)));
2734 werr = ntstatus_to_werror(nt_status);
2735 goto error_exit;
2738 psd = r->in.sd_buf->sd;
2739 security_info_sent = r->in.securityinformation;
2741 nt_status = set_sd(fsp, psd, security_info_sent);
2743 if (!NT_STATUS_IS_OK(nt_status) ) {
2744 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2745 "on file %s\n", r->in.share));
2746 werr = WERR_ACCESS_DENIED;
2747 goto error_exit;
2750 werr = WERR_OK;
2752 error_exit:
2754 if (fsp) {
2755 close_file_free(NULL, &fsp, NORMAL_CLOSE);
2758 TALLOC_FREE(frame);
2759 return werr;
2762 /***********************************************************************************
2763 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2764 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2765 These disks would the disks listed by this function.
2766 Users could then create shares relative to these disks. Watch out for moving these disks around.
2767 "Nigel Williams" <nigel@veritas.com>.
2768 ***********************************************************************************/
2770 static const char *server_disks[] = {"C:"};
2772 static uint32_t get_server_disk_count(void)
2774 return sizeof(server_disks)/sizeof(server_disks[0]);
2777 static uint32_t init_server_disk_enum(uint32_t *resume)
2779 uint32_t server_disk_count = get_server_disk_count();
2781 /*resume can be an offset into the list for now*/
2783 if(*resume & 0x80000000)
2784 *resume = 0;
2786 if(*resume > server_disk_count)
2787 *resume = server_disk_count;
2789 return server_disk_count - *resume;
2792 static const char *next_server_disk_enum(uint32_t *resume)
2794 const char *disk;
2796 if(init_server_disk_enum(resume) == 0)
2797 return NULL;
2799 disk = server_disks[*resume];
2801 (*resume)++;
2803 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2805 return disk;
2808 /********************************************************************
2809 _srvsvc_NetDiskEnum
2810 ********************************************************************/
2812 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2813 struct srvsvc_NetDiskEnum *r)
2815 uint32_t i;
2816 const char *disk_name;
2817 TALLOC_CTX *ctx = p->mem_ctx;
2818 WERROR werr;
2819 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2821 werr = WERR_OK;
2823 *r->out.totalentries = init_server_disk_enum(&resume);
2825 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2826 MAX_SERVER_DISK_ENTRIES);
2827 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2829 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2831 r->out.info->count = 0;
2833 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2835 r->out.info->count++;
2837 /*copy disk name into a unicode string*/
2839 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2840 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2843 /* add a terminating null string. Is this there if there is more data to come? */
2845 r->out.info->count++;
2847 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2848 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2850 if (r->out.resume_handle) {
2851 *r->out.resume_handle = resume;
2854 return werr;
2857 /********************************************************************
2858 _srvsvc_NetNameValidate
2859 ********************************************************************/
2861 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2862 struct srvsvc_NetNameValidate *r)
2864 switch (r->in.name_type) {
2865 case 0x9:
2866 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2867 strlen_m(r->in.name)))
2869 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2870 r->in.name));
2871 return WERR_INVALID_NAME;
2873 break;
2875 default:
2876 return WERR_INVALID_LEVEL;
2879 return WERR_OK;
2882 /*******************************************************************
2883 ********************************************************************/
2885 struct enum_file_close_state {
2886 struct srvsvc_NetFileClose *r;
2887 struct messaging_context *msg_ctx;
2890 static int enum_file_close_fn(struct file_id id,
2891 const struct share_mode_data *d,
2892 const struct share_mode_entry *e,
2893 void *private_data)
2895 struct enum_file_close_state *state =
2896 (struct enum_file_close_state *)private_data;
2897 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2898 struct oplock_break_message msg = {
2899 .id = id,
2900 .share_file_id = e->share_file_id,
2902 enum ndr_err_code ndr_err;
2903 uint8_t msgbuf[33];
2904 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
2905 NTSTATUS status;
2907 if (fid != state->r->in.fid) {
2908 return 0; /* Not this file. */
2911 if (!process_exists(e->pid) ) {
2912 return 0;
2915 /* Ok - send the close message. */
2916 DBG_DEBUG("request to close file %s, %s\n", d->servicepath,
2917 share_mode_str(talloc_tos(), 0, &id, e));
2919 ndr_err = ndr_push_struct_into_fixed_blob(
2920 &blob,
2921 &msg,
2922 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2923 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2924 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2925 ndr_errstr(ndr_err));
2926 status = ndr_map_error2ntstatus(ndr_err);
2927 } else {
2928 status = messaging_send(state->msg_ctx,
2929 e->pid,
2930 MSG_SMB_CLOSE_FILE,
2931 &blob);
2934 if (!NT_STATUS_IS_OK(status)) {
2935 state->r->out.result = ntstatus_to_werror(status);
2938 return 0;
2941 /********************************************************************
2942 Close a file given a 32-bit file id.
2943 ********************************************************************/
2945 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2946 struct srvsvc_NetFileClose *r)
2948 struct dcesrv_call_state *dce_call = p->dce_call;
2949 struct auth_session_info *session_info =
2950 dcesrv_call_session_info(dce_call);
2951 struct enum_file_close_state state;
2952 bool is_disk_op;
2954 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2956 is_disk_op = security_token_has_privilege(
2957 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2959 if (session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2960 return WERR_ACCESS_DENIED;
2963 /* enum_file_close_fn sends the close message to
2964 * the relevant smbd process. */
2966 r->out.result = WERR_FILE_NOT_FOUND;
2967 state.r = r;
2968 state.msg_ctx = p->msg_ctx;
2969 share_entry_forall(enum_file_close_fn, &state);
2970 return r->out.result;
2973 /********************************************************************
2974 ********************************************************************/
2976 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2977 struct srvsvc_NetCharDevEnum *r)
2979 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2980 return WERR_NOT_SUPPORTED;
2983 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2984 struct srvsvc_NetCharDevGetInfo *r)
2986 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2987 return WERR_NOT_SUPPORTED;
2990 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2991 struct srvsvc_NetCharDevControl *r)
2993 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2994 return WERR_NOT_SUPPORTED;
2997 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2998 struct srvsvc_NetCharDevQEnum *r)
3000 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3001 return WERR_NOT_SUPPORTED;
3004 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
3005 struct srvsvc_NetCharDevQGetInfo *r)
3007 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3008 return WERR_NOT_SUPPORTED;
3011 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
3012 struct srvsvc_NetCharDevQSetInfo *r)
3014 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3015 return WERR_NOT_SUPPORTED;
3018 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
3019 struct srvsvc_NetCharDevQPurge *r)
3021 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3022 return WERR_NOT_SUPPORTED;
3025 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
3026 struct srvsvc_NetCharDevQPurgeSelf *r)
3028 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3029 return WERR_NOT_SUPPORTED;
3032 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
3033 struct srvsvc_NetFileGetInfo *r)
3035 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3036 return WERR_NOT_SUPPORTED;
3039 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
3040 struct srvsvc_NetShareCheck *r)
3042 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3043 return WERR_NOT_SUPPORTED;
3046 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
3047 struct srvsvc_NetServerStatisticsGet *r)
3049 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3050 return WERR_NOT_SUPPORTED;
3053 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
3054 struct srvsvc_NetTransportAdd *r)
3056 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3057 return WERR_NOT_SUPPORTED;
3060 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
3061 struct srvsvc_NetTransportEnum *r)
3063 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3064 return WERR_NOT_SUPPORTED;
3067 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
3068 struct srvsvc_NetTransportDel *r)
3070 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3071 return WERR_NOT_SUPPORTED;
3074 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
3075 struct srvsvc_NetSetServiceBits *r)
3077 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3078 return WERR_NOT_SUPPORTED;
3081 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
3082 struct srvsvc_NetPathType *r)
3084 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3085 return WERR_NOT_SUPPORTED;
3088 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
3089 struct srvsvc_NetPathCanonicalize *r)
3091 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3092 return WERR_NOT_SUPPORTED;
3095 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
3096 struct srvsvc_NetPathCompare *r)
3098 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3099 return WERR_NOT_SUPPORTED;
3102 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
3103 struct srvsvc_NETRPRNAMECANONICALIZE *r)
3105 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3106 return WERR_NOT_SUPPORTED;
3109 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
3110 struct srvsvc_NetPRNameCompare *r)
3112 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3113 return WERR_NOT_SUPPORTED;
3116 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
3117 struct srvsvc_NetShareDelStart *r)
3119 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3120 return WERR_NOT_SUPPORTED;
3123 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
3124 struct srvsvc_NetShareDelCommit *r)
3126 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3127 return WERR_NOT_SUPPORTED;
3130 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
3131 struct srvsvc_NetServerTransportAddEx *r)
3133 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3134 return WERR_NOT_SUPPORTED;
3137 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
3138 struct srvsvc_NetServerSetServiceBitsEx *r)
3140 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3141 return WERR_NOT_SUPPORTED;
3144 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
3145 struct srvsvc_NETRDFSGETVERSION *r)
3147 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3148 return WERR_NOT_SUPPORTED;
3151 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
3152 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
3154 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3155 return WERR_NOT_SUPPORTED;
3158 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
3159 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
3161 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3162 return WERR_NOT_SUPPORTED;
3165 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
3166 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
3168 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3169 return WERR_NOT_SUPPORTED;
3172 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
3173 struct srvsvc_NETRDFSSETSERVERINFO *r)
3175 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3176 return WERR_NOT_SUPPORTED;
3179 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
3180 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
3182 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3183 return WERR_NOT_SUPPORTED;
3186 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
3187 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
3189 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3190 return WERR_NOT_SUPPORTED;
3193 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
3194 struct srvsvc_NETRDFSMODIFYPREFIX *r)
3196 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3197 return WERR_NOT_SUPPORTED;
3200 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
3201 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
3203 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3204 return WERR_NOT_SUPPORTED;
3207 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3208 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3210 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3211 return WERR_NOT_SUPPORTED;
3214 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3215 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3217 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3218 return WERR_NOT_SUPPORTED;
3221 /* include the generated boilerplate */
3222 #include "librpc/gen_ndr/ndr_srvsvc_scompat.c"