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();
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 TALLOC_CTX *frame = talloc_stackframe();
2318 struct smb_filename *smb_fname = NULL;
2320 char *servicename = NULL;
2324 struct conn_struct_tos *c = NULL;
2325 connection_struct *conn = NULL;
2326 struct sec_desc_buf *sd_buf = NULL;
2327 files_struct *fsp = NULL;
2329 uint32_t ucf_flags = 0;
2334 werr = WERR_NERR_NETNAMENOTFOUND;
2337 snum = find_service(frame, r->in.share, &servicename);
2339 werr = WERR_NOT_ENOUGH_MEMORY;
2343 DEBUG(10, ("Could not find service %s\n", servicename));
2344 werr = WERR_NERR_NETNAMENOTFOUND;
2348 nt_status = create_conn_struct_tos_cwd(server_messaging_context(),
2350 lp_path(frame, snum),
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);
2361 nt_status = filename_convert(frame,
2367 if (!NT_STATUS_IS_OK(nt_status)) {
2368 werr = ntstatus_to_werror(nt_status);
2372 nt_status = SMB_VFS_CREATE_FILE(
2375 0, /* root_dir_fid */
2376 smb_fname, /* fname */
2377 FILE_READ_ATTRIBUTES, /* access_mask */
2378 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2379 FILE_OPEN, /* create_disposition*/
2380 0, /* create_options */
2381 0, /* file_attributes */
2382 INTERNAL_OPEN_ONLY, /* oplock_request */
2384 0, /* allocation_size */
2385 0, /* private_flags */
2390 NULL, NULL); /* create context */
2392 if (!NT_STATUS_IS_OK(nt_status)) {
2393 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2394 smb_fname_str_dbg(smb_fname)));
2395 werr = ntstatus_to_werror(nt_status);
2399 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2401 werr = WERR_NOT_ENOUGH_MEMORY;
2405 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2408 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2410 if (!NT_STATUS_IS_OK(nt_status)) {
2411 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2412 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2413 werr = ntstatus_to_werror(nt_status);
2414 TALLOC_FREE(sd_buf);
2418 if (sd_buf->sd->dacl) {
2419 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2422 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2424 sd_buf->sd_size = sd_size;
2426 *r->out.sd_buf = sd_buf;
2433 close_file(NULL, fsp, NORMAL_CLOSE);
2440 /***********************************************************************************
2441 _srvsvc_NetSetFileSecurity
2442 Win9x NT tools set security descriptor.
2443 ***********************************************************************************/
2445 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2446 struct srvsvc_NetSetFileSecurity *r)
2448 TALLOC_CTX *frame = talloc_stackframe();
2449 struct smb_filename *smb_fname = NULL;
2450 char *servicename = NULL;
2451 files_struct *fsp = NULL;
2455 connection_struct *conn = NULL;
2457 struct smb_filename *oldcwd_fname = NULL;
2458 struct security_descriptor *psd = NULL;
2459 uint32_t security_info_sent = 0;
2460 uint32_t ucf_flags = 0;
2465 werr = WERR_NERR_NETNAMENOTFOUND;
2469 snum = find_service(frame, r->in.share, &servicename);
2471 werr = WERR_NOT_ENOUGH_MEMORY;
2476 DEBUG(10, ("Could not find service %s\n", servicename));
2477 werr = WERR_NERR_NETNAMENOTFOUND;
2481 nt_status = create_conn_struct_cwd(frame,
2482 server_event_context(),
2483 server_messaging_context(),
2485 snum, lp_path(frame, snum),
2486 p->session_info, &oldcwd_fname);
2487 if (!NT_STATUS_IS_OK(nt_status)) {
2488 DEBUG(10, ("create_conn_struct failed: %s\n",
2489 nt_errstr(nt_status)));
2490 werr = ntstatus_to_werror(nt_status);
2494 nt_status = filename_convert(frame,
2500 if (!NT_STATUS_IS_OK(nt_status)) {
2501 werr = ntstatus_to_werror(nt_status);
2505 nt_status = SMB_VFS_CREATE_FILE(
2508 0, /* root_dir_fid */
2509 smb_fname, /* fname */
2510 FILE_WRITE_ATTRIBUTES, /* access_mask */
2511 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2512 FILE_OPEN, /* create_disposition*/
2513 0, /* create_options */
2514 0, /* file_attributes */
2515 INTERNAL_OPEN_ONLY, /* oplock_request */
2517 0, /* allocation_size */
2518 0, /* private_flags */
2523 NULL, NULL); /* create context */
2525 if (!NT_STATUS_IS_OK(nt_status)) {
2526 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2527 smb_fname_str_dbg(smb_fname)));
2528 werr = ntstatus_to_werror(nt_status);
2532 psd = r->in.sd_buf->sd;
2533 security_info_sent = r->in.securityinformation;
2535 nt_status = set_sd(fsp, psd, security_info_sent);
2537 if (!NT_STATUS_IS_OK(nt_status) ) {
2538 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2539 "on file %s\n", r->in.share));
2540 werr = WERR_ACCESS_DENIED;
2549 close_file(NULL, fsp, NORMAL_CLOSE);
2553 vfs_ChDir(conn, oldcwd_fname);
2557 SMB_VFS_DISCONNECT(conn);
2565 /***********************************************************************************
2566 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2567 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2568 These disks would the disks listed by this function.
2569 Users could then create shares relative to these disks. Watch out for moving these disks around.
2570 "Nigel Williams" <nigel@veritas.com>.
2571 ***********************************************************************************/
2573 static const char *server_disks[] = {"C:"};
2575 static uint32_t get_server_disk_count(void)
2577 return sizeof(server_disks)/sizeof(server_disks[0]);
2580 static uint32_t init_server_disk_enum(uint32_t *resume)
2582 uint32_t server_disk_count = get_server_disk_count();
2584 /*resume can be an offset into the list for now*/
2586 if(*resume & 0x80000000)
2589 if(*resume > server_disk_count)
2590 *resume = server_disk_count;
2592 return server_disk_count - *resume;
2595 static const char *next_server_disk_enum(uint32_t *resume)
2599 if(init_server_disk_enum(resume) == 0)
2602 disk = server_disks[*resume];
2606 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2611 /********************************************************************
2613 ********************************************************************/
2615 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2616 struct srvsvc_NetDiskEnum *r)
2619 const char *disk_name;
2620 TALLOC_CTX *ctx = p->mem_ctx;
2622 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2626 *r->out.totalentries = init_server_disk_enum(&resume);
2628 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2629 MAX_SERVER_DISK_ENTRIES);
2630 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2632 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2634 r->out.info->count = 0;
2636 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2638 r->out.info->count++;
2640 /*copy disk name into a unicode string*/
2642 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2643 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2646 /* add a terminating null string. Is this there if there is more data to come? */
2648 r->out.info->count++;
2650 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2651 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2653 if (r->out.resume_handle) {
2654 *r->out.resume_handle = resume;
2660 /********************************************************************
2661 _srvsvc_NetNameValidate
2662 ********************************************************************/
2664 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2665 struct srvsvc_NetNameValidate *r)
2667 switch (r->in.name_type) {
2669 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2670 strlen_m(r->in.name)))
2672 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2674 return WERR_INVALID_NAME;
2679 return WERR_INVALID_LEVEL;
2685 /*******************************************************************
2686 ********************************************************************/
2688 struct enum_file_close_state {
2689 struct srvsvc_NetFileClose *r;
2690 struct messaging_context *msg_ctx;
2693 static int enum_file_close_fn(const struct share_mode_entry *e,
2694 const struct file_id *id,
2695 const char *sharepath,
2700 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2701 struct enum_file_close_state *state =
2702 (struct enum_file_close_state *)private_data;
2703 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2705 if (fid != state->r->in.fid) {
2706 return 0; /* Not this file. */
2709 if (!process_exists(e->pid) ) {
2713 /* Ok - send the close message. */
2714 DBG_DEBUG("request to close file %s, %s\n", sharepath,
2715 share_mode_str(talloc_tos(), 0, id, e));
2717 share_mode_entry_to_message(msg, id, e);
2719 state->r->out.result = ntstatus_to_werror(
2720 messaging_send_buf(state->msg_ctx,
2721 e->pid, MSG_SMB_CLOSE_FILE,
2722 (uint8_t *)msg, sizeof(msg)));
2727 /********************************************************************
2728 Close a file given a 32-bit file id.
2729 ********************************************************************/
2731 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2732 struct srvsvc_NetFileClose *r)
2734 struct enum_file_close_state state;
2737 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2739 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2741 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2742 return WERR_ACCESS_DENIED;
2745 /* enum_file_close_fn sends the close message to
2746 * the relevant smbd process. */
2748 r->out.result = WERR_FILE_NOT_FOUND;
2750 state.msg_ctx = p->msg_ctx;
2751 share_entry_forall(enum_file_close_fn, &state);
2752 return r->out.result;
2755 /********************************************************************
2756 ********************************************************************/
2758 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2759 struct srvsvc_NetCharDevEnum *r)
2761 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2762 return WERR_NOT_SUPPORTED;
2765 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2766 struct srvsvc_NetCharDevGetInfo *r)
2768 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2769 return WERR_NOT_SUPPORTED;
2772 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2773 struct srvsvc_NetCharDevControl *r)
2775 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2776 return WERR_NOT_SUPPORTED;
2779 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2780 struct srvsvc_NetCharDevQEnum *r)
2782 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2783 return WERR_NOT_SUPPORTED;
2786 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2787 struct srvsvc_NetCharDevQGetInfo *r)
2789 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2790 return WERR_NOT_SUPPORTED;
2793 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2794 struct srvsvc_NetCharDevQSetInfo *r)
2796 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2797 return WERR_NOT_SUPPORTED;
2800 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2801 struct srvsvc_NetCharDevQPurge *r)
2803 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2804 return WERR_NOT_SUPPORTED;
2807 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2808 struct srvsvc_NetCharDevQPurgeSelf *r)
2810 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2811 return WERR_NOT_SUPPORTED;
2814 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2815 struct srvsvc_NetFileGetInfo *r)
2817 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2818 return WERR_NOT_SUPPORTED;
2821 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2822 struct srvsvc_NetShareCheck *r)
2824 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2825 return WERR_NOT_SUPPORTED;
2828 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2829 struct srvsvc_NetServerStatisticsGet *r)
2831 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2832 return WERR_NOT_SUPPORTED;
2835 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2836 struct srvsvc_NetTransportAdd *r)
2838 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2839 return WERR_NOT_SUPPORTED;
2842 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2843 struct srvsvc_NetTransportEnum *r)
2845 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2846 return WERR_NOT_SUPPORTED;
2849 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2850 struct srvsvc_NetTransportDel *r)
2852 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2853 return WERR_NOT_SUPPORTED;
2856 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2857 struct srvsvc_NetSetServiceBits *r)
2859 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2860 return WERR_NOT_SUPPORTED;
2863 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2864 struct srvsvc_NetPathType *r)
2866 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2867 return WERR_NOT_SUPPORTED;
2870 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2871 struct srvsvc_NetPathCanonicalize *r)
2873 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2874 return WERR_NOT_SUPPORTED;
2877 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2878 struct srvsvc_NetPathCompare *r)
2880 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2881 return WERR_NOT_SUPPORTED;
2884 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2885 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2887 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2888 return WERR_NOT_SUPPORTED;
2891 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2892 struct srvsvc_NetPRNameCompare *r)
2894 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2895 return WERR_NOT_SUPPORTED;
2898 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2899 struct srvsvc_NetShareDelStart *r)
2901 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2902 return WERR_NOT_SUPPORTED;
2905 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2906 struct srvsvc_NetShareDelCommit *r)
2908 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2909 return WERR_NOT_SUPPORTED;
2912 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2913 struct srvsvc_NetServerTransportAddEx *r)
2915 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2916 return WERR_NOT_SUPPORTED;
2919 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2920 struct srvsvc_NetServerSetServiceBitsEx *r)
2922 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2923 return WERR_NOT_SUPPORTED;
2926 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2927 struct srvsvc_NETRDFSGETVERSION *r)
2929 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2930 return WERR_NOT_SUPPORTED;
2933 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2934 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2936 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2937 return WERR_NOT_SUPPORTED;
2940 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2941 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2943 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2944 return WERR_NOT_SUPPORTED;
2947 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2948 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2950 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2951 return WERR_NOT_SUPPORTED;
2954 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2955 struct srvsvc_NETRDFSSETSERVERINFO *r)
2957 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2958 return WERR_NOT_SUPPORTED;
2961 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2962 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2964 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2965 return WERR_NOT_SUPPORTED;
2968 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2969 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2971 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2972 return WERR_NOT_SUPPORTED;
2975 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2976 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2978 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2979 return WERR_NOT_SUPPORTED;
2982 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2983 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2985 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2986 return WERR_NOT_SUPPORTED;
2989 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2990 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2992 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2993 return WERR_NOT_SUPPORTED;
2996 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2997 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2999 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3000 return WERR_NOT_SUPPORTED;