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. */
27 #include "system/passwd.h"
28 #include "lib/util/server_id.h"
30 #include "../librpc/gen_ndr/srv_srvsvc.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/open_files.h"
34 #include "dbwrap/dbwrap.h"
36 #include "../lib/util/util_pw.h"
37 #include "smbd/smbd.h"
38 #include "smbd/globals.h"
42 #include "lib/conn_tdb.h"
44 extern const struct generic_mapping file_generic_mapping;
47 #define DBGC_CLASS DBGC_RPC_SRV
49 #define MAX_SERVER_DISK_ENTRIES 15
51 /* Use for enumerating connections, pipes, & files */
53 struct file_enum_count {
56 struct srvsvc_NetFileCtr3 *ctr3;
59 struct sess_file_info {
60 struct srvsvc_NetSessCtr1 *ctr;
61 struct sessionid *session_list;
62 uint32_t resume_handle;
66 struct share_file_stat {
67 struct srvsvc_NetConnInfo1 *netconn_arr;
68 struct server_id *svrid_arr;
69 const char *in_sharepath;
70 uint32_t resp_entries;
71 uint32_t total_entries;
74 struct share_conn_stat {
76 const char *sharename;
77 struct server_id *svrid_arr;
81 /*******************************************************************
82 ********************************************************************/
84 static int enum_file_fn(const struct share_mode_entry *e,
85 const struct file_id *id,
86 const char *sharepath,
91 struct file_enum_count *fenum =
92 (struct file_enum_count *)private_data;
94 struct srvsvc_NetFileInfo3 *f;
95 int i = fenum->ctr3->count;
97 struct byte_range_lock *brl;
99 char *fullpath = NULL;
100 uint32_t permissions;
101 const char *username;
103 /* If the pid was not found delete the entry from connections.tdb */
105 if ( !process_exists(e->pid) ) {
109 username = uidtoname(e->uid);
111 if ((fenum->username != NULL)
112 && !strequal(username, fenum->username)) {
116 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
117 struct srvsvc_NetFileInfo3, i+1);
119 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
122 fenum->ctr3->array = f;
124 /* need to count the number of locks on a file */
129 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
130 num_locks = brl_num_locks(brl);
134 if ( strcmp( fname, "." ) == 0 ) {
135 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
137 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s%s",
144 string_replace( fullpath, '/', '\\' );
146 /* mask out create (what ever that is) */
147 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
149 /* now fill in the srvsvc_NetFileInfo3 struct */
151 fenum->ctr3->array[i].fid =
152 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
153 fenum->ctr3->array[i].permissions = permissions;
154 fenum->ctr3->array[i].num_locks = num_locks;
155 fenum->ctr3->array[i].path = fullpath;
156 fenum->ctr3->array[i].user = username;
158 fenum->ctr3->count++;
163 /*******************************************************************
164 ********************************************************************/
166 static WERROR net_enum_files(TALLOC_CTX *ctx,
167 const char *username,
168 struct srvsvc_NetFileCtr3 **ctr3,
171 struct file_enum_count f_enum_cnt;
173 f_enum_cnt.ctx = ctx;
174 f_enum_cnt.username = username;
175 f_enum_cnt.ctr3 = *ctr3;
177 share_entry_forall(enum_file_fn, (void *)&f_enum_cnt );
179 *ctr3 = f_enum_cnt.ctr3;
184 /*******************************************************************
185 Utility function to get the 'type' of a share from an snum.
186 ********************************************************************/
187 static enum srvsvc_ShareType get_share_type(int snum)
189 /* work out the share type */
190 enum srvsvc_ShareType type = STYPE_DISKTREE;
192 if (lp_printable(snum)) {
193 type = lp_administrative_share(snum)
194 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
196 if (strequal(lp_fstype(snum), "IPC")) {
197 type = lp_administrative_share(snum)
198 ? STYPE_IPC_HIDDEN : STYPE_IPC;
203 /*******************************************************************
204 Fill in a share info level 0 structure.
205 ********************************************************************/
207 static void init_srv_share_info_0(struct pipes_struct *p,
208 struct srvsvc_NetShareInfo0 *r, int snum)
210 r->name = lp_servicename(talloc_tos(), snum);
213 /*******************************************************************
214 Fill in a share info level 1 structure.
215 ********************************************************************/
217 static void init_srv_share_info_1(struct pipes_struct *p,
218 struct srvsvc_NetShareInfo1 *r,
221 char *net_name = lp_servicename(talloc_tos(), snum);
222 char *remark = lp_comment(p->mem_ctx, snum);
225 remark = talloc_sub_advanced(
226 p->mem_ctx, lp_servicename(talloc_tos(), snum),
227 get_current_username(), lp_path(talloc_tos(), snum),
228 p->session_info->unix_token->uid, get_current_username(),
233 r->type = get_share_type(snum);
234 r->comment = remark ? remark : "";
237 /*******************************************************************
238 Fill in a share info level 2 structure.
239 ********************************************************************/
241 static void init_srv_share_info_2(struct pipes_struct *p,
242 struct srvsvc_NetShareInfo2 *r,
247 int max_connections = lp_max_connections(snum);
248 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
249 char *net_name = lp_servicename(talloc_tos(), snum);
251 remark = lp_comment(p->mem_ctx, snum);
253 remark = talloc_sub_advanced(
254 p->mem_ctx, lp_servicename(talloc_tos(), snum),
255 get_current_username(), lp_path(talloc_tos(), snum),
256 p->session_info->unix_token->uid, get_current_username(),
259 path = talloc_asprintf(p->mem_ctx,
260 "C:%s", lp_path(talloc_tos(), snum));
264 * Change / to \\ so that win2k will see it as a valid path.
265 * This was added to enable use of browsing in win2k add
269 string_replace(path, '/', '\\');
273 r->type = get_share_type(snum);
274 r->comment = remark ? remark : "";
276 r->max_users = max_uses;
277 r->current_users = 0; /* computed later */
278 r->path = path ? path : "";
282 /*******************************************************************
283 Map any generic bits to file specific bits.
284 ********************************************************************/
286 static void map_generic_share_sd_bits(struct security_descriptor *psd)
289 struct security_acl *ps_dacl = NULL;
298 for (i = 0; i < ps_dacl->num_aces; i++) {
299 struct security_ace *psa = &ps_dacl->aces[i];
300 uint32_t orig_mask = psa->access_mask;
302 se_map_generic(&psa->access_mask, &file_generic_mapping);
303 psa->access_mask |= orig_mask;
307 /*******************************************************************
308 Fill in a share info level 501 structure.
309 ********************************************************************/
311 static void init_srv_share_info_501(struct pipes_struct *p,
312 struct srvsvc_NetShareInfo501 *r, int snum)
314 const char *net_name = lp_servicename(talloc_tos(), snum);
315 char *remark = lp_comment(p->mem_ctx, snum);
318 remark = talloc_sub_advanced(
319 p->mem_ctx, lp_servicename(talloc_tos(), snum),
320 get_current_username(), lp_path(talloc_tos(), snum),
321 p->session_info->unix_token->uid, get_current_username(),
326 r->type = get_share_type(snum);
327 r->comment = remark ? remark : "";
330 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
333 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
336 /*******************************************************************
337 Fill in a share info level 502 structure.
338 ********************************************************************/
340 static void init_srv_share_info_502(struct pipes_struct *p,
341 struct srvsvc_NetShareInfo502 *r, int snum)
343 const char *net_name = lp_servicename(talloc_tos(), snum);
345 struct security_descriptor *sd = NULL;
346 struct sec_desc_buf *sd_buf = NULL;
348 TALLOC_CTX *ctx = p->mem_ctx;
349 char *remark = lp_comment(ctx, snum);
352 remark = talloc_sub_advanced(
353 p->mem_ctx, lp_servicename(talloc_tos(), snum),
354 get_current_username(), lp_path(talloc_tos(), snum),
355 p->session_info->unix_token->uid, get_current_username(),
358 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
361 * Change / to \\ so that win2k will see it as a valid path. This was added to
362 * enable use of browsing in win2k add share dialog.
364 string_replace(path, '/', '\\');
367 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
369 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
372 r->type = get_share_type(snum);
373 r->comment = remark ? remark : "";
375 r->max_users = (uint32_t)-1;
376 r->current_users = 1; /* ??? */
377 r->path = path ? path : "";
382 /***************************************************************************
383 Fill in a share info level 1004 structure.
384 ***************************************************************************/
386 static void init_srv_share_info_1004(struct pipes_struct *p,
387 struct srvsvc_NetShareInfo1004 *r,
390 char *remark = lp_comment(p->mem_ctx, snum);
393 remark = talloc_sub_advanced(
394 p->mem_ctx, lp_servicename(talloc_tos(), snum),
395 get_current_username(), lp_path(talloc_tos(), snum),
396 p->session_info->unix_token->uid, get_current_username(),
400 r->comment = remark ? remark : "";
403 /***************************************************************************
404 Fill in a share info level 1005 structure.
405 ***************************************************************************/
407 static void init_srv_share_info_1005(struct pipes_struct *p,
408 struct srvsvc_NetShareInfo1005 *r,
411 uint32_t dfs_flags = 0;
413 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
414 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
417 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
419 r->dfs_flags = dfs_flags;
422 /***************************************************************************
423 Fill in a share info level 1006 structure.
424 ***************************************************************************/
426 static void init_srv_share_info_1006(struct pipes_struct *p,
427 struct srvsvc_NetShareInfo1006 *r,
430 r->max_users = (uint32_t)-1;
433 /***************************************************************************
434 Fill in a share info level 1007 structure.
435 ***************************************************************************/
437 static void init_srv_share_info_1007(struct pipes_struct *p,
438 struct srvsvc_NetShareInfo1007 *r,
442 r->alternate_directory_name = "";
445 /*******************************************************************
446 Fill in a share info level 1501 structure.
447 ********************************************************************/
449 static void init_srv_share_info_1501(struct pipes_struct *p,
450 struct sec_desc_buf **r,
453 struct security_descriptor *sd;
454 struct sec_desc_buf *sd_buf = NULL;
456 TALLOC_CTX *ctx = p->mem_ctx;
458 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
460 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
466 /*******************************************************************
467 True if it ends in '$'.
468 ********************************************************************/
470 static bool is_hidden_share(int snum)
472 const char *net_name = lp_servicename(talloc_tos(), snum);
474 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
477 /*******************************************************************
478 Verify user is allowed to view share, access based enumeration
479 ********************************************************************/
480 static bool is_enumeration_allowed(struct pipes_struct *p,
483 if (!lp_access_based_share_enum(snum)) {
487 if (!user_ok_token(p->session_info->unix_info->unix_name,
488 p->session_info->info->domain_name,
489 p->session_info->security_token, snum)) {
493 return share_access_check(p->session_info->security_token,
494 lp_servicename(talloc_tos(), snum),
495 FILE_READ_DATA, NULL);
498 /****************************************************************************
499 Count an entry against the respective service.
500 ****************************************************************************/
502 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
504 union srvsvc_NetShareCtr *ctr = NULL;
505 struct srvsvc_NetShareInfo2 *info2 = NULL;
506 int share_entries = 0;
509 ctr = (union srvsvc_NetShareCtr *) udp;
512 share_entries = ctr->ctr2->count;
513 info2 = &ctr->ctr2->array[0];
515 for (i = 0; i < share_entries; i++, info2++) {
516 if (strequal(tcon->share_name, info2->name)) {
517 info2->current_users++;
525 /****************************************************************************
526 Count the entries belonging to all services in the connection db.
527 ****************************************************************************/
529 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
532 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
534 if (!NT_STATUS_IS_OK(status)) {
535 DEBUG(0,("count_connections_for_all_shares: traverse of "
536 "smbXsrv_tcon_global.tdb failed - %s\n",
541 /*******************************************************************
542 Fill in a share info structure.
543 ********************************************************************/
545 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
546 struct srvsvc_NetShareInfoCtr *info_ctr,
547 uint32_t *resume_handle_p,
548 uint32_t *total_entries,
551 uint32_t num_entries = 0;
552 uint32_t alloc_entries = 0;
553 int num_services = 0;
555 TALLOC_CTX *ctx = p->mem_ctx;
557 uint32_t valid_share_count = 0;
559 union srvsvc_NetShareCtr ctr;
560 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
562 DEBUG(5,("init_srv_share_info_ctr\n"));
564 /* Ensure all the usershares are loaded. */
566 delete_and_reload_printers(server_event_context(), p->msg_ctx);
567 load_usershare_shares(NULL, connections_snum_used);
568 load_registry_shares();
569 num_services = lp_numservices();
572 allowed = talloc_zero_array(ctx, bool, num_services);
573 W_ERROR_HAVE_NO_MEMORY(allowed);
575 /* Count the number of entries. */
576 for (snum = 0; snum < num_services; snum++) {
577 if (lp_browseable(snum) && lp_snum_ok(snum) &&
578 is_enumeration_allowed(p, snum) &&
579 (all_shares || !is_hidden_share(snum)) ) {
580 DEBUG(10, ("counting service %s\n",
581 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
582 allowed[snum] = true;
585 DEBUG(10, ("NOT counting service %s\n",
586 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
590 if (!num_entries || (resume_handle >= num_entries)) {
594 /* Calculate alloc entries. */
595 alloc_entries = num_entries - resume_handle;
596 switch (info_ctr->level) {
598 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
599 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
601 ctr.ctr0->count = alloc_entries;
602 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
603 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
605 for (snum = 0; snum < num_services; snum++) {
607 (resume_handle <= (i + valid_share_count++)) ) {
608 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
615 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
616 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
618 ctr.ctr1->count = alloc_entries;
619 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
620 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
622 for (snum = 0; snum < num_services; snum++) {
624 (resume_handle <= (i + valid_share_count++)) ) {
625 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
632 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
633 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
635 ctr.ctr2->count = alloc_entries;
636 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
637 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
639 for (snum = 0; snum < num_services; snum++) {
641 (resume_handle <= (i + valid_share_count++)) ) {
642 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
646 count_connections_for_all_shares(&ctr);
650 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
651 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
653 ctr.ctr501->count = alloc_entries;
654 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
655 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
657 for (snum = 0; snum < num_services; snum++) {
659 (resume_handle <= (i + valid_share_count++)) ) {
660 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
667 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
668 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
670 ctr.ctr502->count = alloc_entries;
671 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
672 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
674 for (snum = 0; snum < num_services; snum++) {
676 (resume_handle <= (i + valid_share_count++)) ) {
677 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
684 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
685 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
687 ctr.ctr1004->count = alloc_entries;
688 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
689 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
691 for (snum = 0; snum < num_services; snum++) {
693 (resume_handle <= (i + valid_share_count++)) ) {
694 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
701 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
702 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
704 ctr.ctr1005->count = alloc_entries;
705 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
706 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
708 for (snum = 0; snum < num_services; snum++) {
710 (resume_handle <= (i + valid_share_count++)) ) {
711 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
718 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
719 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
721 ctr.ctr1006->count = alloc_entries;
722 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
723 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
725 for (snum = 0; snum < num_services; snum++) {
727 (resume_handle <= (i + valid_share_count++)) ) {
728 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
735 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
736 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
738 ctr.ctr1007->count = alloc_entries;
739 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
740 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
742 for (snum = 0; snum < num_services; snum++) {
744 (resume_handle <= (i + valid_share_count++)) ) {
745 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
752 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
753 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
755 ctr.ctr1501->count = alloc_entries;
756 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
757 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
759 for (snum = 0; snum < num_services; snum++) {
761 (resume_handle <= (i + valid_share_count++)) ) {
762 struct sec_desc_buf *sd_buf = NULL;
763 init_srv_share_info_1501(p, &sd_buf, snum);
764 ctr.ctr1501->array[i++] = *sd_buf;
771 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
773 return WERR_INVALID_LEVEL;
776 *total_entries = alloc_entries;
777 if (resume_handle_p) {
779 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
781 *resume_handle_p = num_entries;
790 /*******************************************************************
791 fill in a sess info level 0 structure.
792 ********************************************************************/
794 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
795 struct srvsvc_NetSessCtr0 *ctr0,
796 uint32_t *resume_handle_p,
797 uint32_t *total_entries)
799 struct sessionid *session_list;
800 uint32_t num_entries = 0;
801 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
802 *total_entries = list_sessions(p->mem_ctx, &session_list);
804 DEBUG(5,("init_srv_sess_info_0\n"));
807 if (resume_handle_p) {
808 *resume_handle_p = 0;
813 for (; resume_handle < *total_entries; resume_handle++) {
815 ctr0->array = talloc_realloc(p->mem_ctx,
817 struct srvsvc_NetSessInfo0,
819 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
821 ctr0->array[num_entries].client =
822 session_list[resume_handle].remote_machine;
827 ctr0->count = num_entries;
829 if (resume_handle_p) {
830 if (*resume_handle_p >= *total_entries) {
831 *resume_handle_p = 0;
833 *resume_handle_p = resume_handle;
840 /***********************************************************************
841 * find out the session on which this file is open and bump up its count
842 **********************************************************************/
844 static int count_sess_files_fn(const struct share_mode_entry *e,
845 const struct file_id *id,
846 const char *sharepath,
851 struct sess_file_info *info = data;
852 uint32_t rh = info->resume_handle;
855 for (i=0; i < info->num_entries; i++) {
856 /* rh+info->num_entries is safe, as we've
858 *total_entries > resume_handle &&
859 info->num_entries = *total_entries - resume_handle;
860 inside init_srv_sess_info_1() below.
862 struct sessionid *sess = &info->session_list[rh + i];
863 if ((e->uid == sess->uid) &&
864 serverid_equal(&e->pid, &sess->pid)) {
866 info->ctr->array[i].num_open++;
873 /*******************************************************************
874 * count the num of open files on all sessions
875 *******************************************************************/
877 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
878 struct sessionid *session_list,
879 uint32_t resume_handle,
880 uint32_t num_entries)
882 struct sess_file_info s_file_info;
884 s_file_info.ctr = ctr1;
885 s_file_info.session_list = session_list;
886 s_file_info.resume_handle = resume_handle;
887 s_file_info.num_entries = num_entries;
889 share_entry_forall(count_sess_files_fn, &s_file_info);
892 /*******************************************************************
893 fill in a sess info level 1 structure.
894 ********************************************************************/
896 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
897 struct srvsvc_NetSessCtr1 *ctr1,
898 uint32_t *resume_handle_p,
899 uint32_t *total_entries)
901 struct sessionid *session_list;
902 uint32_t num_entries = 0;
903 time_t now = time(NULL);
904 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
909 if (resume_handle_p) {
910 *resume_handle_p = 0;
915 *total_entries = list_sessions(p->mem_ctx, &session_list);
917 if (resume_handle >= *total_entries) {
918 if (resume_handle_p) {
919 *resume_handle_p = 0;
924 /* We know num_entries must be positive, due to
925 the check resume_handle >= *total_entries above. */
927 num_entries = *total_entries - resume_handle;
929 ctr1->array = talloc_zero_array(p->mem_ctx,
930 struct srvsvc_NetSessInfo1,
933 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
935 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
936 uint32_t connect_time;
939 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
940 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
942 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
943 ctr1->array[num_entries].user = session_list[resume_handle].username;
944 ctr1->array[num_entries].num_open = 0;/* computed later */
945 ctr1->array[num_entries].time = connect_time;
946 ctr1->array[num_entries].idle_time = 0;
947 ctr1->array[num_entries].user_flags = guest;
950 ctr1->count = num_entries;
952 /* count open files on all sessions in single tdb traversal */
953 net_count_files_for_all_sess(ctr1, session_list,
954 resume_handle_p ? *resume_handle_p : 0,
957 if (resume_handle_p) {
958 if (*resume_handle_p >= *total_entries) {
959 *resume_handle_p = 0;
961 *resume_handle_p = resume_handle;
968 /*******************************************************************
969 find the share connection on which this open exists.
970 ********************************************************************/
972 static int share_file_fn(const struct share_mode_entry *e,
973 const struct file_id *id,
974 const char *sharepath,
979 struct share_file_stat *sfs = data;
981 uint32_t offset = sfs->total_entries - sfs->resp_entries;
983 if (strequal(sharepath, sfs->in_sharepath)) {
984 for (i=0; i < sfs->resp_entries; i++) {
985 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
986 sfs->netconn_arr[i].num_open ++;
994 /*******************************************************************
995 count number of open files on given share connections.
996 ********************************************************************/
998 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
999 struct server_id *svrid_arr, char *sharepath,
1000 uint32_t resp_entries, uint32_t total_entries)
1002 struct share_file_stat sfs;
1004 sfs.netconn_arr = arr;
1005 sfs.svrid_arr = svrid_arr;
1006 sfs.in_sharepath = sharepath;
1007 sfs.resp_entries = resp_entries;
1008 sfs.total_entries = total_entries;
1010 share_entry_forall(share_file_fn, &sfs);
1013 /****************************************************************************
1014 process an entry from the connection db.
1015 ****************************************************************************/
1017 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
1020 struct share_conn_stat *scs = data;
1022 if (!process_exists(tcon->server_id)) {
1026 if (strequal(tcon->share_name, scs->sharename)) {
1027 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1030 if (!scs->svrid_arr) {
1034 scs->svrid_arr[scs->count] = tcon->server_id;
1041 /****************************************************************************
1042 Count the connections to a share. Build an array of serverid's owning these
1044 ****************************************************************************/
1046 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1047 struct server_id **arr)
1049 struct share_conn_stat scs;
1053 scs.sharename = sharename;
1054 scs.svrid_arr = NULL;
1057 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1059 if (!NT_STATUS_IS_OK(status)) {
1060 DEBUG(0,("count_share_conns: traverse of "
1061 "smbXsrv_tcon_global.tdb failed - %s\n",
1062 nt_errstr(status)));
1066 *arr = scs.svrid_arr;
1070 /*******************************************************************
1071 fill in a conn info level 0 structure.
1072 ********************************************************************/
1074 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1075 uint32_t *resume_handle_p,
1076 uint32_t *total_entries)
1078 uint32_t num_entries = 0;
1079 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1081 DEBUG(5,("init_srv_conn_info_0\n"));
1084 if (resume_handle_p) {
1085 *resume_handle_p = 0;
1094 for (; resume_handle < *total_entries; resume_handle++) {
1096 ctr0->array = talloc_realloc(talloc_tos(),
1098 struct srvsvc_NetConnInfo0,
1101 return WERR_NOT_ENOUGH_MEMORY;
1104 ctr0->array[num_entries].conn_id = *total_entries;
1106 /* move on to creating next connection */
1110 ctr0->count = num_entries;
1111 *total_entries = num_entries;
1113 if (resume_handle_p) {
1114 if (*resume_handle_p >= *total_entries) {
1115 *resume_handle_p = 0;
1117 *resume_handle_p = resume_handle;
1124 /*******************************************************************
1125 fill in a conn info level 1 structure.
1126 ********************************************************************/
1128 static WERROR init_srv_conn_info_1(const char *name,
1129 struct srvsvc_NetConnCtr1 *ctr1,
1130 uint32_t *resume_handle_p,
1131 uint32_t *total_entries)
1133 uint32_t num_entries = 0;
1135 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1136 char *share_name = NULL;
1137 struct server_id *svrid_arr = NULL;
1139 DEBUG(5,("init_srv_conn_info_1\n"));
1142 if (resume_handle_p) {
1143 *resume_handle_p = 0;
1148 /* check if this is a server name or a share name */
1149 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1150 (name[1] == '\\')) {
1152 /* 'name' is a server name - this part is unimplemented */
1155 /* 'name' is a share name */
1156 snum = find_service(talloc_tos(), name, &share_name);
1159 return WERR_NOT_ENOUGH_MEMORY;
1163 return WERR_INVALID_NAME;
1167 * count the num of connections to this share. Also,
1168 * build a list of serverid's that own these
1169 * connections. The serverid list is used later to
1170 * identify the share connection on which an open exists.
1173 *total_entries = count_share_conns(talloc_tos(),
1178 if (resume_handle >= *total_entries) {
1179 if (resume_handle_p) {
1180 *resume_handle_p = 0;
1186 * We know num_entries must be positive, due to
1187 * the check resume_handle >= *total_entries above.
1190 num_entries = *total_entries - resume_handle;
1194 ctr1->array = talloc_zero_array(talloc_tos(),
1195 struct srvsvc_NetConnInfo1,
1198 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1200 for (num_entries = 0; resume_handle < *total_entries;
1201 num_entries++, resume_handle++) {
1203 ctr1->array[num_entries].conn_id = *total_entries;
1204 ctr1->array[num_entries].conn_type = 0x3;
1207 * if these are connections to a share, we are going to
1208 * compute the opens on them later. If it's for the server,
1209 * it's unimplemented.
1213 ctr1->array[num_entries].num_open = 1;
1216 ctr1->array[num_entries].num_users = 1;
1217 ctr1->array[num_entries].conn_time = 3;
1218 ctr1->array[num_entries].user = "dummy_user";
1219 ctr1->array[num_entries].share = "IPC$";
1222 /* now compute open files on the share connections */
1227 * the locking tdb, which has the open files information,
1228 * does not store share name or share (service) number, but
1229 * just the share path. So, we can compute open files only
1230 * on the share path. If more than one shares are defined
1231 * on a share path, open files on all of them are included
1234 * To have the correct behavior in case multiple shares
1235 * are defined on the same path, changes to tdb records
1236 * would be required. That would be lot more effort, so
1237 * this seems a good stopgap fix.
1240 count_share_opens(ctr1->array, svrid_arr,
1241 lp_path(talloc_tos(), snum),
1242 num_entries, *total_entries);
1246 ctr1->count = num_entries;
1247 *total_entries = num_entries;
1249 if (resume_handle_p) {
1250 *resume_handle_p = resume_handle;
1256 /*******************************************************************
1258 *******************************************************************/
1260 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1261 struct srvsvc_NetFileEnum *r)
1263 TALLOC_CTX *ctx = NULL;
1264 struct srvsvc_NetFileCtr3 *ctr3;
1265 uint32_t resume_hnd = 0;
1268 switch (r->in.info_ctr->level) {
1272 return WERR_INVALID_LEVEL;
1275 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1276 p->session_info->security_token)) {
1277 DEBUG(1, ("Enumerating files only allowed for "
1278 "administrators\n"));
1279 return WERR_ACCESS_DENIED;
1283 ctr3 = r->in.info_ctr->ctr.ctr3;
1285 werr = WERR_INVALID_PARAMETER;
1289 /* TODO -- Windows enumerates
1291 (c) open directories and files */
1293 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1294 if (!W_ERROR_IS_OK(werr)) {
1298 *r->out.totalentries = ctr3->count;
1299 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1300 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1308 /*******************************************************************
1309 _srvsvc_NetSrvGetInfo
1310 ********************************************************************/
1312 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1313 struct srvsvc_NetSrvGetInfo *r)
1315 WERROR status = WERR_OK;
1317 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1319 if (!pipe_access_check(p)) {
1320 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1321 return WERR_ACCESS_DENIED;
1324 switch (r->in.level) {
1326 /* Technically level 102 should only be available to
1327 Administrators but there isn't anything super-secret
1328 here, as most of it is made up. */
1331 struct srvsvc_NetSrvInfo102 *info102;
1333 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1335 return WERR_NOT_ENOUGH_MEMORY;
1338 info102->platform_id = PLATFORM_ID_NT;
1339 info102->server_name = lp_netbios_name();
1340 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1341 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1342 info102->server_type = lp_default_server_announce();
1343 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1344 MAX_SERVER_STRING_LENGTH);
1345 info102->users = 0xffffffff;
1346 info102->disc = 0xf;
1347 info102->hidden = 0;
1348 info102->announce = 240;
1349 info102->anndelta = 3000;
1350 info102->licenses = 100000;
1351 info102->userpath = "C:\\";
1353 r->out.info->info102 = info102;
1357 struct srvsvc_NetSrvInfo101 *info101;
1359 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1361 return WERR_NOT_ENOUGH_MEMORY;
1364 info101->platform_id = PLATFORM_ID_NT;
1365 info101->server_name = lp_netbios_name();
1366 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1367 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1368 info101->server_type = lp_default_server_announce();
1369 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1370 MAX_SERVER_STRING_LENGTH);
1372 r->out.info->info101 = info101;
1376 struct srvsvc_NetSrvInfo100 *info100;
1378 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1380 return WERR_NOT_ENOUGH_MEMORY;
1383 info100->platform_id = PLATFORM_ID_NT;
1384 info100->server_name = lp_netbios_name();
1386 r->out.info->info100 = info100;
1391 status = WERR_INVALID_LEVEL;
1395 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1400 /*******************************************************************
1401 _srvsvc_NetSrvSetInfo
1402 ********************************************************************/
1404 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1405 struct srvsvc_NetSrvSetInfo *r)
1407 WERROR status = WERR_OK;
1409 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1411 /* Set up the net server set info structure. */
1413 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1418 /*******************************************************************
1420 ********************************************************************/
1422 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1423 struct srvsvc_NetConnEnum *r)
1427 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1429 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1430 p->session_info->security_token)) {
1431 DEBUG(1, ("Enumerating connections only allowed for "
1432 "administrators\n"));
1433 return WERR_ACCESS_DENIED;
1436 switch (r->in.info_ctr->level) {
1438 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1439 r->in.resume_handle,
1440 r->out.totalentries);
1443 werr = init_srv_conn_info_1(r->in.path,
1444 r->in.info_ctr->ctr.ctr1,
1445 r->in.resume_handle,
1446 r->out.totalentries);
1449 return WERR_INVALID_LEVEL;
1452 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1457 /*******************************************************************
1459 ********************************************************************/
1461 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1462 struct srvsvc_NetSessEnum *r)
1466 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1468 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1469 p->session_info->security_token)) {
1470 DEBUG(1, ("Enumerating sessions only allowed for "
1471 "administrators\n"));
1472 return WERR_ACCESS_DENIED;
1475 switch (r->in.info_ctr->level) {
1477 werr = init_srv_sess_info_0(p,
1478 r->in.info_ctr->ctr.ctr0,
1479 r->in.resume_handle,
1480 r->out.totalentries);
1483 werr = init_srv_sess_info_1(p,
1484 r->in.info_ctr->ctr.ctr1,
1485 r->in.resume_handle,
1486 r->out.totalentries);
1489 return WERR_INVALID_LEVEL;
1492 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1497 /*******************************************************************
1499 ********************************************************************/
1501 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1502 struct srvsvc_NetSessDel *r)
1504 struct sessionid *session_list;
1505 int num_sessions, snum;
1506 const char *username;
1507 const char *machine;
1508 bool not_root = False;
1511 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1513 werr = WERR_ACCESS_DENIED;
1515 /* fail out now if you are not root or not a domain admin */
1517 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1518 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1519 DOMAIN_RID_ADMINS))) {
1524 username = r->in.user;
1525 machine = r->in.client;
1527 /* strip leading backslashes if any */
1528 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1532 num_sessions = find_sessions(p->mem_ctx, username, machine,
1535 for (snum = 0; snum < num_sessions; snum++) {
1539 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1544 ntstat = messaging_send(p->msg_ctx,
1545 session_list[snum].pid,
1546 MSG_SHUTDOWN, &data_blob_null);
1548 if (NT_STATUS_IS_OK(ntstat))
1555 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1562 /*******************************************************************
1563 _srvsvc_NetShareEnumAll
1564 ********************************************************************/
1566 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1567 struct srvsvc_NetShareEnumAll *r)
1571 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1573 if (!pipe_access_check(p)) {
1574 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1575 return WERR_ACCESS_DENIED;
1578 /* Create the list of shares for the response. */
1579 werr = init_srv_share_info_ctr(p,
1581 r->in.resume_handle,
1582 r->out.totalentries,
1585 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1590 /*******************************************************************
1591 _srvsvc_NetShareEnum
1592 ********************************************************************/
1594 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1595 struct srvsvc_NetShareEnum *r)
1599 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1601 if (!pipe_access_check(p)) {
1602 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1603 return WERR_ACCESS_DENIED;
1606 /* Create the list of shares for the response. */
1607 werr = init_srv_share_info_ctr(p,
1609 r->in.resume_handle,
1610 r->out.totalentries,
1613 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1618 /*******************************************************************
1619 _srvsvc_NetShareGetInfo
1620 ********************************************************************/
1622 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1623 struct srvsvc_NetShareGetInfo *r)
1625 WERROR status = WERR_OK;
1626 char *share_name = NULL;
1628 union srvsvc_NetShareInfo *info = r->out.info;
1630 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1632 if (!r->in.share_name) {
1633 return WERR_INVALID_NAME;
1636 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1638 return WERR_NOT_ENOUGH_MEMORY;
1641 return WERR_INVALID_NAME;
1644 switch (r->in.level) {
1646 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1647 W_ERROR_HAVE_NO_MEMORY(info->info0);
1648 init_srv_share_info_0(p, info->info0, snum);
1651 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1652 W_ERROR_HAVE_NO_MEMORY(info->info1);
1653 init_srv_share_info_1(p, info->info1, snum);
1656 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1657 W_ERROR_HAVE_NO_MEMORY(info->info2);
1658 init_srv_share_info_2(p, info->info2, snum);
1659 info->info2->current_users =
1660 count_current_connections(info->info2->name, false);
1663 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1664 W_ERROR_HAVE_NO_MEMORY(info->info501);
1665 init_srv_share_info_501(p, info->info501, snum);
1668 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1669 W_ERROR_HAVE_NO_MEMORY(info->info502);
1670 init_srv_share_info_502(p, info->info502, snum);
1673 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1674 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1675 init_srv_share_info_1004(p, info->info1004, snum);
1678 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1679 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1680 init_srv_share_info_1005(p, info->info1005, snum);
1683 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1684 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1685 init_srv_share_info_1006(p, info->info1006, snum);
1688 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1689 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1690 init_srv_share_info_1007(p, info->info1007, snum);
1693 init_srv_share_info_1501(p, &info->info1501, snum);
1696 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1698 status = WERR_INVALID_LEVEL;
1702 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1707 /*******************************************************************
1708 _srvsvc_NetShareSetInfo. Modify share details.
1709 ********************************************************************/
1711 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1712 struct srvsvc_NetShareSetInfo *r)
1714 char *command = NULL;
1715 char *share_name = NULL;
1716 char *comment = NULL;
1717 const char *pathname = NULL;
1722 struct security_descriptor *psd = NULL;
1723 bool is_disk_op = False;
1724 const char *csc_policy = NULL;
1725 bool csc_policy_changed = false;
1726 const char *csc_policies[] = {"manual", "documents", "programs",
1728 uint32_t client_csc_policy;
1729 int max_connections = 0;
1730 TALLOC_CTX *ctx = p->mem_ctx;
1731 union srvsvc_NetShareInfo *info = r->in.info;
1733 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1735 if (!r->in.share_name) {
1736 return WERR_INVALID_NAME;
1739 if (r->out.parm_error) {
1740 *r->out.parm_error = 0;
1743 if ( strequal(r->in.share_name,"IPC$")
1744 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1745 || strequal(r->in.share_name,"global") )
1747 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1748 "modified by a remote user.\n",
1749 r->in.share_name ));
1750 return WERR_ACCESS_DENIED;
1753 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1755 return WERR_NOT_ENOUGH_MEMORY;
1758 /* Does this share exist ? */
1760 return WERR_NERR_NETNAMENOTFOUND;
1762 /* No change to printer shares. */
1763 if (lp_printable(snum))
1764 return WERR_ACCESS_DENIED;
1766 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1768 /* fail out now if you are not root and not a disk op */
1770 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1771 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1772 "SeDiskOperatorPrivilege privilege needed to modify "
1774 (unsigned int)p->session_info->unix_token->uid,
1776 return WERR_ACCESS_DENIED;
1779 max_connections = lp_max_connections(snum);
1780 csc_policy = csc_policies[lp_csc_policy(snum)];
1782 switch (r->in.level) {
1784 pathname = lp_path(ctx, snum);
1785 comment = talloc_strdup(ctx, info->info1->comment);
1786 type = info->info1->type;
1790 comment = talloc_strdup(ctx, info->info2->comment);
1791 pathname = info->info2->path;
1792 type = info->info2->type;
1793 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1794 0 : info->info2->max_users;
1798 /* not supported on set but here for completeness */
1800 comment = talloc_strdup(ctx, info->info501->comment);
1801 type = info->info501->type;
1806 comment = talloc_strdup(ctx, info->info502->comment);
1807 pathname = info->info502->path;
1808 type = info->info502->type;
1809 psd = info->info502->sd_buf.sd;
1810 map_generic_share_sd_bits(psd);
1813 pathname = lp_path(ctx, snum);
1814 comment = talloc_strdup(ctx, info->info1004->comment);
1815 type = STYPE_DISKTREE;
1818 /* XP re-sets the csc policy even if it wasn't changed by the
1819 user, so we must compare it to see if it's what is set in
1820 smb.conf, so that we can contine other ops like setting
1822 client_csc_policy = (info->info1005->dfs_flags &
1823 SHARE_1005_CSC_POLICY_MASK) >>
1824 SHARE_1005_CSC_POLICY_SHIFT;
1826 if (client_csc_policy == lp_csc_policy(snum))
1829 csc_policy = csc_policies[client_csc_policy];
1830 csc_policy_changed = true;
1833 pathname = lp_path(ctx, snum);
1834 comment = lp_comment(ctx, snum);
1835 type = STYPE_DISKTREE;
1839 return WERR_ACCESS_DENIED;
1841 pathname = lp_path(ctx, snum);
1842 comment = lp_comment(ctx, snum);
1843 psd = info->info1501->sd;
1844 map_generic_share_sd_bits(psd);
1845 type = STYPE_DISKTREE;
1848 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1850 return WERR_INVALID_LEVEL;
1853 /* We can only modify disk shares. */
1854 if (type != STYPE_DISKTREE) {
1855 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1858 return WERR_ACCESS_DENIED;
1861 if (comment == NULL) {
1862 return WERR_NOT_ENOUGH_MEMORY;
1865 /* Check if the pathname is valid. */
1866 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1867 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1869 return WERR_BAD_PATHNAME;
1872 /* Ensure share name, pathname and comment don't contain '"' characters. */
1873 string_replace(share_name, '"', ' ');
1874 string_replace(path, '"', ' ');
1875 string_replace(comment, '"', ' ');
1877 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1878 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1880 /* Only call modify function if something changed. */
1882 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1883 || (lp_max_connections(snum) != max_connections)
1884 || csc_policy_changed) {
1886 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1887 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1888 return WERR_ACCESS_DENIED;
1891 command = talloc_asprintf(p->mem_ctx,
1892 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1893 lp_change_share_command(talloc_tos()),
1894 get_dyn_CONFIGFILE(),
1901 return WERR_NOT_ENOUGH_MEMORY;
1904 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1906 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1911 ret = smbrun(command, NULL, NULL);
1913 /* Tell everyone we updated smb.conf. */
1914 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1921 /********* END SeDiskOperatorPrivilege BLOCK *********/
1923 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1926 TALLOC_FREE(command);
1929 return WERR_ACCESS_DENIED;
1931 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1935 /* Replace SD if changed. */
1937 struct security_descriptor *old_sd;
1940 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1942 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1943 if (!set_share_security(share_name, psd))
1944 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1949 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1954 /*******************************************************************
1955 _srvsvc_NetShareAdd.
1956 Call 'add_share_command "sharename" "pathname"
1957 "comment" "max connections = "
1958 ********************************************************************/
1960 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1961 struct srvsvc_NetShareAdd *r)
1963 char *command = NULL;
1964 char *share_name_in = NULL;
1965 char *share_name = NULL;
1966 char *comment = NULL;
1967 char *pathname = NULL;
1972 struct security_descriptor *psd = NULL;
1974 int max_connections = 0;
1976 TALLOC_CTX *ctx = p->mem_ctx;
1978 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1980 if (r->out.parm_error) {
1981 *r->out.parm_error = 0;
1984 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1986 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1987 return WERR_ACCESS_DENIED;
1989 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1990 DBG_WARNING("_srvsvc_NetShareAdd: No \"add share command\" parameter set in smb.conf.\n");
1991 return WERR_ACCESS_DENIED;
1994 switch (r->in.level) {
1996 /* No path. Not enough info in a level 0 to do anything. */
1997 return WERR_ACCESS_DENIED;
1999 /* Not enough info in a level 1 to do anything. */
2000 return WERR_ACCESS_DENIED;
2002 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
2003 comment = talloc_strdup(ctx, r->in.info->info2->comment);
2004 pathname = talloc_strdup(ctx, r->in.info->info2->path);
2005 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
2006 0 : r->in.info->info2->max_users;
2007 type = r->in.info->info2->type;
2010 /* No path. Not enough info in a level 501 to do anything. */
2011 return WERR_ACCESS_DENIED;
2013 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2014 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2015 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2016 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2017 0 : r->in.info->info502->max_users;
2018 type = r->in.info->info502->type;
2019 psd = r->in.info->info502->sd_buf.sd;
2020 map_generic_share_sd_bits(psd);
2023 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2029 return WERR_ACCESS_DENIED;
2031 /* DFS only level. */
2032 return WERR_ACCESS_DENIED;
2034 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2036 return WERR_INVALID_LEVEL;
2039 /* check for invalid share names */
2041 if (!share_name_in || !validate_net_name(share_name_in,
2042 INVALID_SHARENAME_CHARS,
2043 strlen(share_name_in))) {
2044 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2045 share_name_in ? share_name_in : ""));
2046 return WERR_INVALID_NAME;
2049 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2050 || (lp_enable_asu_support() &&
2051 strequal(share_name_in,"ADMIN$"))) {
2052 return WERR_ACCESS_DENIED;
2055 snum = find_service(ctx, share_name_in, &share_name);
2057 return WERR_NOT_ENOUGH_MEMORY;
2060 /* Share already exists. */
2062 return WERR_FILE_EXISTS;
2065 /* We can only add disk shares. */
2066 if (type != STYPE_DISKTREE) {
2067 return WERR_ACCESS_DENIED;
2070 /* Check if the pathname is valid. */
2071 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2072 return WERR_BAD_PATHNAME;
2075 ret = sys_lstat(path, &st, false);
2076 if (ret == -1 && (errno != EACCES)) {
2078 * If path has any other than permission
2079 * problem, return WERR_FILE_NOT_FOUND (as Windows
2082 return WERR_FILE_NOT_FOUND;
2085 /* Ensure share name, pathname and comment don't contain '"' characters. */
2086 string_replace(share_name_in, '"', ' ');
2087 string_replace(share_name, '"', ' ');
2088 string_replace(path, '"', ' ');
2090 string_replace(comment, '"', ' ');
2093 command = talloc_asprintf(ctx,
2094 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2095 lp_add_share_command(talloc_tos()),
2096 get_dyn_CONFIGFILE(),
2099 comment ? comment : "",
2102 return WERR_NOT_ENOUGH_MEMORY;
2105 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2107 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2112 /* FIXME: use libnetconf here - gd */
2114 ret = smbrun(command, NULL, NULL);
2116 /* Tell everyone we updated smb.conf. */
2117 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
2123 /********* END SeDiskOperatorPrivilege BLOCK *********/
2125 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2128 TALLOC_FREE(command);
2131 return WERR_ACCESS_DENIED;
2134 /* Note we use share_name here, not share_name_in as
2135 we need a canonicalized name for setting security. */
2136 if (!set_share_security(share_name, psd)) {
2137 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2143 * We don't call reload_services() here, the message will
2144 * cause this to be done before the next packet is read
2145 * from the client. JRA.
2148 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2153 /*******************************************************************
2155 Call "delete share command" with the share name as
2157 ********************************************************************/
2159 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2160 struct srvsvc_NetShareDel *r)
2162 char *command = NULL;
2163 char *share_name = NULL;
2167 TALLOC_CTX *ctx = p->mem_ctx;
2169 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2171 if (!r->in.share_name) {
2172 return WERR_NERR_NETNAMENOTFOUND;
2175 if ( strequal(r->in.share_name,"IPC$")
2176 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2177 || strequal(r->in.share_name,"global") )
2179 return WERR_ACCESS_DENIED;
2182 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2184 return WERR_NOT_ENOUGH_MEMORY;
2188 return WERR_BAD_NET_NAME;
2191 /* No change to printer shares. */
2192 if (lp_printable(snum))
2193 return WERR_ACCESS_DENIED;
2195 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2197 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2198 return WERR_ACCESS_DENIED;
2200 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2201 DBG_WARNING("_srvsvc_NetShareDel: No \"delete share command\" parameter set in smb.conf.\n");
2202 return WERR_ACCESS_DENIED;
2205 command = talloc_asprintf(ctx,
2207 lp_delete_share_command(talloc_tos()),
2208 get_dyn_CONFIGFILE(),
2211 return WERR_NOT_ENOUGH_MEMORY;
2214 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2216 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2221 ret = smbrun(command, NULL, NULL);
2223 /* Tell everyone we updated smb.conf. */
2224 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
2230 /********* END SeDiskOperatorPrivilege BLOCK *********/
2232 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2235 return WERR_ACCESS_DENIED;
2237 /* Delete the SD in the database. */
2238 delete_share_security(share_name);
2240 lp_killservice(snum);
2245 /*******************************************************************
2246 _srvsvc_NetShareDelSticky
2247 ********************************************************************/
2249 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2250 struct srvsvc_NetShareDelSticky *r)
2252 struct srvsvc_NetShareDel q;
2254 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2256 q.in.server_unc = r->in.server_unc;
2257 q.in.share_name = r->in.share_name;
2258 q.in.reserved = r->in.reserved;
2260 return _srvsvc_NetShareDel(p, &q);
2263 /*******************************************************************
2264 _srvsvc_NetRemoteTOD
2265 ********************************************************************/
2267 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2268 struct srvsvc_NetRemoteTOD *r)
2270 struct srvsvc_NetRemoteTODInfo *tod;
2272 time_t unixdate = time(NULL);
2274 /* We do this call first as if we do it *after* the gmtime call
2275 it overwrites the pointed-to values. JRA */
2277 uint32_t zone = get_time_zone(unixdate)/60;
2279 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2281 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2282 return WERR_NOT_ENOUGH_MEMORY;
2286 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2288 t = gmtime(&unixdate);
2291 tod->elapsed = unixdate;
2293 tod->hours = t->tm_hour;
2294 tod->mins = t->tm_min;
2295 tod->secs = t->tm_sec;
2297 tod->timezone = zone;
2298 tod->tinterval = 10000;
2299 tod->day = t->tm_mday;
2300 tod->month = t->tm_mon + 1;
2301 tod->year = 1900+t->tm_year;
2302 tod->weekday = t->tm_wday;
2304 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2309 /***********************************************************************************
2310 _srvsvc_NetGetFileSecurity
2311 Win9x NT tools get security descriptor.
2312 ***********************************************************************************/
2314 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2315 struct srvsvc_NetGetFileSecurity *r)
2317 struct smb_filename *smb_fname = NULL;
2319 char *servicename = NULL;
2323 connection_struct *conn = NULL;
2324 struct sec_desc_buf *sd_buf = NULL;
2325 files_struct *fsp = NULL;
2327 struct smb_filename *oldcwd_fname = NULL;
2328 uint32_t ucf_flags = 0;
2333 werr = WERR_NERR_NETNAMENOTFOUND;
2336 snum = find_service(talloc_tos(), r->in.share, &servicename);
2338 werr = WERR_NOT_ENOUGH_MEMORY;
2342 DEBUG(10, ("Could not find service %s\n", servicename));
2343 werr = WERR_NERR_NETNAMENOTFOUND;
2347 nt_status = create_conn_struct_cwd(talloc_tos(),
2348 server_event_context(),
2349 server_messaging_context(),
2351 snum, lp_path(talloc_tos(), snum),
2352 p->session_info, &oldcwd_fname);
2353 if (!NT_STATUS_IS_OK(nt_status)) {
2354 DEBUG(10, ("create_conn_struct failed: %s\n",
2355 nt_errstr(nt_status)));
2356 werr = ntstatus_to_werror(nt_status);
2360 nt_status = filename_convert(talloc_tos(),
2366 if (!NT_STATUS_IS_OK(nt_status)) {
2367 werr = ntstatus_to_werror(nt_status);
2371 nt_status = SMB_VFS_CREATE_FILE(
2374 0, /* root_dir_fid */
2375 smb_fname, /* fname */
2376 FILE_READ_ATTRIBUTES, /* access_mask */
2377 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2378 FILE_OPEN, /* create_disposition*/
2379 0, /* create_options */
2380 0, /* file_attributes */
2381 INTERNAL_OPEN_ONLY, /* oplock_request */
2383 0, /* allocation_size */
2384 0, /* private_flags */
2389 NULL, NULL); /* create context */
2391 if (!NT_STATUS_IS_OK(nt_status)) {
2392 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2393 smb_fname_str_dbg(smb_fname)));
2394 werr = ntstatus_to_werror(nt_status);
2398 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2400 werr = WERR_NOT_ENOUGH_MEMORY;
2404 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2407 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2409 if (!NT_STATUS_IS_OK(nt_status)) {
2410 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2411 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2412 werr = ntstatus_to_werror(nt_status);
2413 TALLOC_FREE(sd_buf);
2417 if (sd_buf->sd->dacl) {
2418 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2421 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2423 sd_buf->sd_size = sd_size;
2425 *r->out.sd_buf = sd_buf;
2432 close_file(NULL, fsp, NORMAL_CLOSE);
2436 vfs_ChDir(conn, oldcwd_fname);
2437 TALLOC_FREE(oldcwd_fname);
2441 SMB_VFS_DISCONNECT(conn);
2445 TALLOC_FREE(smb_fname);
2450 /***********************************************************************************
2451 _srvsvc_NetSetFileSecurity
2452 Win9x NT tools set security descriptor.
2453 ***********************************************************************************/
2455 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2456 struct srvsvc_NetSetFileSecurity *r)
2458 struct smb_filename *smb_fname = NULL;
2459 char *servicename = NULL;
2460 files_struct *fsp = NULL;
2464 connection_struct *conn = NULL;
2466 struct smb_filename *oldcwd_fname = NULL;
2467 struct security_descriptor *psd = NULL;
2468 uint32_t security_info_sent = 0;
2469 uint32_t ucf_flags = 0;
2474 werr = WERR_NERR_NETNAMENOTFOUND;
2478 snum = find_service(talloc_tos(), r->in.share, &servicename);
2480 werr = WERR_NOT_ENOUGH_MEMORY;
2485 DEBUG(10, ("Could not find service %s\n", servicename));
2486 werr = WERR_NERR_NETNAMENOTFOUND;
2490 nt_status = create_conn_struct_cwd(talloc_tos(),
2491 server_event_context(),
2492 server_messaging_context(),
2494 snum, lp_path(talloc_tos(), snum),
2495 p->session_info, &oldcwd_fname);
2496 if (!NT_STATUS_IS_OK(nt_status)) {
2497 DEBUG(10, ("create_conn_struct failed: %s\n",
2498 nt_errstr(nt_status)));
2499 werr = ntstatus_to_werror(nt_status);
2503 nt_status = filename_convert(talloc_tos(),
2509 if (!NT_STATUS_IS_OK(nt_status)) {
2510 werr = ntstatus_to_werror(nt_status);
2514 nt_status = SMB_VFS_CREATE_FILE(
2517 0, /* root_dir_fid */
2518 smb_fname, /* fname */
2519 FILE_WRITE_ATTRIBUTES, /* access_mask */
2520 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2521 FILE_OPEN, /* create_disposition*/
2522 0, /* create_options */
2523 0, /* file_attributes */
2524 INTERNAL_OPEN_ONLY, /* oplock_request */
2526 0, /* allocation_size */
2527 0, /* private_flags */
2532 NULL, NULL); /* create context */
2534 if (!NT_STATUS_IS_OK(nt_status)) {
2535 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2536 smb_fname_str_dbg(smb_fname)));
2537 werr = ntstatus_to_werror(nt_status);
2541 psd = r->in.sd_buf->sd;
2542 security_info_sent = r->in.securityinformation;
2544 nt_status = set_sd(fsp, psd, security_info_sent);
2546 if (!NT_STATUS_IS_OK(nt_status) ) {
2547 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2548 "on file %s\n", r->in.share));
2549 werr = WERR_ACCESS_DENIED;
2558 close_file(NULL, fsp, NORMAL_CLOSE);
2562 vfs_ChDir(conn, oldcwd_fname);
2563 TALLOC_FREE(oldcwd_fname);
2567 SMB_VFS_DISCONNECT(conn);
2571 TALLOC_FREE(smb_fname);
2576 /***********************************************************************************
2577 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2578 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2579 These disks would the disks listed by this function.
2580 Users could then create shares relative to these disks. Watch out for moving these disks around.
2581 "Nigel Williams" <nigel@veritas.com>.
2582 ***********************************************************************************/
2584 static const char *server_disks[] = {"C:"};
2586 static uint32_t get_server_disk_count(void)
2588 return sizeof(server_disks)/sizeof(server_disks[0]);
2591 static uint32_t init_server_disk_enum(uint32_t *resume)
2593 uint32_t server_disk_count = get_server_disk_count();
2595 /*resume can be an offset into the list for now*/
2597 if(*resume & 0x80000000)
2600 if(*resume > server_disk_count)
2601 *resume = server_disk_count;
2603 return server_disk_count - *resume;
2606 static const char *next_server_disk_enum(uint32_t *resume)
2610 if(init_server_disk_enum(resume) == 0)
2613 disk = server_disks[*resume];
2617 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2622 /********************************************************************
2624 ********************************************************************/
2626 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2627 struct srvsvc_NetDiskEnum *r)
2630 const char *disk_name;
2631 TALLOC_CTX *ctx = p->mem_ctx;
2633 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2637 *r->out.totalentries = init_server_disk_enum(&resume);
2639 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2640 MAX_SERVER_DISK_ENTRIES);
2641 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2643 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2645 r->out.info->count = 0;
2647 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2649 r->out.info->count++;
2651 /*copy disk name into a unicode string*/
2653 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2654 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2657 /* add a terminating null string. Is this there if there is more data to come? */
2659 r->out.info->count++;
2661 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2662 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2664 if (r->out.resume_handle) {
2665 *r->out.resume_handle = resume;
2671 /********************************************************************
2672 _srvsvc_NetNameValidate
2673 ********************************************************************/
2675 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2676 struct srvsvc_NetNameValidate *r)
2678 switch (r->in.name_type) {
2680 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2681 strlen_m(r->in.name)))
2683 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2685 return WERR_INVALID_NAME;
2690 return WERR_INVALID_LEVEL;
2696 /*******************************************************************
2697 ********************************************************************/
2699 struct enum_file_close_state {
2700 struct srvsvc_NetFileClose *r;
2701 struct messaging_context *msg_ctx;
2704 static int enum_file_close_fn(const struct share_mode_entry *e,
2705 const struct file_id *id,
2706 const char *sharepath,
2711 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2712 struct enum_file_close_state *state =
2713 (struct enum_file_close_state *)private_data;
2714 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2716 if (fid != state->r->in.fid) {
2717 return 0; /* Not this file. */
2720 if (!process_exists(e->pid) ) {
2724 /* Ok - send the close message. */
2725 DBG_DEBUG("request to close file %s, %s\n", sharepath,
2726 share_mode_str(talloc_tos(), 0, id, e));
2728 share_mode_entry_to_message(msg, id, e);
2730 state->r->out.result = ntstatus_to_werror(
2731 messaging_send_buf(state->msg_ctx,
2732 e->pid, MSG_SMB_CLOSE_FILE,
2733 (uint8_t *)msg, sizeof(msg)));
2738 /********************************************************************
2739 Close a file given a 32-bit file id.
2740 ********************************************************************/
2742 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2743 struct srvsvc_NetFileClose *r)
2745 struct enum_file_close_state state;
2748 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2750 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2752 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2753 return WERR_ACCESS_DENIED;
2756 /* enum_file_close_fn sends the close message to
2757 * the relevant smbd process. */
2759 r->out.result = WERR_FILE_NOT_FOUND;
2761 state.msg_ctx = p->msg_ctx;
2762 share_entry_forall(enum_file_close_fn, &state);
2763 return r->out.result;
2766 /********************************************************************
2767 ********************************************************************/
2769 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2770 struct srvsvc_NetCharDevEnum *r)
2772 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2773 return WERR_NOT_SUPPORTED;
2776 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2777 struct srvsvc_NetCharDevGetInfo *r)
2779 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2780 return WERR_NOT_SUPPORTED;
2783 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2784 struct srvsvc_NetCharDevControl *r)
2786 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2787 return WERR_NOT_SUPPORTED;
2790 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2791 struct srvsvc_NetCharDevQEnum *r)
2793 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2794 return WERR_NOT_SUPPORTED;
2797 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2798 struct srvsvc_NetCharDevQGetInfo *r)
2800 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2801 return WERR_NOT_SUPPORTED;
2804 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2805 struct srvsvc_NetCharDevQSetInfo *r)
2807 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2808 return WERR_NOT_SUPPORTED;
2811 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2812 struct srvsvc_NetCharDevQPurge *r)
2814 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2815 return WERR_NOT_SUPPORTED;
2818 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2819 struct srvsvc_NetCharDevQPurgeSelf *r)
2821 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2822 return WERR_NOT_SUPPORTED;
2825 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2826 struct srvsvc_NetFileGetInfo *r)
2828 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2829 return WERR_NOT_SUPPORTED;
2832 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2833 struct srvsvc_NetShareCheck *r)
2835 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2836 return WERR_NOT_SUPPORTED;
2839 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2840 struct srvsvc_NetServerStatisticsGet *r)
2842 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2843 return WERR_NOT_SUPPORTED;
2846 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2847 struct srvsvc_NetTransportAdd *r)
2849 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2850 return WERR_NOT_SUPPORTED;
2853 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2854 struct srvsvc_NetTransportEnum *r)
2856 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2857 return WERR_NOT_SUPPORTED;
2860 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2861 struct srvsvc_NetTransportDel *r)
2863 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2864 return WERR_NOT_SUPPORTED;
2867 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2868 struct srvsvc_NetSetServiceBits *r)
2870 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2871 return WERR_NOT_SUPPORTED;
2874 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2875 struct srvsvc_NetPathType *r)
2877 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2878 return WERR_NOT_SUPPORTED;
2881 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2882 struct srvsvc_NetPathCanonicalize *r)
2884 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2885 return WERR_NOT_SUPPORTED;
2888 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2889 struct srvsvc_NetPathCompare *r)
2891 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2892 return WERR_NOT_SUPPORTED;
2895 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2896 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2898 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2899 return WERR_NOT_SUPPORTED;
2902 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2903 struct srvsvc_NetPRNameCompare *r)
2905 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2906 return WERR_NOT_SUPPORTED;
2909 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2910 struct srvsvc_NetShareDelStart *r)
2912 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2913 return WERR_NOT_SUPPORTED;
2916 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2917 struct srvsvc_NetShareDelCommit *r)
2919 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2920 return WERR_NOT_SUPPORTED;
2923 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2924 struct srvsvc_NetServerTransportAddEx *r)
2926 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2927 return WERR_NOT_SUPPORTED;
2930 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2931 struct srvsvc_NetServerSetServiceBitsEx *r)
2933 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2934 return WERR_NOT_SUPPORTED;
2937 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2938 struct srvsvc_NETRDFSGETVERSION *r)
2940 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2941 return WERR_NOT_SUPPORTED;
2944 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2945 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2947 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2948 return WERR_NOT_SUPPORTED;
2951 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2952 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2954 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2955 return WERR_NOT_SUPPORTED;
2958 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2959 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2961 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2962 return WERR_NOT_SUPPORTED;
2965 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2966 struct srvsvc_NETRDFSSETSERVERINFO *r)
2968 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2969 return WERR_NOT_SUPPORTED;
2972 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2973 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2975 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2976 return WERR_NOT_SUPPORTED;
2979 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2980 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2982 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2983 return WERR_NOT_SUPPORTED;
2986 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2987 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2989 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2990 return WERR_NOT_SUPPORTED;
2993 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2994 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2996 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2997 return WERR_NOT_SUPPORTED;
3000 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3001 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3003 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3004 return WERR_NOT_SUPPORTED;
3007 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3008 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3010 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3011 return WERR_NOT_SUPPORTED;