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"
43 extern const struct generic_mapping file_generic_mapping;
46 #define DBGC_CLASS DBGC_RPC_SRV
48 #define MAX_SERVER_DISK_ENTRIES 15
50 /* Use for enumerating connections, pipes, & files */
52 struct file_enum_count {
55 struct srvsvc_NetFileCtr3 *ctr3;
58 struct sess_file_info {
59 struct srvsvc_NetSessCtr1 *ctr;
60 struct sessionid *session_list;
61 uint32_t resume_handle;
65 struct share_file_stat {
66 struct srvsvc_NetConnInfo1 *netconn_arr;
67 struct server_id *svrid_arr;
68 const char *in_sharepath;
69 uint32_t resp_entries;
70 uint32_t total_entries;
73 struct share_conn_stat {
75 const char *sharename;
76 struct server_id *svrid_arr;
80 /*******************************************************************
81 ********************************************************************/
83 static int enum_file_fn(struct file_id id,
84 const struct share_mode_data *d,
85 const struct share_mode_entry *e,
88 struct file_enum_count *fenum =
89 (struct file_enum_count *)private_data;
91 struct srvsvc_NetFileInfo3 *f;
92 int i = fenum->ctr3->count;
94 struct byte_range_lock *brl;
96 char *fullpath = NULL;
100 /* If the pid was not found delete the entry from connections.tdb */
102 if ( !process_exists(e->pid) ) {
106 username = uidtoname(e->uid);
108 if ((fenum->username != NULL)
109 && !strequal(username, fenum->username)) {
113 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
114 struct srvsvc_NetFileInfo3, i+1);
116 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
119 fenum->ctr3->array = f;
121 /* need to count the number of locks on a file */
126 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
127 num_locks = brl_num_locks(brl);
131 if ( strcmp(d->base_name, "." ) == 0 ) {
132 fullpath = talloc_asprintf(
137 fullpath = talloc_asprintf(
142 (d->stream_name != NULL) ? d->stream_name : "");
147 string_replace( fullpath, '/', '\\' );
149 /* mask out create (what ever that is) */
150 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
152 /* now fill in the srvsvc_NetFileInfo3 struct */
154 fenum->ctr3->array[i].fid =
155 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
156 fenum->ctr3->array[i].permissions = permissions;
157 fenum->ctr3->array[i].num_locks = num_locks;
158 fenum->ctr3->array[i].path = fullpath;
159 fenum->ctr3->array[i].user = username;
161 fenum->ctr3->count++;
166 /*******************************************************************
167 ********************************************************************/
169 static WERROR net_enum_files(TALLOC_CTX *ctx,
170 const char *username,
171 struct srvsvc_NetFileCtr3 **ctr3,
174 struct file_enum_count f_enum_cnt;
176 f_enum_cnt.ctx = ctx;
177 f_enum_cnt.username = username;
178 f_enum_cnt.ctr3 = *ctr3;
180 share_entry_forall(enum_file_fn, (void *)&f_enum_cnt );
182 *ctr3 = f_enum_cnt.ctr3;
187 /*******************************************************************
188 Utility function to get the 'type' of a share from an snum.
189 ********************************************************************/
190 static enum srvsvc_ShareType get_share_type(int snum)
192 /* work out the share type */
193 enum srvsvc_ShareType type = STYPE_DISKTREE;
195 if (lp_printable(snum)) {
196 type = lp_administrative_share(snum)
197 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
199 if (strequal(lp_fstype(snum), "IPC")) {
200 type = lp_administrative_share(snum)
201 ? STYPE_IPC_HIDDEN : STYPE_IPC;
206 /*******************************************************************
207 Fill in a share info level 0 structure.
208 ********************************************************************/
210 static void init_srv_share_info_0(struct pipes_struct *p,
211 struct srvsvc_NetShareInfo0 *r, int snum)
213 r->name = lp_servicename(talloc_tos(), snum);
216 /*******************************************************************
217 Fill in a share info level 1 structure.
218 ********************************************************************/
220 static void init_srv_share_info_1(struct pipes_struct *p,
221 struct srvsvc_NetShareInfo1 *r,
224 const struct loadparm_substitution *lp_sub =
225 loadparm_s3_global_substitution();
226 char *net_name = lp_servicename(talloc_tos(), snum);
227 char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
230 remark = talloc_sub_full(
231 p->mem_ctx, lp_servicename(talloc_tos(), snum),
232 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
233 p->session_info->unix_token->uid, get_current_username(),
238 r->type = get_share_type(snum);
239 r->comment = remark ? remark : "";
242 /*******************************************************************
243 Fill in a share info level 2 structure.
244 ********************************************************************/
246 static void init_srv_share_info_2(struct pipes_struct *p,
247 struct srvsvc_NetShareInfo2 *r,
250 const struct loadparm_substitution *lp_sub =
251 loadparm_s3_global_substitution();
254 int max_connections = lp_max_connections(snum);
255 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
256 char *net_name = lp_servicename(talloc_tos(), snum);
258 remark = lp_comment(p->mem_ctx, lp_sub, snum);
260 remark = talloc_sub_full(
261 p->mem_ctx, lp_servicename(talloc_tos(), snum),
262 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
263 p->session_info->unix_token->uid, get_current_username(),
266 path = talloc_asprintf(p->mem_ctx,
267 "C:%s", lp_path(talloc_tos(), lp_sub, snum));
271 * Change / to \\ so that win2k will see it as a valid path.
272 * This was added to enable use of browsing in win2k add
276 string_replace(path, '/', '\\');
280 r->type = get_share_type(snum);
281 r->comment = remark ? remark : "";
283 r->max_users = max_uses;
284 r->current_users = 0; /* computed later */
285 r->path = path ? path : "";
289 /*******************************************************************
290 Map any generic bits to file specific bits.
291 ********************************************************************/
293 static void map_generic_share_sd_bits(struct security_descriptor *psd)
296 struct security_acl *ps_dacl = NULL;
305 for (i = 0; i < ps_dacl->num_aces; i++) {
306 struct security_ace *psa = &ps_dacl->aces[i];
307 uint32_t orig_mask = psa->access_mask;
309 se_map_generic(&psa->access_mask, &file_generic_mapping);
310 psa->access_mask |= orig_mask;
314 /*******************************************************************
315 Fill in a share info level 501 structure.
316 ********************************************************************/
318 static void init_srv_share_info_501(struct pipes_struct *p,
319 struct srvsvc_NetShareInfo501 *r, int snum)
321 const struct loadparm_substitution *lp_sub =
322 loadparm_s3_global_substitution();
323 const char *net_name = lp_servicename(talloc_tos(), snum);
324 char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
327 remark = talloc_sub_full(
328 p->mem_ctx, lp_servicename(talloc_tos(), snum),
329 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
330 p->session_info->unix_token->uid, get_current_username(),
335 r->type = get_share_type(snum);
336 r->comment = remark ? remark : "";
339 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
342 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
345 /*******************************************************************
346 Fill in a share info level 502 structure.
347 ********************************************************************/
349 static void init_srv_share_info_502(struct pipes_struct *p,
350 struct srvsvc_NetShareInfo502 *r, int snum)
352 const struct loadparm_substitution *lp_sub =
353 loadparm_s3_global_substitution();
354 const char *net_name = lp_servicename(talloc_tos(), snum);
356 struct security_descriptor *sd = NULL;
357 struct sec_desc_buf *sd_buf = NULL;
359 TALLOC_CTX *ctx = p->mem_ctx;
360 char *remark = lp_comment(ctx, lp_sub, snum);
363 remark = talloc_sub_full(
364 p->mem_ctx, lp_servicename(talloc_tos(), snum),
365 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
366 p->session_info->unix_token->uid, get_current_username(),
369 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), lp_sub, snum));
372 * Change / to \\ so that win2k will see it as a valid path. This was added to
373 * enable use of browsing in win2k add share dialog.
375 string_replace(path, '/', '\\');
378 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
380 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
383 r->type = get_share_type(snum);
384 r->comment = remark ? remark : "";
386 r->max_users = (uint32_t)-1;
387 r->current_users = 1; /* ??? */
388 r->path = path ? path : "";
393 /***************************************************************************
394 Fill in a share info level 1004 structure.
395 ***************************************************************************/
397 static void init_srv_share_info_1004(struct pipes_struct *p,
398 struct srvsvc_NetShareInfo1004 *r,
401 const struct loadparm_substitution *lp_sub =
402 loadparm_s3_global_substitution();
403 char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
406 remark = talloc_sub_full(
407 p->mem_ctx, lp_servicename(talloc_tos(), snum),
408 get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
409 p->session_info->unix_token->uid, get_current_username(),
413 r->comment = remark ? remark : "";
416 /***************************************************************************
417 Fill in a share info level 1005 structure.
418 ***************************************************************************/
420 static void init_srv_share_info_1005(struct pipes_struct *p,
421 struct srvsvc_NetShareInfo1005 *r,
424 uint32_t dfs_flags = 0;
426 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
427 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
430 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
432 r->dfs_flags = dfs_flags;
435 /***************************************************************************
436 Fill in a share info level 1006 structure.
437 ***************************************************************************/
439 static void init_srv_share_info_1006(struct pipes_struct *p,
440 struct srvsvc_NetShareInfo1006 *r,
443 r->max_users = (uint32_t)-1;
446 /***************************************************************************
447 Fill in a share info level 1007 structure.
448 ***************************************************************************/
450 static void init_srv_share_info_1007(struct pipes_struct *p,
451 struct srvsvc_NetShareInfo1007 *r,
455 r->alternate_directory_name = "";
458 /*******************************************************************
459 Fill in a share info level 1501 structure.
460 ********************************************************************/
462 static void init_srv_share_info_1501(struct pipes_struct *p,
463 struct sec_desc_buf **r,
466 struct security_descriptor *sd;
467 struct sec_desc_buf *sd_buf = NULL;
469 TALLOC_CTX *ctx = p->mem_ctx;
471 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
473 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
479 /*******************************************************************
480 True if it ends in '$'.
481 ********************************************************************/
483 static bool is_hidden_share(int snum)
485 const char *net_name = lp_servicename(talloc_tos(), snum);
487 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
490 /*******************************************************************
491 Verify user is allowed to view share, access based enumeration
492 ********************************************************************/
493 static bool is_enumeration_allowed(struct pipes_struct *p,
496 if (!lp_access_based_share_enum(snum)) {
500 if (!user_ok_token(p->session_info->unix_info->unix_name,
501 p->session_info->info->domain_name,
502 p->session_info->security_token, snum)) {
506 return share_access_check(p->session_info->security_token,
507 lp_servicename(talloc_tos(), snum),
508 FILE_READ_DATA, NULL);
511 /****************************************************************************
512 Count an entry against the respective service.
513 ****************************************************************************/
515 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
517 union srvsvc_NetShareCtr *ctr = NULL;
518 struct srvsvc_NetShareInfo2 *info2 = NULL;
519 int share_entries = 0;
522 ctr = (union srvsvc_NetShareCtr *) udp;
525 share_entries = ctr->ctr2->count;
526 info2 = &ctr->ctr2->array[0];
528 for (i = 0; i < share_entries; i++, info2++) {
529 if (strequal(tcon->share_name, info2->name)) {
530 info2->current_users++;
538 /****************************************************************************
539 Count the entries belonging to all services in the connection db.
540 ****************************************************************************/
542 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
545 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
547 if (!NT_STATUS_IS_OK(status)) {
548 DEBUG(0,("count_connections_for_all_shares: traverse of "
549 "smbXsrv_tcon_global.tdb failed - %s\n",
554 /*******************************************************************
555 Fill in a share info structure.
556 ********************************************************************/
558 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
559 struct srvsvc_NetShareInfoCtr *info_ctr,
560 uint32_t *resume_handle_p,
561 uint32_t *total_entries,
564 uint32_t num_entries = 0;
565 uint32_t alloc_entries = 0;
566 int num_services = 0;
568 TALLOC_CTX *ctx = p->mem_ctx;
570 uint32_t valid_share_count = 0;
572 union srvsvc_NetShareCtr ctr;
573 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
575 DEBUG(5,("init_srv_share_info_ctr\n"));
577 /* Ensure all the usershares are loaded. */
579 delete_and_reload_printers();
580 load_usershare_shares(NULL, connections_snum_used);
581 load_registry_shares();
582 num_services = lp_numservices();
585 allowed = talloc_zero_array(ctx, bool, num_services);
586 W_ERROR_HAVE_NO_MEMORY(allowed);
588 /* Count the number of entries. */
589 for (snum = 0; snum < num_services; snum++) {
590 if (lp_browseable(snum) && lp_snum_ok(snum) &&
591 is_enumeration_allowed(p, snum) &&
592 (all_shares || !is_hidden_share(snum)) ) {
593 DEBUG(10, ("counting service %s\n",
594 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
595 allowed[snum] = true;
598 DEBUG(10, ("NOT counting service %s\n",
599 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
603 if (!num_entries || (resume_handle >= num_entries)) {
607 /* Calculate alloc entries. */
608 alloc_entries = num_entries - resume_handle;
609 switch (info_ctr->level) {
611 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
612 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
614 ctr.ctr0->count = alloc_entries;
615 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
616 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
618 for (snum = 0; snum < num_services; snum++) {
620 (resume_handle <= (i + valid_share_count++)) ) {
621 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
628 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
629 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
631 ctr.ctr1->count = alloc_entries;
632 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
633 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
635 for (snum = 0; snum < num_services; snum++) {
637 (resume_handle <= (i + valid_share_count++)) ) {
638 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
645 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
646 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
648 ctr.ctr2->count = alloc_entries;
649 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
650 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
652 for (snum = 0; snum < num_services; snum++) {
654 (resume_handle <= (i + valid_share_count++)) ) {
655 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
659 count_connections_for_all_shares(&ctr);
663 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
664 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
666 ctr.ctr501->count = alloc_entries;
667 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
668 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
670 for (snum = 0; snum < num_services; snum++) {
672 (resume_handle <= (i + valid_share_count++)) ) {
673 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
680 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
681 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
683 ctr.ctr502->count = alloc_entries;
684 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
685 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
687 for (snum = 0; snum < num_services; snum++) {
689 (resume_handle <= (i + valid_share_count++)) ) {
690 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
697 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
698 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
700 ctr.ctr1004->count = alloc_entries;
701 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
702 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
704 for (snum = 0; snum < num_services; snum++) {
706 (resume_handle <= (i + valid_share_count++)) ) {
707 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
714 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
715 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
717 ctr.ctr1005->count = alloc_entries;
718 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
719 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
721 for (snum = 0; snum < num_services; snum++) {
723 (resume_handle <= (i + valid_share_count++)) ) {
724 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
731 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
732 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
734 ctr.ctr1006->count = alloc_entries;
735 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
736 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
738 for (snum = 0; snum < num_services; snum++) {
740 (resume_handle <= (i + valid_share_count++)) ) {
741 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
748 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
749 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
751 ctr.ctr1007->count = alloc_entries;
752 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
753 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
755 for (snum = 0; snum < num_services; snum++) {
757 (resume_handle <= (i + valid_share_count++)) ) {
758 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
765 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
766 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
768 ctr.ctr1501->count = alloc_entries;
769 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
770 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
772 for (snum = 0; snum < num_services; snum++) {
774 (resume_handle <= (i + valid_share_count++)) ) {
775 struct sec_desc_buf *sd_buf = NULL;
776 init_srv_share_info_1501(p, &sd_buf, snum);
777 ctr.ctr1501->array[i++] = *sd_buf;
784 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
786 return WERR_INVALID_LEVEL;
789 *total_entries = alloc_entries;
790 if (resume_handle_p) {
792 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
794 *resume_handle_p = num_entries;
803 /*******************************************************************
804 fill in a sess info level 0 structure.
805 ********************************************************************/
807 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
808 struct srvsvc_NetSessCtr0 *ctr0,
809 uint32_t *resume_handle_p,
810 uint32_t *total_entries)
812 struct sessionid *session_list;
813 uint32_t num_entries = 0;
814 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
815 *total_entries = list_sessions(p->mem_ctx, &session_list);
817 DEBUG(5,("init_srv_sess_info_0\n"));
820 if (resume_handle_p) {
821 *resume_handle_p = 0;
826 for (; resume_handle < *total_entries; resume_handle++) {
828 ctr0->array = talloc_realloc(p->mem_ctx,
830 struct srvsvc_NetSessInfo0,
832 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
834 ctr0->array[num_entries].client =
835 session_list[resume_handle].remote_machine;
840 ctr0->count = num_entries;
842 if (resume_handle_p) {
843 if (*resume_handle_p >= *total_entries) {
844 *resume_handle_p = 0;
846 *resume_handle_p = resume_handle;
853 /***********************************************************************
854 * find out the session on which this file is open and bump up its count
855 **********************************************************************/
857 static int count_sess_files_fn(struct file_id fid,
858 const struct share_mode_data *d,
859 const struct share_mode_entry *e,
862 struct sess_file_info *info = data;
863 uint32_t rh = info->resume_handle;
866 for (i=0; i < info->num_entries; i++) {
867 /* rh+info->num_entries is safe, as we've
869 *total_entries > resume_handle &&
870 info->num_entries = *total_entries - resume_handle;
871 inside init_srv_sess_info_1() below.
873 struct sessionid *sess = &info->session_list[rh + i];
874 if ((e->uid == sess->uid) &&
875 server_id_equal(&e->pid, &sess->pid)) {
877 info->ctr->array[i].num_open++;
884 /*******************************************************************
885 * count the num of open files on all sessions
886 *******************************************************************/
888 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
889 struct sessionid *session_list,
890 uint32_t resume_handle,
891 uint32_t num_entries)
893 struct sess_file_info s_file_info;
895 s_file_info.ctr = ctr1;
896 s_file_info.session_list = session_list;
897 s_file_info.resume_handle = resume_handle;
898 s_file_info.num_entries = num_entries;
900 share_entry_forall(count_sess_files_fn, &s_file_info);
903 /*******************************************************************
904 fill in a sess info level 1 structure.
905 ********************************************************************/
907 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
908 struct srvsvc_NetSessCtr1 *ctr1,
909 uint32_t *resume_handle_p,
910 uint32_t *total_entries)
912 struct sessionid *session_list;
913 uint32_t num_entries = 0;
914 time_t now = time(NULL);
915 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
920 if (resume_handle_p) {
921 *resume_handle_p = 0;
926 *total_entries = list_sessions(p->mem_ctx, &session_list);
928 if (resume_handle >= *total_entries) {
929 if (resume_handle_p) {
930 *resume_handle_p = 0;
935 /* We know num_entries must be positive, due to
936 the check resume_handle >= *total_entries above. */
938 num_entries = *total_entries - resume_handle;
940 ctr1->array = talloc_zero_array(p->mem_ctx,
941 struct srvsvc_NetSessInfo1,
944 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
946 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
947 uint32_t connect_time;
950 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
951 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
953 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
954 ctr1->array[num_entries].user = session_list[resume_handle].username;
955 ctr1->array[num_entries].num_open = 0;/* computed later */
956 ctr1->array[num_entries].time = connect_time;
957 ctr1->array[num_entries].idle_time = 0;
958 ctr1->array[num_entries].user_flags = guest;
961 ctr1->count = num_entries;
963 /* count open files on all sessions in single tdb traversal */
964 net_count_files_for_all_sess(ctr1, session_list,
965 resume_handle_p ? *resume_handle_p : 0,
968 if (resume_handle_p) {
969 if (*resume_handle_p >= *total_entries) {
970 *resume_handle_p = 0;
972 *resume_handle_p = resume_handle;
979 /*******************************************************************
980 find the share connection on which this open exists.
981 ********************************************************************/
983 static int share_file_fn(struct file_id fid,
984 const struct share_mode_data *d,
985 const struct share_mode_entry *e,
988 struct share_file_stat *sfs = data;
990 uint32_t offset = sfs->total_entries - sfs->resp_entries;
992 if (strequal(d->servicepath, sfs->in_sharepath)) {
993 for (i=0; i < sfs->resp_entries; i++) {
995 &e->pid, &sfs->svrid_arr[offset + i])) {
996 sfs->netconn_arr[i].num_open ++;
1004 /*******************************************************************
1005 count number of open files on given share connections.
1006 ********************************************************************/
1008 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
1009 struct server_id *svrid_arr, char *sharepath,
1010 uint32_t resp_entries, uint32_t total_entries)
1012 struct share_file_stat sfs;
1014 sfs.netconn_arr = arr;
1015 sfs.svrid_arr = svrid_arr;
1016 sfs.in_sharepath = sharepath;
1017 sfs.resp_entries = resp_entries;
1018 sfs.total_entries = total_entries;
1020 share_entry_forall(share_file_fn, &sfs);
1023 /****************************************************************************
1024 process an entry from the connection db.
1025 ****************************************************************************/
1027 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
1030 struct share_conn_stat *scs = data;
1032 if (!process_exists(tcon->server_id)) {
1036 if (strequal(tcon->share_name, scs->sharename)) {
1037 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1040 if (!scs->svrid_arr) {
1044 scs->svrid_arr[scs->count] = tcon->server_id;
1051 /****************************************************************************
1052 Count the connections to a share. Build an array of serverid's owning these
1054 ****************************************************************************/
1056 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1057 struct server_id **arr)
1059 struct share_conn_stat scs;
1063 scs.sharename = sharename;
1064 scs.svrid_arr = NULL;
1067 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1069 if (!NT_STATUS_IS_OK(status)) {
1070 DEBUG(0,("count_share_conns: traverse of "
1071 "smbXsrv_tcon_global.tdb failed - %s\n",
1072 nt_errstr(status)));
1076 *arr = scs.svrid_arr;
1080 /*******************************************************************
1081 fill in a conn info level 0 structure.
1082 ********************************************************************/
1084 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1085 uint32_t *resume_handle_p,
1086 uint32_t *total_entries)
1088 uint32_t num_entries = 0;
1089 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1091 DEBUG(5,("init_srv_conn_info_0\n"));
1094 if (resume_handle_p) {
1095 *resume_handle_p = 0;
1104 for (; resume_handle < *total_entries; resume_handle++) {
1106 ctr0->array = talloc_realloc(talloc_tos(),
1108 struct srvsvc_NetConnInfo0,
1111 return WERR_NOT_ENOUGH_MEMORY;
1114 ctr0->array[num_entries].conn_id = *total_entries;
1116 /* move on to creating next connection */
1120 ctr0->count = num_entries;
1121 *total_entries = num_entries;
1123 if (resume_handle_p) {
1124 if (*resume_handle_p >= *total_entries) {
1125 *resume_handle_p = 0;
1127 *resume_handle_p = resume_handle;
1134 /*******************************************************************
1135 fill in a conn info level 1 structure.
1136 ********************************************************************/
1138 static WERROR init_srv_conn_info_1(const char *name,
1139 struct srvsvc_NetConnCtr1 *ctr1,
1140 uint32_t *resume_handle_p,
1141 uint32_t *total_entries)
1143 const struct loadparm_substitution *lp_sub =
1144 loadparm_s3_global_substitution();
1145 uint32_t num_entries = 0;
1147 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1148 char *share_name = NULL;
1149 struct server_id *svrid_arr = NULL;
1151 DEBUG(5,("init_srv_conn_info_1\n"));
1154 if (resume_handle_p) {
1155 *resume_handle_p = 0;
1160 /* check if this is a server name or a share name */
1161 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1162 (name[1] == '\\')) {
1164 /* 'name' is a server name - this part is unimplemented */
1167 /* 'name' is a share name */
1168 snum = find_service(talloc_tos(), name, &share_name);
1171 return WERR_NOT_ENOUGH_MEMORY;
1175 return WERR_INVALID_NAME;
1179 * count the num of connections to this share. Also,
1180 * build a list of serverid's that own these
1181 * connections. The serverid list is used later to
1182 * identify the share connection on which an open exists.
1185 *total_entries = count_share_conns(talloc_tos(),
1190 if (resume_handle >= *total_entries) {
1191 if (resume_handle_p) {
1192 *resume_handle_p = 0;
1198 * We know num_entries must be positive, due to
1199 * the check resume_handle >= *total_entries above.
1202 num_entries = *total_entries - resume_handle;
1206 ctr1->array = talloc_zero_array(talloc_tos(),
1207 struct srvsvc_NetConnInfo1,
1210 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1212 for (num_entries = 0; resume_handle < *total_entries;
1213 num_entries++, resume_handle++) {
1215 ctr1->array[num_entries].conn_id = *total_entries;
1216 ctr1->array[num_entries].conn_type = 0x3;
1219 * if these are connections to a share, we are going to
1220 * compute the opens on them later. If it's for the server,
1221 * it's unimplemented.
1225 ctr1->array[num_entries].num_open = 1;
1228 ctr1->array[num_entries].num_users = 1;
1229 ctr1->array[num_entries].conn_time = 3;
1230 ctr1->array[num_entries].user = "dummy_user";
1231 ctr1->array[num_entries].share = "IPC$";
1234 /* now compute open files on the share connections */
1239 * the locking tdb, which has the open files information,
1240 * does not store share name or share (service) number, but
1241 * just the share path. So, we can compute open files only
1242 * on the share path. If more than one shares are defined
1243 * on a share path, open files on all of them are included
1246 * To have the correct behavior in case multiple shares
1247 * are defined on the same path, changes to tdb records
1248 * would be required. That would be lot more effort, so
1249 * this seems a good stopgap fix.
1252 count_share_opens(ctr1->array, svrid_arr,
1253 lp_path(talloc_tos(), lp_sub, snum),
1254 num_entries, *total_entries);
1258 ctr1->count = num_entries;
1259 *total_entries = num_entries;
1261 if (resume_handle_p) {
1262 *resume_handle_p = resume_handle;
1268 /*******************************************************************
1270 *******************************************************************/
1272 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1273 struct srvsvc_NetFileEnum *r)
1275 TALLOC_CTX *ctx = NULL;
1276 struct srvsvc_NetFileCtr3 *ctr3;
1277 uint32_t resume_hnd = 0;
1280 switch (r->in.info_ctr->level) {
1284 return WERR_INVALID_LEVEL;
1287 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1288 p->session_info->security_token)) {
1289 DEBUG(1, ("Enumerating files only allowed for "
1290 "administrators\n"));
1291 return WERR_ACCESS_DENIED;
1295 ctr3 = r->in.info_ctr->ctr.ctr3;
1297 werr = WERR_INVALID_PARAMETER;
1301 /* TODO -- Windows enumerates
1303 (c) open directories and files */
1305 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1306 if (!W_ERROR_IS_OK(werr)) {
1310 *r->out.totalentries = ctr3->count;
1311 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1312 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1320 /*******************************************************************
1321 _srvsvc_NetSrvGetInfo
1322 ********************************************************************/
1324 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1325 struct srvsvc_NetSrvGetInfo *r)
1327 WERROR status = WERR_OK;
1329 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1331 if (!pipe_access_check(p)) {
1332 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1333 return WERR_ACCESS_DENIED;
1336 switch (r->in.level) {
1338 /* Technically level 102 should only be available to
1339 Administrators but there isn't anything super-secret
1340 here, as most of it is made up. */
1343 struct srvsvc_NetSrvInfo102 *info102;
1345 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1347 return WERR_NOT_ENOUGH_MEMORY;
1350 info102->platform_id = PLATFORM_ID_NT;
1351 info102->server_name = lp_netbios_name();
1352 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1353 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1354 info102->server_type = lp_default_server_announce();
1355 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1356 MAX_SERVER_STRING_LENGTH);
1357 info102->users = 0xffffffff;
1358 info102->disc = 0xf;
1359 info102->hidden = 0;
1360 info102->announce = 240;
1361 info102->anndelta = 3000;
1362 info102->licenses = 100000;
1363 info102->userpath = "C:\\";
1365 r->out.info->info102 = info102;
1369 struct srvsvc_NetSrvInfo101 *info101;
1371 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1373 return WERR_NOT_ENOUGH_MEMORY;
1376 info101->platform_id = PLATFORM_ID_NT;
1377 info101->server_name = lp_netbios_name();
1378 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1379 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1380 info101->server_type = lp_default_server_announce();
1381 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1382 MAX_SERVER_STRING_LENGTH);
1384 r->out.info->info101 = info101;
1388 struct srvsvc_NetSrvInfo100 *info100;
1390 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1392 return WERR_NOT_ENOUGH_MEMORY;
1395 info100->platform_id = PLATFORM_ID_NT;
1396 info100->server_name = lp_netbios_name();
1398 r->out.info->info100 = info100;
1403 status = WERR_INVALID_LEVEL;
1407 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1412 /*******************************************************************
1413 _srvsvc_NetSrvSetInfo
1414 ********************************************************************/
1416 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1417 struct srvsvc_NetSrvSetInfo *r)
1419 WERROR status = WERR_OK;
1421 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1423 /* Set up the net server set info structure. */
1425 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1430 /*******************************************************************
1432 ********************************************************************/
1434 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1435 struct srvsvc_NetConnEnum *r)
1439 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1441 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1442 p->session_info->security_token)) {
1443 DEBUG(1, ("Enumerating connections only allowed for "
1444 "administrators\n"));
1445 return WERR_ACCESS_DENIED;
1448 switch (r->in.info_ctr->level) {
1450 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1451 r->in.resume_handle,
1452 r->out.totalentries);
1455 werr = init_srv_conn_info_1(r->in.path,
1456 r->in.info_ctr->ctr.ctr1,
1457 r->in.resume_handle,
1458 r->out.totalentries);
1461 return WERR_INVALID_LEVEL;
1464 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1469 /*******************************************************************
1471 ********************************************************************/
1473 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1474 struct srvsvc_NetSessEnum *r)
1478 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1480 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1481 p->session_info->security_token)) {
1482 DEBUG(1, ("Enumerating sessions only allowed for "
1483 "administrators\n"));
1484 return WERR_ACCESS_DENIED;
1487 switch (r->in.info_ctr->level) {
1489 werr = init_srv_sess_info_0(p,
1490 r->in.info_ctr->ctr.ctr0,
1491 r->in.resume_handle,
1492 r->out.totalentries);
1495 werr = init_srv_sess_info_1(p,
1496 r->in.info_ctr->ctr.ctr1,
1497 r->in.resume_handle,
1498 r->out.totalentries);
1501 return WERR_INVALID_LEVEL;
1504 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1509 /*******************************************************************
1511 ********************************************************************/
1513 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1514 struct srvsvc_NetSessDel *r)
1516 struct sessionid *session_list;
1517 int num_sessions, snum;
1518 const char *username;
1519 const char *machine;
1520 bool not_root = False;
1523 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1525 werr = WERR_ACCESS_DENIED;
1527 /* fail out now if you are not root or not a domain admin */
1529 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1530 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1531 DOMAIN_RID_ADMINS))) {
1536 username = r->in.user;
1537 machine = r->in.client;
1539 /* strip leading backslashes if any */
1540 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1544 num_sessions = find_sessions(p->mem_ctx, username, machine,
1547 for (snum = 0; snum < num_sessions; snum++) {
1551 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1556 ntstat = messaging_send(p->msg_ctx,
1557 session_list[snum].pid,
1558 MSG_SHUTDOWN, &data_blob_null);
1560 if (NT_STATUS_IS_OK(ntstat))
1567 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1574 /*******************************************************************
1575 _srvsvc_NetShareEnumAll
1576 ********************************************************************/
1578 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1579 struct srvsvc_NetShareEnumAll *r)
1583 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1585 if (!pipe_access_check(p)) {
1586 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1587 return WERR_ACCESS_DENIED;
1590 /* Create the list of shares for the response. */
1591 werr = init_srv_share_info_ctr(p,
1593 r->in.resume_handle,
1594 r->out.totalentries,
1597 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1602 /*******************************************************************
1603 _srvsvc_NetShareEnum
1604 ********************************************************************/
1606 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1607 struct srvsvc_NetShareEnum *r)
1611 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1613 if (!pipe_access_check(p)) {
1614 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1615 return WERR_ACCESS_DENIED;
1618 /* Create the list of shares for the response. */
1619 werr = init_srv_share_info_ctr(p,
1621 r->in.resume_handle,
1622 r->out.totalentries,
1625 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1630 /*******************************************************************
1631 _srvsvc_NetShareGetInfo
1632 ********************************************************************/
1634 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1635 struct srvsvc_NetShareGetInfo *r)
1637 WERROR status = WERR_OK;
1638 char *share_name = NULL;
1640 union srvsvc_NetShareInfo *info = r->out.info;
1642 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1644 if (!r->in.share_name) {
1645 return WERR_INVALID_NAME;
1648 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1650 return WERR_NOT_ENOUGH_MEMORY;
1653 return WERR_INVALID_NAME;
1656 switch (r->in.level) {
1658 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1659 W_ERROR_HAVE_NO_MEMORY(info->info0);
1660 init_srv_share_info_0(p, info->info0, snum);
1663 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1664 W_ERROR_HAVE_NO_MEMORY(info->info1);
1665 init_srv_share_info_1(p, info->info1, snum);
1668 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1669 W_ERROR_HAVE_NO_MEMORY(info->info2);
1670 init_srv_share_info_2(p, info->info2, snum);
1671 info->info2->current_users =
1672 count_current_connections(info->info2->name, false);
1675 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1676 W_ERROR_HAVE_NO_MEMORY(info->info501);
1677 init_srv_share_info_501(p, info->info501, snum);
1680 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1681 W_ERROR_HAVE_NO_MEMORY(info->info502);
1682 init_srv_share_info_502(p, info->info502, snum);
1685 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1686 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1687 init_srv_share_info_1004(p, info->info1004, snum);
1690 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1691 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1692 init_srv_share_info_1005(p, info->info1005, snum);
1695 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1696 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1697 init_srv_share_info_1006(p, info->info1006, snum);
1700 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1701 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1702 init_srv_share_info_1007(p, info->info1007, snum);
1705 init_srv_share_info_1501(p, &info->info1501, snum);
1708 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1710 status = WERR_INVALID_LEVEL;
1714 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1719 /*******************************************************************
1720 _srvsvc_NetShareSetInfo. Modify share details.
1721 ********************************************************************/
1723 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1724 struct srvsvc_NetShareSetInfo *r)
1726 const struct loadparm_substitution *lp_sub =
1727 loadparm_s3_global_substitution();
1728 char *command = NULL;
1729 char *share_name = NULL;
1730 char *comment = NULL;
1731 const char *pathname = NULL;
1736 struct security_descriptor *psd = NULL;
1737 bool is_disk_op = False;
1738 const char *csc_policy = NULL;
1739 bool csc_policy_changed = false;
1740 const char *csc_policies[] = {"manual", "documents", "programs",
1742 uint32_t client_csc_policy;
1743 int max_connections = 0;
1744 TALLOC_CTX *ctx = p->mem_ctx;
1745 union srvsvc_NetShareInfo *info = r->in.info;
1747 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1749 if (!r->in.share_name) {
1750 return WERR_INVALID_NAME;
1753 if (r->out.parm_error) {
1754 *r->out.parm_error = 0;
1757 if ( strequal(r->in.share_name,"IPC$")
1758 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1759 || strequal(r->in.share_name,"global") )
1761 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1762 "modified by a remote user.\n",
1763 r->in.share_name ));
1764 return WERR_ACCESS_DENIED;
1767 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1769 return WERR_NOT_ENOUGH_MEMORY;
1772 /* Does this share exist ? */
1774 return WERR_NERR_NETNAMENOTFOUND;
1776 /* No change to printer shares. */
1777 if (lp_printable(snum))
1778 return WERR_ACCESS_DENIED;
1780 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1782 /* fail out now if you are not root and not a disk op */
1784 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1785 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1786 "SeDiskOperatorPrivilege privilege needed to modify "
1788 (unsigned int)p->session_info->unix_token->uid,
1790 return WERR_ACCESS_DENIED;
1793 max_connections = lp_max_connections(snum);
1794 csc_policy = csc_policies[lp_csc_policy(snum)];
1796 switch (r->in.level) {
1798 pathname = lp_path(ctx, lp_sub, snum);
1799 comment = talloc_strdup(ctx, info->info1->comment);
1800 type = info->info1->type;
1804 comment = talloc_strdup(ctx, info->info2->comment);
1805 pathname = info->info2->path;
1806 type = info->info2->type;
1807 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1808 0 : info->info2->max_users;
1812 /* not supported on set but here for completeness */
1814 comment = talloc_strdup(ctx, info->info501->comment);
1815 type = info->info501->type;
1820 comment = talloc_strdup(ctx, info->info502->comment);
1821 pathname = info->info502->path;
1822 type = info->info502->type;
1823 psd = info->info502->sd_buf.sd;
1824 map_generic_share_sd_bits(psd);
1827 pathname = lp_path(ctx, lp_sub, snum);
1828 comment = talloc_strdup(ctx, info->info1004->comment);
1829 type = STYPE_DISKTREE;
1832 /* XP re-sets the csc policy even if it wasn't changed by the
1833 user, so we must compare it to see if it's what is set in
1834 smb.conf, so that we can contine other ops like setting
1836 client_csc_policy = (info->info1005->dfs_flags &
1837 SHARE_1005_CSC_POLICY_MASK) >>
1838 SHARE_1005_CSC_POLICY_SHIFT;
1840 if (client_csc_policy == lp_csc_policy(snum))
1843 csc_policy = csc_policies[client_csc_policy];
1844 csc_policy_changed = true;
1847 pathname = lp_path(ctx, lp_sub, snum);
1848 comment = lp_comment(ctx, lp_sub, snum);
1849 type = STYPE_DISKTREE;
1853 return WERR_ACCESS_DENIED;
1855 pathname = lp_path(ctx, lp_sub, snum);
1856 comment = lp_comment(ctx, lp_sub, snum);
1857 psd = info->info1501->sd;
1858 map_generic_share_sd_bits(psd);
1859 type = STYPE_DISKTREE;
1862 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1864 return WERR_INVALID_LEVEL;
1867 /* We can only modify disk shares. */
1868 if (type != STYPE_DISKTREE) {
1869 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1872 return WERR_ACCESS_DENIED;
1875 if (comment == NULL) {
1876 return WERR_NOT_ENOUGH_MEMORY;
1879 /* Check if the pathname is valid. */
1880 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1881 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1883 return WERR_BAD_PATHNAME;
1886 /* Ensure share name, pathname and comment don't contain '"' characters. */
1887 string_replace(share_name, '"', ' ');
1888 string_replace(path, '"', ' ');
1889 string_replace(comment, '"', ' ');
1891 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1892 lp_change_share_command(talloc_tos(), lp_sub) ? lp_change_share_command(talloc_tos(), lp_sub) : "NULL" ));
1894 /* Only call modify function if something changed. */
1896 if (strcmp(path, lp_path(talloc_tos(), lp_sub, snum))
1897 || strcmp(comment, lp_comment(talloc_tos(), lp_sub, snum))
1898 || (lp_max_connections(snum) != max_connections)
1899 || csc_policy_changed) {
1901 if (!lp_change_share_command(talloc_tos(), lp_sub) || !*lp_change_share_command(talloc_tos(), lp_sub)) {
1902 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1903 return WERR_ACCESS_DENIED;
1906 command = talloc_asprintf(p->mem_ctx,
1907 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1908 lp_change_share_command(talloc_tos(), lp_sub),
1909 get_dyn_CONFIGFILE(),
1916 return WERR_NOT_ENOUGH_MEMORY;
1919 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1921 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1926 ret = smbrun(command, NULL, NULL);
1928 /* Tell everyone we updated smb.conf. */
1929 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1936 /********* END SeDiskOperatorPrivilege BLOCK *********/
1938 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1941 TALLOC_FREE(command);
1944 return WERR_ACCESS_DENIED;
1946 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1950 /* Replace SD if changed. */
1952 struct security_descriptor *old_sd;
1956 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1958 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1959 status = set_share_security(share_name, psd);
1960 if (!NT_STATUS_IS_OK(status)) {
1961 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1967 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1972 /*******************************************************************
1973 _srvsvc_NetShareAdd.
1974 Call 'add_share_command "sharename" "pathname"
1975 "comment" "max connections = "
1976 ********************************************************************/
1978 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1979 struct srvsvc_NetShareAdd *r)
1981 char *command = NULL;
1982 char *share_name_in = NULL;
1983 char *share_name = NULL;
1984 char *comment = NULL;
1985 char *pathname = NULL;
1990 struct security_descriptor *psd = NULL;
1992 int max_connections = 0;
1994 TALLOC_CTX *ctx = p->mem_ctx;
1995 const struct loadparm_substitution *lp_sub =
1996 loadparm_s3_global_substitution();
1998 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2000 if (r->out.parm_error) {
2001 *r->out.parm_error = 0;
2004 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2006 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2007 return WERR_ACCESS_DENIED;
2009 if (!lp_add_share_command(talloc_tos(), lp_sub) || !*lp_add_share_command(talloc_tos(), lp_sub)) {
2010 DBG_WARNING("_srvsvc_NetShareAdd: No \"add share command\" parameter set in smb.conf.\n");
2011 return WERR_ACCESS_DENIED;
2014 switch (r->in.level) {
2016 /* No path. Not enough info in a level 0 to do anything. */
2017 return WERR_ACCESS_DENIED;
2019 /* Not enough info in a level 1 to do anything. */
2020 return WERR_ACCESS_DENIED;
2022 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
2023 comment = talloc_strdup(ctx, r->in.info->info2->comment);
2024 pathname = talloc_strdup(ctx, r->in.info->info2->path);
2025 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
2026 0 : r->in.info->info2->max_users;
2027 type = r->in.info->info2->type;
2030 /* No path. Not enough info in a level 501 to do anything. */
2031 return WERR_ACCESS_DENIED;
2033 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2034 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2035 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2036 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2037 0 : r->in.info->info502->max_users;
2038 type = r->in.info->info502->type;
2039 psd = r->in.info->info502->sd_buf.sd;
2040 map_generic_share_sd_bits(psd);
2043 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2049 return WERR_ACCESS_DENIED;
2051 /* DFS only level. */
2052 return WERR_ACCESS_DENIED;
2054 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2056 return WERR_INVALID_LEVEL;
2059 /* check for invalid share names */
2061 if (!share_name_in || !validate_net_name(share_name_in,
2062 INVALID_SHARENAME_CHARS,
2063 strlen(share_name_in))) {
2064 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2065 share_name_in ? share_name_in : ""));
2066 return WERR_INVALID_NAME;
2069 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2070 || (lp_enable_asu_support() &&
2071 strequal(share_name_in,"ADMIN$"))) {
2072 return WERR_ACCESS_DENIED;
2075 snum = find_service(ctx, share_name_in, &share_name);
2077 return WERR_NOT_ENOUGH_MEMORY;
2080 /* Share already exists. */
2082 return WERR_FILE_EXISTS;
2085 /* We can only add disk shares. */
2086 if (type != STYPE_DISKTREE) {
2087 return WERR_ACCESS_DENIED;
2090 /* Check if the pathname is valid. */
2091 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2092 return WERR_BAD_PATHNAME;
2095 ret = sys_lstat(path, &st, false);
2096 if (ret == -1 && (errno != EACCES)) {
2098 * If path has any other than permission
2099 * problem, return WERR_FILE_NOT_FOUND (as Windows
2102 return WERR_FILE_NOT_FOUND;
2105 /* Ensure share name, pathname and comment don't contain '"' characters. */
2106 string_replace(share_name_in, '"', ' ');
2107 string_replace(share_name, '"', ' ');
2108 string_replace(path, '"', ' ');
2110 string_replace(comment, '"', ' ');
2113 command = talloc_asprintf(ctx,
2114 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2115 lp_add_share_command(talloc_tos(), lp_sub),
2116 get_dyn_CONFIGFILE(),
2119 comment ? comment : "",
2122 return WERR_NOT_ENOUGH_MEMORY;
2125 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2127 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2132 /* FIXME: use libnetconf here - gd */
2134 ret = smbrun(command, NULL, NULL);
2136 /* Tell everyone we updated smb.conf. */
2137 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
2143 /********* END SeDiskOperatorPrivilege BLOCK *********/
2145 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2148 TALLOC_FREE(command);
2151 return WERR_ACCESS_DENIED;
2155 /* Note we use share_name here, not share_name_in as
2156 we need a canonicalized name for setting security. */
2157 status = set_share_security(share_name, psd);
2158 if (!NT_STATUS_IS_OK(status)) {
2159 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2165 * We don't call reload_services() here, the message will
2166 * cause this to be done before the next packet is read
2167 * from the client. JRA.
2170 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2175 /*******************************************************************
2177 Call "delete share command" with the share name as
2179 ********************************************************************/
2181 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2182 struct srvsvc_NetShareDel *r)
2184 char *command = NULL;
2185 char *share_name = NULL;
2189 TALLOC_CTX *ctx = p->mem_ctx;
2191 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2193 if (!r->in.share_name) {
2194 return WERR_NERR_NETNAMENOTFOUND;
2197 if ( strequal(r->in.share_name,"IPC$")
2198 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2199 || strequal(r->in.share_name,"global") )
2201 return WERR_ACCESS_DENIED;
2204 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2206 return WERR_NOT_ENOUGH_MEMORY;
2210 return WERR_BAD_NET_NAME;
2213 /* No change to printer shares. */
2214 if (lp_printable(snum))
2215 return WERR_ACCESS_DENIED;
2217 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2219 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2220 return WERR_ACCESS_DENIED;
2222 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2223 DBG_WARNING("_srvsvc_NetShareDel: No \"delete share command\" parameter set in smb.conf.\n");
2224 return WERR_ACCESS_DENIED;
2227 command = talloc_asprintf(ctx,
2229 lp_delete_share_command(talloc_tos()),
2230 get_dyn_CONFIGFILE(),
2233 return WERR_NOT_ENOUGH_MEMORY;
2236 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2238 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2243 ret = smbrun(command, NULL, NULL);
2245 /* Tell everyone we updated smb.conf. */
2246 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
2252 /********* END SeDiskOperatorPrivilege BLOCK *********/
2254 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2257 return WERR_ACCESS_DENIED;
2259 /* Delete the SD in the database. */
2260 delete_share_security(share_name);
2262 lp_killservice(snum);
2267 /*******************************************************************
2268 _srvsvc_NetShareDelSticky
2269 ********************************************************************/
2271 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2272 struct srvsvc_NetShareDelSticky *r)
2274 struct srvsvc_NetShareDel q;
2276 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2278 q.in.server_unc = r->in.server_unc;
2279 q.in.share_name = r->in.share_name;
2280 q.in.reserved = r->in.reserved;
2282 return _srvsvc_NetShareDel(p, &q);
2285 /*******************************************************************
2286 _srvsvc_NetRemoteTOD
2287 ********************************************************************/
2289 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2290 struct srvsvc_NetRemoteTOD *r)
2292 struct srvsvc_NetRemoteTODInfo *tod;
2294 time_t unixdate = time(NULL);
2296 /* We do this call first as if we do it *after* the gmtime call
2297 it overwrites the pointed-to values. JRA */
2299 uint32_t zone = get_time_zone(unixdate)/60;
2301 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2303 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2304 return WERR_NOT_ENOUGH_MEMORY;
2308 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2310 t = gmtime(&unixdate);
2313 tod->elapsed = unixdate;
2315 tod->hours = t->tm_hour;
2316 tod->mins = t->tm_min;
2317 tod->secs = t->tm_sec;
2319 tod->timezone = zone;
2320 tod->tinterval = 10000;
2321 tod->day = t->tm_mday;
2322 tod->month = t->tm_mon + 1;
2323 tod->year = 1900+t->tm_year;
2324 tod->weekday = t->tm_wday;
2326 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2331 /***********************************************************************************
2332 _srvsvc_NetGetFileSecurity
2333 Win9x NT tools get security descriptor.
2334 ***********************************************************************************/
2336 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2337 struct srvsvc_NetGetFileSecurity *r)
2339 TALLOC_CTX *frame = talloc_stackframe();
2340 const struct loadparm_substitution *lp_sub =
2341 loadparm_s3_global_substitution();
2342 struct smb_filename *smb_fname = NULL;
2344 char *servicename = NULL;
2348 struct conn_struct_tos *c = NULL;
2349 connection_struct *conn = NULL;
2350 struct sec_desc_buf *sd_buf = NULL;
2351 files_struct *fsp = NULL;
2353 uint32_t ucf_flags = 0;
2358 werr = WERR_NERR_NETNAMENOTFOUND;
2361 snum = find_service(frame, r->in.share, &servicename);
2363 werr = WERR_NOT_ENOUGH_MEMORY;
2367 DEBUG(10, ("Could not find service %s\n", servicename));
2368 werr = WERR_NERR_NETNAMENOTFOUND;
2372 nt_status = create_conn_struct_tos_cwd(global_messaging_context(),
2374 lp_path(frame, lp_sub, snum),
2377 if (!NT_STATUS_IS_OK(nt_status)) {
2378 DEBUG(10, ("create_conn_struct failed: %s\n",
2379 nt_errstr(nt_status)));
2380 werr = ntstatus_to_werror(nt_status);
2385 nt_status = filename_convert(frame,
2392 if (!NT_STATUS_IS_OK(nt_status)) {
2393 werr = ntstatus_to_werror(nt_status);
2397 nt_status = SMB_VFS_CREATE_FILE(
2400 0, /* root_dir_fid */
2401 smb_fname, /* fname */
2402 FILE_READ_ATTRIBUTES, /* access_mask */
2403 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2404 FILE_OPEN, /* create_disposition*/
2405 0, /* create_options */
2406 0, /* file_attributes */
2407 INTERNAL_OPEN_ONLY, /* oplock_request */
2409 0, /* allocation_size */
2410 0, /* private_flags */
2415 NULL, NULL); /* create context */
2417 if (!NT_STATUS_IS_OK(nt_status)) {
2418 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2419 smb_fname_str_dbg(smb_fname)));
2420 werr = ntstatus_to_werror(nt_status);
2424 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2426 werr = WERR_NOT_ENOUGH_MEMORY;
2430 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2433 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2435 if (!NT_STATUS_IS_OK(nt_status)) {
2436 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2437 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2438 werr = ntstatus_to_werror(nt_status);
2439 TALLOC_FREE(sd_buf);
2443 if (sd_buf->sd->dacl) {
2444 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2447 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2449 sd_buf->sd_size = sd_size;
2451 *r->out.sd_buf = sd_buf;
2458 close_file(NULL, fsp, NORMAL_CLOSE);
2465 /***********************************************************************************
2466 _srvsvc_NetSetFileSecurity
2467 Win9x NT tools set security descriptor.
2468 ***********************************************************************************/
2470 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2471 struct srvsvc_NetSetFileSecurity *r)
2473 TALLOC_CTX *frame = talloc_stackframe();
2474 const struct loadparm_substitution *lp_sub =
2475 loadparm_s3_global_substitution();
2476 struct smb_filename *smb_fname = NULL;
2477 char *servicename = NULL;
2478 files_struct *fsp = NULL;
2482 struct conn_struct_tos *c = NULL;
2483 connection_struct *conn = NULL;
2485 struct security_descriptor *psd = NULL;
2486 uint32_t security_info_sent = 0;
2487 uint32_t ucf_flags = 0;
2492 werr = WERR_NERR_NETNAMENOTFOUND;
2496 snum = find_service(frame, r->in.share, &servicename);
2498 werr = WERR_NOT_ENOUGH_MEMORY;
2503 DEBUG(10, ("Could not find service %s\n", servicename));
2504 werr = WERR_NERR_NETNAMENOTFOUND;
2508 nt_status = create_conn_struct_tos_cwd(global_messaging_context(),
2510 lp_path(frame, lp_sub, snum),
2513 if (!NT_STATUS_IS_OK(nt_status)) {
2514 DEBUG(10, ("create_conn_struct failed: %s\n",
2515 nt_errstr(nt_status)));
2516 werr = ntstatus_to_werror(nt_status);
2521 nt_status = filename_convert(frame,
2528 if (!NT_STATUS_IS_OK(nt_status)) {
2529 werr = ntstatus_to_werror(nt_status);
2533 nt_status = SMB_VFS_CREATE_FILE(
2536 0, /* root_dir_fid */
2537 smb_fname, /* fname */
2538 FILE_WRITE_ATTRIBUTES, /* access_mask */
2539 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2540 FILE_OPEN, /* create_disposition*/
2541 0, /* create_options */
2542 0, /* file_attributes */
2543 INTERNAL_OPEN_ONLY, /* oplock_request */
2545 0, /* allocation_size */
2546 0, /* private_flags */
2551 NULL, NULL); /* create context */
2553 if (!NT_STATUS_IS_OK(nt_status)) {
2554 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2555 smb_fname_str_dbg(smb_fname)));
2556 werr = ntstatus_to_werror(nt_status);
2560 psd = r->in.sd_buf->sd;
2561 security_info_sent = r->in.securityinformation;
2563 nt_status = set_sd(fsp, psd, security_info_sent);
2565 if (!NT_STATUS_IS_OK(nt_status) ) {
2566 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2567 "on file %s\n", r->in.share));
2568 werr = WERR_ACCESS_DENIED;
2577 close_file(NULL, fsp, NORMAL_CLOSE);
2584 /***********************************************************************************
2585 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2586 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2587 These disks would the disks listed by this function.
2588 Users could then create shares relative to these disks. Watch out for moving these disks around.
2589 "Nigel Williams" <nigel@veritas.com>.
2590 ***********************************************************************************/
2592 static const char *server_disks[] = {"C:"};
2594 static uint32_t get_server_disk_count(void)
2596 return sizeof(server_disks)/sizeof(server_disks[0]);
2599 static uint32_t init_server_disk_enum(uint32_t *resume)
2601 uint32_t server_disk_count = get_server_disk_count();
2603 /*resume can be an offset into the list for now*/
2605 if(*resume & 0x80000000)
2608 if(*resume > server_disk_count)
2609 *resume = server_disk_count;
2611 return server_disk_count - *resume;
2614 static const char *next_server_disk_enum(uint32_t *resume)
2618 if(init_server_disk_enum(resume) == 0)
2621 disk = server_disks[*resume];
2625 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2630 /********************************************************************
2632 ********************************************************************/
2634 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2635 struct srvsvc_NetDiskEnum *r)
2638 const char *disk_name;
2639 TALLOC_CTX *ctx = p->mem_ctx;
2641 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2645 *r->out.totalentries = init_server_disk_enum(&resume);
2647 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2648 MAX_SERVER_DISK_ENTRIES);
2649 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2651 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2653 r->out.info->count = 0;
2655 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2657 r->out.info->count++;
2659 /*copy disk name into a unicode string*/
2661 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2662 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2665 /* add a terminating null string. Is this there if there is more data to come? */
2667 r->out.info->count++;
2669 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2670 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2672 if (r->out.resume_handle) {
2673 *r->out.resume_handle = resume;
2679 /********************************************************************
2680 _srvsvc_NetNameValidate
2681 ********************************************************************/
2683 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2684 struct srvsvc_NetNameValidate *r)
2686 switch (r->in.name_type) {
2688 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2689 strlen_m(r->in.name)))
2691 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2693 return WERR_INVALID_NAME;
2698 return WERR_INVALID_LEVEL;
2704 /*******************************************************************
2705 ********************************************************************/
2707 struct enum_file_close_state {
2708 struct srvsvc_NetFileClose *r;
2709 struct messaging_context *msg_ctx;
2712 static int enum_file_close_fn(struct file_id id,
2713 const struct share_mode_data *d,
2714 const struct share_mode_entry *e,
2717 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2718 struct enum_file_close_state *state =
2719 (struct enum_file_close_state *)private_data;
2720 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2722 if (fid != state->r->in.fid) {
2723 return 0; /* Not this file. */
2726 if (!process_exists(e->pid) ) {
2730 /* Ok - send the close message. */
2731 DBG_DEBUG("request to close file %s, %s\n", d->servicepath,
2732 share_mode_str(talloc_tos(), 0, &id, e));
2734 share_mode_entry_to_message(msg, &id, e);
2736 state->r->out.result = ntstatus_to_werror(
2737 messaging_send_buf(state->msg_ctx,
2738 e->pid, MSG_SMB_CLOSE_FILE,
2739 (uint8_t *)msg, sizeof(msg)));
2744 /********************************************************************
2745 Close a file given a 32-bit file id.
2746 ********************************************************************/
2748 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2749 struct srvsvc_NetFileClose *r)
2751 struct enum_file_close_state state;
2754 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2756 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2758 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2759 return WERR_ACCESS_DENIED;
2762 /* enum_file_close_fn sends the close message to
2763 * the relevant smbd process. */
2765 r->out.result = WERR_FILE_NOT_FOUND;
2767 state.msg_ctx = p->msg_ctx;
2768 share_entry_forall(enum_file_close_fn, &state);
2769 return r->out.result;
2772 /********************************************************************
2773 ********************************************************************/
2775 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2776 struct srvsvc_NetCharDevEnum *r)
2778 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2779 return WERR_NOT_SUPPORTED;
2782 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2783 struct srvsvc_NetCharDevGetInfo *r)
2785 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2786 return WERR_NOT_SUPPORTED;
2789 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2790 struct srvsvc_NetCharDevControl *r)
2792 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2793 return WERR_NOT_SUPPORTED;
2796 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2797 struct srvsvc_NetCharDevQEnum *r)
2799 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2800 return WERR_NOT_SUPPORTED;
2803 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2804 struct srvsvc_NetCharDevQGetInfo *r)
2806 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2807 return WERR_NOT_SUPPORTED;
2810 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2811 struct srvsvc_NetCharDevQSetInfo *r)
2813 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2814 return WERR_NOT_SUPPORTED;
2817 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2818 struct srvsvc_NetCharDevQPurge *r)
2820 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2821 return WERR_NOT_SUPPORTED;
2824 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2825 struct srvsvc_NetCharDevQPurgeSelf *r)
2827 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2828 return WERR_NOT_SUPPORTED;
2831 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2832 struct srvsvc_NetFileGetInfo *r)
2834 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2835 return WERR_NOT_SUPPORTED;
2838 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2839 struct srvsvc_NetShareCheck *r)
2841 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2842 return WERR_NOT_SUPPORTED;
2845 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2846 struct srvsvc_NetServerStatisticsGet *r)
2848 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2849 return WERR_NOT_SUPPORTED;
2852 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2853 struct srvsvc_NetTransportAdd *r)
2855 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2856 return WERR_NOT_SUPPORTED;
2859 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2860 struct srvsvc_NetTransportEnum *r)
2862 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2863 return WERR_NOT_SUPPORTED;
2866 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2867 struct srvsvc_NetTransportDel *r)
2869 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2870 return WERR_NOT_SUPPORTED;
2873 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2874 struct srvsvc_NetSetServiceBits *r)
2876 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2877 return WERR_NOT_SUPPORTED;
2880 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2881 struct srvsvc_NetPathType *r)
2883 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2884 return WERR_NOT_SUPPORTED;
2887 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2888 struct srvsvc_NetPathCanonicalize *r)
2890 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2891 return WERR_NOT_SUPPORTED;
2894 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2895 struct srvsvc_NetPathCompare *r)
2897 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2898 return WERR_NOT_SUPPORTED;
2901 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2902 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2904 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2905 return WERR_NOT_SUPPORTED;
2908 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2909 struct srvsvc_NetPRNameCompare *r)
2911 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2912 return WERR_NOT_SUPPORTED;
2915 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2916 struct srvsvc_NetShareDelStart *r)
2918 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2919 return WERR_NOT_SUPPORTED;
2922 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2923 struct srvsvc_NetShareDelCommit *r)
2925 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2926 return WERR_NOT_SUPPORTED;
2929 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2930 struct srvsvc_NetServerTransportAddEx *r)
2932 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2933 return WERR_NOT_SUPPORTED;
2936 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2937 struct srvsvc_NetServerSetServiceBitsEx *r)
2939 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2940 return WERR_NOT_SUPPORTED;
2943 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2944 struct srvsvc_NETRDFSGETVERSION *r)
2946 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2947 return WERR_NOT_SUPPORTED;
2950 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2951 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2953 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2954 return WERR_NOT_SUPPORTED;
2957 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2958 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2960 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2961 return WERR_NOT_SUPPORTED;
2964 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2965 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2967 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2968 return WERR_NOT_SUPPORTED;
2971 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2972 struct srvsvc_NETRDFSSETSERVERINFO *r)
2974 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2975 return WERR_NOT_SUPPORTED;
2978 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2979 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2981 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2982 return WERR_NOT_SUPPORTED;
2985 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2986 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2988 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2989 return WERR_NOT_SUPPORTED;
2992 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2993 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2995 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2996 return WERR_NOT_SUPPORTED;
2999 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
3000 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
3002 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3003 return WERR_NOT_SUPPORTED;
3006 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3007 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3009 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3010 return WERR_NOT_SUPPORTED;
3013 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3014 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3016 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3017 return WERR_NOT_SUPPORTED;