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"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping;
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count {
54 struct srvsvc_NetFileCtr3 *ctr3;
57 struct sess_file_info {
58 struct srvsvc_NetSessCtr1 *ctr;
59 struct sessionid *session_list;
60 uint32_t resume_handle;
64 struct share_file_stat {
65 struct srvsvc_NetConnInfo1 *netconn_arr;
66 struct server_id *svrid_arr;
67 const char *in_sharepath;
68 uint32_t resp_entries;
69 uint32_t total_entries;
72 struct share_conn_stat {
74 const char *sharename;
75 struct server_id *svrid_arr;
79 /*******************************************************************
80 ********************************************************************/
82 static int enum_file_fn(const struct share_mode_entry *e,
83 const char *sharepath,
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( fname, "." ) == 0 ) {
132 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
134 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s%s",
141 string_replace( fullpath, '/', '\\' );
143 /* mask out create (what ever that is) */
144 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
146 /* now fill in the srvsvc_NetFileInfo3 struct */
148 fenum->ctr3->array[i].fid =
149 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
150 fenum->ctr3->array[i].permissions = permissions;
151 fenum->ctr3->array[i].num_locks = num_locks;
152 fenum->ctr3->array[i].path = fullpath;
153 fenum->ctr3->array[i].user = username;
155 fenum->ctr3->count++;
160 /*******************************************************************
161 ********************************************************************/
163 static WERROR net_enum_files(TALLOC_CTX *ctx,
164 const char *username,
165 struct srvsvc_NetFileCtr3 **ctr3,
168 struct file_enum_count f_enum_cnt;
170 f_enum_cnt.ctx = ctx;
171 f_enum_cnt.username = username;
172 f_enum_cnt.ctr3 = *ctr3;
174 share_entry_forall( enum_file_fn, (void *)&f_enum_cnt );
176 *ctr3 = f_enum_cnt.ctr3;
181 /*******************************************************************
182 Utility function to get the 'type' of a share from an snum.
183 ********************************************************************/
184 static enum srvsvc_ShareType get_share_type(int snum)
186 /* work out the share type */
187 enum srvsvc_ShareType type = STYPE_DISKTREE;
189 if (lp_printable(snum)) {
190 type = lp_administrative_share(snum)
191 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
193 if (strequal(lp_fstype(snum), "IPC")) {
194 type = lp_administrative_share(snum)
195 ? STYPE_IPC_HIDDEN : STYPE_IPC;
200 /*******************************************************************
201 Fill in a share info level 0 structure.
202 ********************************************************************/
204 static void init_srv_share_info_0(struct pipes_struct *p,
205 struct srvsvc_NetShareInfo0 *r, int snum)
207 r->name = lp_servicename(talloc_tos(), snum);
210 /*******************************************************************
211 Fill in a share info level 1 structure.
212 ********************************************************************/
214 static void init_srv_share_info_1(struct pipes_struct *p,
215 struct srvsvc_NetShareInfo1 *r,
218 char *net_name = lp_servicename(talloc_tos(), snum);
219 char *remark = lp_comment(p->mem_ctx, snum);
222 remark = talloc_sub_advanced(
223 p->mem_ctx, lp_servicename(talloc_tos(), snum),
224 get_current_username(), lp_path(talloc_tos(), snum),
225 p->session_info->unix_token->uid, get_current_username(),
230 r->type = get_share_type(snum);
231 r->comment = remark ? remark : "";
234 /*******************************************************************
235 Fill in a share info level 2 structure.
236 ********************************************************************/
238 static void init_srv_share_info_2(struct pipes_struct *p,
239 struct srvsvc_NetShareInfo2 *r,
244 int max_connections = lp_max_connections(snum);
245 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
246 char *net_name = lp_servicename(talloc_tos(), snum);
248 remark = lp_comment(p->mem_ctx, snum);
250 remark = talloc_sub_advanced(
251 p->mem_ctx, lp_servicename(talloc_tos(), snum),
252 get_current_username(), lp_path(talloc_tos(), snum),
253 p->session_info->unix_token->uid, get_current_username(),
256 path = talloc_asprintf(p->mem_ctx,
257 "C:%s", lp_path(talloc_tos(), snum));
261 * Change / to \\ so that win2k will see it as a valid path.
262 * This was added to enable use of browsing in win2k add
266 string_replace(path, '/', '\\');
270 r->type = get_share_type(snum);
271 r->comment = remark ? remark : "";
273 r->max_users = max_uses;
274 r->current_users = 0; /* computed later */
275 r->path = path ? path : "";
279 /*******************************************************************
280 Map any generic bits to file specific bits.
281 ********************************************************************/
283 static void map_generic_share_sd_bits(struct security_descriptor *psd)
286 struct security_acl *ps_dacl = NULL;
295 for (i = 0; i < ps_dacl->num_aces; i++) {
296 struct security_ace *psa = &ps_dacl->aces[i];
297 uint32_t orig_mask = psa->access_mask;
299 se_map_generic(&psa->access_mask, &file_generic_mapping);
300 psa->access_mask |= orig_mask;
304 /*******************************************************************
305 Fill in a share info level 501 structure.
306 ********************************************************************/
308 static void init_srv_share_info_501(struct pipes_struct *p,
309 struct srvsvc_NetShareInfo501 *r, int snum)
311 const char *net_name = lp_servicename(talloc_tos(), snum);
312 char *remark = lp_comment(p->mem_ctx, snum);
315 remark = talloc_sub_advanced(
316 p->mem_ctx, lp_servicename(talloc_tos(), snum),
317 get_current_username(), lp_path(talloc_tos(), snum),
318 p->session_info->unix_token->uid, get_current_username(),
323 r->type = get_share_type(snum);
324 r->comment = remark ? remark : "";
327 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
330 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
333 /*******************************************************************
334 Fill in a share info level 502 structure.
335 ********************************************************************/
337 static void init_srv_share_info_502(struct pipes_struct *p,
338 struct srvsvc_NetShareInfo502 *r, int snum)
340 const char *net_name = lp_servicename(talloc_tos(), snum);
342 struct security_descriptor *sd = NULL;
343 struct sec_desc_buf *sd_buf = NULL;
345 TALLOC_CTX *ctx = p->mem_ctx;
346 char *remark = lp_comment(ctx, snum);
349 remark = talloc_sub_advanced(
350 p->mem_ctx, lp_servicename(talloc_tos(), snum),
351 get_current_username(), lp_path(talloc_tos(), snum),
352 p->session_info->unix_token->uid, get_current_username(),
355 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
358 * Change / to \\ so that win2k will see it as a valid path. This was added to
359 * enable use of browsing in win2k add share dialog.
361 string_replace(path, '/', '\\');
364 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
366 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
369 r->type = get_share_type(snum);
370 r->comment = remark ? remark : "";
372 r->max_users = (uint32_t)-1;
373 r->current_users = 1; /* ??? */
374 r->path = path ? path : "";
379 /***************************************************************************
380 Fill in a share info level 1004 structure.
381 ***************************************************************************/
383 static void init_srv_share_info_1004(struct pipes_struct *p,
384 struct srvsvc_NetShareInfo1004 *r,
387 char *remark = lp_comment(p->mem_ctx, snum);
390 remark = talloc_sub_advanced(
391 p->mem_ctx, lp_servicename(talloc_tos(), snum),
392 get_current_username(), lp_path(talloc_tos(), snum),
393 p->session_info->unix_token->uid, get_current_username(),
397 r->comment = remark ? remark : "";
400 /***************************************************************************
401 Fill in a share info level 1005 structure.
402 ***************************************************************************/
404 static void init_srv_share_info_1005(struct pipes_struct *p,
405 struct srvsvc_NetShareInfo1005 *r,
408 uint32_t dfs_flags = 0;
410 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
411 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
414 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
416 r->dfs_flags = dfs_flags;
419 /***************************************************************************
420 Fill in a share info level 1006 structure.
421 ***************************************************************************/
423 static void init_srv_share_info_1006(struct pipes_struct *p,
424 struct srvsvc_NetShareInfo1006 *r,
427 r->max_users = (uint32_t)-1;
430 /***************************************************************************
431 Fill in a share info level 1007 structure.
432 ***************************************************************************/
434 static void init_srv_share_info_1007(struct pipes_struct *p,
435 struct srvsvc_NetShareInfo1007 *r,
439 r->alternate_directory_name = "";
442 /*******************************************************************
443 Fill in a share info level 1501 structure.
444 ********************************************************************/
446 static void init_srv_share_info_1501(struct pipes_struct *p,
447 struct sec_desc_buf **r,
450 struct security_descriptor *sd;
451 struct sec_desc_buf *sd_buf = NULL;
453 TALLOC_CTX *ctx = p->mem_ctx;
455 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
457 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
463 /*******************************************************************
464 True if it ends in '$'.
465 ********************************************************************/
467 static bool is_hidden_share(int snum)
469 const char *net_name = lp_servicename(talloc_tos(), snum);
471 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
474 /*******************************************************************
475 Verify user is allowed to view share, access based enumeration
476 ********************************************************************/
477 static bool is_enumeration_allowed(struct pipes_struct *p,
480 if (!lp_access_based_share_enum(snum))
483 return share_access_check(p->session_info->security_token,
484 lp_servicename(talloc_tos(), snum),
485 FILE_READ_DATA, NULL);
488 /****************************************************************************
489 Count an entry against the respective service.
490 ****************************************************************************/
492 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
494 union srvsvc_NetShareCtr *ctr = NULL;
495 struct srvsvc_NetShareInfo2 *info2 = NULL;
496 int share_entries = 0;
499 ctr = (union srvsvc_NetShareCtr *) udp;
502 share_entries = ctr->ctr2->count;
503 info2 = &ctr->ctr2->array[0];
505 for (i = 0; i < share_entries; i++, info2++) {
506 if (strequal(tcon->share_name, info2->name)) {
507 info2->current_users++;
515 /****************************************************************************
516 Count the entries belonging to all services in the connection db.
517 ****************************************************************************/
519 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
522 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
524 if (!NT_STATUS_IS_OK(status)) {
525 DEBUG(0,("count_connections_for_all_shares: traverse of "
526 "smbXsrv_tcon_global.tdb failed - %s\n",
531 /*******************************************************************
532 Fill in a share info structure.
533 ********************************************************************/
535 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
536 struct srvsvc_NetShareInfoCtr *info_ctr,
537 uint32_t *resume_handle_p,
538 uint32_t *total_entries,
542 int alloc_entries = 0;
543 int num_services = 0;
545 TALLOC_CTX *ctx = p->mem_ctx;
547 int valid_share_count = 0;
549 union srvsvc_NetShareCtr ctr;
550 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
552 DEBUG(5,("init_srv_share_info_ctr\n"));
554 /* Ensure all the usershares are loaded. */
556 delete_and_reload_printers(server_event_context(), p->msg_ctx);
557 load_usershare_shares(NULL, connections_snum_used);
558 load_registry_shares();
559 num_services = lp_numservices();
562 allowed = talloc_zero_array(ctx, bool, num_services);
563 W_ERROR_HAVE_NO_MEMORY(allowed);
565 /* Count the number of entries. */
566 for (snum = 0; snum < num_services; snum++) {
567 if (lp_browseable(snum) && lp_snum_ok(snum) &&
568 is_enumeration_allowed(p, snum) &&
569 (all_shares || !is_hidden_share(snum)) ) {
570 DEBUG(10, ("counting service %s\n",
571 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
572 allowed[snum] = true;
575 DEBUG(10, ("NOT counting service %s\n",
576 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
580 if (!num_entries || (resume_handle >= num_entries)) {
584 /* Calculate alloc entries. */
585 alloc_entries = num_entries - resume_handle;
586 switch (info_ctr->level) {
588 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
589 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
591 ctr.ctr0->count = alloc_entries;
592 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
593 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
595 for (snum = 0; snum < num_services; snum++) {
597 (resume_handle <= (i + valid_share_count++)) ) {
598 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
605 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
606 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
608 ctr.ctr1->count = alloc_entries;
609 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
610 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
612 for (snum = 0; snum < num_services; snum++) {
614 (resume_handle <= (i + valid_share_count++)) ) {
615 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
622 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
623 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
625 ctr.ctr2->count = alloc_entries;
626 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
627 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
629 for (snum = 0; snum < num_services; snum++) {
631 (resume_handle <= (i + valid_share_count++)) ) {
632 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
636 count_connections_for_all_shares(&ctr);
640 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
641 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
643 ctr.ctr501->count = alloc_entries;
644 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
645 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
647 for (snum = 0; snum < num_services; snum++) {
649 (resume_handle <= (i + valid_share_count++)) ) {
650 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
657 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
658 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
660 ctr.ctr502->count = alloc_entries;
661 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
662 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
664 for (snum = 0; snum < num_services; snum++) {
666 (resume_handle <= (i + valid_share_count++)) ) {
667 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
674 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
675 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
677 ctr.ctr1004->count = alloc_entries;
678 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
679 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
681 for (snum = 0; snum < num_services; snum++) {
683 (resume_handle <= (i + valid_share_count++)) ) {
684 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
691 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
692 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
694 ctr.ctr1005->count = alloc_entries;
695 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
696 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
698 for (snum = 0; snum < num_services; snum++) {
700 (resume_handle <= (i + valid_share_count++)) ) {
701 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
708 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
709 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
711 ctr.ctr1006->count = alloc_entries;
712 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
713 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
715 for (snum = 0; snum < num_services; snum++) {
717 (resume_handle <= (i + valid_share_count++)) ) {
718 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
725 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
726 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
728 ctr.ctr1007->count = alloc_entries;
729 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
730 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
732 for (snum = 0; snum < num_services; snum++) {
734 (resume_handle <= (i + valid_share_count++)) ) {
735 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
742 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
743 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
745 ctr.ctr1501->count = alloc_entries;
746 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
747 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
749 for (snum = 0; snum < num_services; snum++) {
751 (resume_handle <= (i + valid_share_count++)) ) {
752 struct sec_desc_buf *sd_buf = NULL;
753 init_srv_share_info_1501(p, &sd_buf, snum);
754 ctr.ctr1501->array[i++] = *sd_buf;
761 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
763 return WERR_UNKNOWN_LEVEL;
766 *total_entries = alloc_entries;
767 if (resume_handle_p) {
769 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
771 *resume_handle_p = num_entries;
780 /*******************************************************************
781 fill in a sess info level 0 structure.
782 ********************************************************************/
784 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
785 struct srvsvc_NetSessCtr0 *ctr0,
786 uint32_t *resume_handle_p,
787 uint32_t *total_entries)
789 struct sessionid *session_list;
790 uint32_t num_entries = 0;
791 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
792 *total_entries = list_sessions(p->mem_ctx, &session_list);
794 DEBUG(5,("init_srv_sess_info_0\n"));
797 if (resume_handle_p) {
798 *resume_handle_p = 0;
803 for (; resume_handle < *total_entries; resume_handle++) {
805 ctr0->array = talloc_realloc(p->mem_ctx,
807 struct srvsvc_NetSessInfo0,
809 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
811 ctr0->array[num_entries].client =
812 session_list[resume_handle].remote_machine;
817 ctr0->count = num_entries;
819 if (resume_handle_p) {
820 if (*resume_handle_p >= *total_entries) {
821 *resume_handle_p = 0;
823 *resume_handle_p = resume_handle;
830 /***********************************************************************
831 * find out the session on which this file is open and bump up its count
832 **********************************************************************/
834 static int count_sess_files_fn(const struct share_mode_entry *e,
835 const char *sharepath,
840 struct sess_file_info *info = data;
841 uint32_t rh = info->resume_handle;
844 for (i=0; i < info->num_entries; i++) {
845 /* rh+info->num_entries is safe, as we've
847 *total_entries > resume_handle &&
848 info->num_entries = *total_entries - resume_handle;
849 inside init_srv_sess_info_1() below.
851 struct sessionid *sess = &info->session_list[rh + i];
852 if ((e->uid == sess->uid) &&
853 serverid_equal(&e->pid, &sess->pid)) {
855 info->ctr->array[i].num_open++;
862 /*******************************************************************
863 * count the num of open files on all sessions
864 *******************************************************************/
866 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
867 struct sessionid *session_list,
868 uint32_t resume_handle,
869 uint32_t num_entries)
871 struct sess_file_info s_file_info;
873 s_file_info.ctr = ctr1;
874 s_file_info.session_list = session_list;
875 s_file_info.resume_handle = resume_handle;
876 s_file_info.num_entries = num_entries;
878 share_entry_forall(count_sess_files_fn, &s_file_info);
881 /*******************************************************************
882 fill in a sess info level 1 structure.
883 ********************************************************************/
885 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
886 struct srvsvc_NetSessCtr1 *ctr1,
887 uint32_t *resume_handle_p,
888 uint32_t *total_entries)
890 struct sessionid *session_list;
891 uint32_t num_entries = 0;
892 time_t now = time(NULL);
893 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
898 if (resume_handle_p) {
899 *resume_handle_p = 0;
904 *total_entries = list_sessions(p->mem_ctx, &session_list);
906 if (resume_handle >= *total_entries) {
907 if (resume_handle_p) {
908 *resume_handle_p = 0;
913 /* We know num_entries must be positive, due to
914 the check resume_handle >= *total_entries above. */
916 num_entries = *total_entries - resume_handle;
918 ctr1->array = talloc_zero_array(p->mem_ctx,
919 struct srvsvc_NetSessInfo1,
922 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
924 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
925 uint32_t connect_time;
928 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
929 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
931 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
932 ctr1->array[num_entries].user = session_list[resume_handle].username;
933 ctr1->array[num_entries].num_open = 0;/* computed later */
934 ctr1->array[num_entries].time = connect_time;
935 ctr1->array[num_entries].idle_time = 0;
936 ctr1->array[num_entries].user_flags = guest;
939 ctr1->count = num_entries;
941 /* count open files on all sessions in single tdb traversal */
942 net_count_files_for_all_sess(ctr1, session_list,
943 resume_handle_p ? *resume_handle_p : 0,
946 if (resume_handle_p) {
947 if (*resume_handle_p >= *total_entries) {
948 *resume_handle_p = 0;
950 *resume_handle_p = resume_handle;
957 /*******************************************************************
958 find the share connection on which this open exists.
959 ********************************************************************/
961 static int share_file_fn(const struct share_mode_entry *e,
962 const char *sharepath,
967 struct share_file_stat *sfs = data;
969 uint32_t offset = sfs->total_entries - sfs->resp_entries;
971 if (strequal(sharepath, sfs->in_sharepath)) {
972 for (i=0; i < sfs->resp_entries; i++) {
973 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
974 sfs->netconn_arr[i].num_open ++;
982 /*******************************************************************
983 count number of open files on given share connections.
984 ********************************************************************/
986 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
987 struct server_id *svrid_arr, char *sharepath,
988 uint32_t resp_entries, uint32_t total_entries)
990 struct share_file_stat sfs;
992 sfs.netconn_arr = arr;
993 sfs.svrid_arr = svrid_arr;
994 sfs.in_sharepath = sharepath;
995 sfs.resp_entries = resp_entries;
996 sfs.total_entries = total_entries;
998 share_entry_forall(share_file_fn, &sfs);
1001 /****************************************************************************
1002 process an entry from the connection db.
1003 ****************************************************************************/
1005 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
1008 struct share_conn_stat *scs = data;
1010 if (!process_exists(tcon->server_id)) {
1014 if (strequal(tcon->share_name, scs->sharename)) {
1015 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1018 if (!scs->svrid_arr) {
1022 scs->svrid_arr[scs->count] = tcon->server_id;
1029 /****************************************************************************
1030 Count the connections to a share. Build an array of serverid's owning these
1032 ****************************************************************************/
1034 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1035 struct server_id **arr)
1037 struct share_conn_stat scs;
1041 scs.sharename = sharename;
1042 scs.svrid_arr = NULL;
1045 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1047 if (!NT_STATUS_IS_OK(status)) {
1048 DEBUG(0,("count_share_conns: traverse of "
1049 "smbXsrv_tcon_global.tdb failed - %s\n",
1050 nt_errstr(status)));
1054 *arr = scs.svrid_arr;
1058 /*******************************************************************
1059 fill in a conn info level 0 structure.
1060 ********************************************************************/
1062 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1063 uint32_t *resume_handle_p,
1064 uint32_t *total_entries)
1066 uint32_t num_entries = 0;
1067 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1069 DEBUG(5,("init_srv_conn_info_0\n"));
1072 if (resume_handle_p) {
1073 *resume_handle_p = 0;
1082 for (; resume_handle < *total_entries; resume_handle++) {
1084 ctr0->array = talloc_realloc(talloc_tos(),
1086 struct srvsvc_NetConnInfo0,
1092 ctr0->array[num_entries].conn_id = *total_entries;
1094 /* move on to creating next connection */
1098 ctr0->count = num_entries;
1099 *total_entries = num_entries;
1101 if (resume_handle_p) {
1102 if (*resume_handle_p >= *total_entries) {
1103 *resume_handle_p = 0;
1105 *resume_handle_p = resume_handle;
1112 /*******************************************************************
1113 fill in a conn info level 1 structure.
1114 ********************************************************************/
1116 static WERROR init_srv_conn_info_1(const char *name,
1117 struct srvsvc_NetConnCtr1 *ctr1,
1118 uint32_t *resume_handle_p,
1119 uint32_t *total_entries)
1121 uint32_t num_entries = 0, snum = 0;
1122 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1123 char *share_name = NULL;
1124 struct server_id *svrid_arr = NULL;
1126 DEBUG(5,("init_srv_conn_info_1\n"));
1129 if (resume_handle_p) {
1130 *resume_handle_p = 0;
1135 /* check if this is a server name or a share name */
1136 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1137 (name[1] == '\\')) {
1139 /* 'name' is a server name - this part is unimplemented */
1142 /* 'name' is a share name */
1143 snum = find_service(talloc_tos(), name, &share_name);
1150 return WERR_INVALID_NAME;
1154 * count the num of connections to this share. Also,
1155 * build a list of serverid's that own these
1156 * connections. The serverid list is used later to
1157 * identify the share connection on which an open exists.
1160 *total_entries = count_share_conns(talloc_tos(),
1165 if (resume_handle >= *total_entries) {
1166 if (resume_handle_p) {
1167 *resume_handle_p = 0;
1173 * We know num_entries must be positive, due to
1174 * the check resume_handle >= *total_entries above.
1177 num_entries = *total_entries - resume_handle;
1181 ctr1->array = talloc_zero_array(talloc_tos(),
1182 struct srvsvc_NetConnInfo1,
1185 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1187 for (num_entries = 0; resume_handle < *total_entries;
1188 num_entries++, resume_handle++) {
1190 ctr1->array[num_entries].conn_id = *total_entries;
1191 ctr1->array[num_entries].conn_type = 0x3;
1194 * if these are connections to a share, we are going to
1195 * compute the opens on them later. If it's for the server,
1196 * it's unimplemented.
1200 ctr1->array[num_entries].num_open = 1;
1203 ctr1->array[num_entries].num_users = 1;
1204 ctr1->array[num_entries].conn_time = 3;
1205 ctr1->array[num_entries].user = "dummy_user";
1206 ctr1->array[num_entries].share = "IPC$";
1209 /* now compute open files on the share connections */
1214 * the locking tdb, which has the open files information,
1215 * does not store share name or share (service) number, but
1216 * just the share path. So, we can compute open files only
1217 * on the share path. If more than one shares are defined
1218 * on a share path, open files on all of them are included
1221 * To have the correct behavior in case multiple shares
1222 * are defined on the same path, changes to tdb records
1223 * would be required. That would be lot more effort, so
1224 * this seems a good stopgap fix.
1227 count_share_opens(ctr1->array, svrid_arr,
1228 lp_path(talloc_tos(), snum),
1229 num_entries, *total_entries);
1233 ctr1->count = num_entries;
1234 *total_entries = num_entries;
1236 if (resume_handle_p) {
1237 *resume_handle_p = resume_handle;
1243 /*******************************************************************
1245 *******************************************************************/
1247 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1248 struct srvsvc_NetFileEnum *r)
1250 TALLOC_CTX *ctx = NULL;
1251 struct srvsvc_NetFileCtr3 *ctr3;
1252 uint32_t resume_hnd = 0;
1255 switch (r->in.info_ctr->level) {
1259 return WERR_UNKNOWN_LEVEL;
1262 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1263 p->session_info->security_token)) {
1264 DEBUG(1, ("Enumerating files only allowed for "
1265 "administrators\n"));
1266 return WERR_ACCESS_DENIED;
1270 ctr3 = r->in.info_ctr->ctr.ctr3;
1272 werr = WERR_INVALID_PARAM;
1276 /* TODO -- Windows enumerates
1278 (c) open directories and files */
1280 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1281 if (!W_ERROR_IS_OK(werr)) {
1285 *r->out.totalentries = ctr3->count;
1286 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1287 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1295 /*******************************************************************
1296 _srvsvc_NetSrvGetInfo
1297 ********************************************************************/
1299 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1300 struct srvsvc_NetSrvGetInfo *r)
1302 WERROR status = WERR_OK;
1304 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1306 if (!pipe_access_check(p)) {
1307 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1308 return WERR_ACCESS_DENIED;
1311 switch (r->in.level) {
1313 /* Technically level 102 should only be available to
1314 Administrators but there isn't anything super-secret
1315 here, as most of it is made up. */
1318 struct srvsvc_NetSrvInfo102 *info102;
1320 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1325 info102->platform_id = PLATFORM_ID_NT;
1326 info102->server_name = lp_netbios_name();
1327 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1328 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1329 info102->server_type = lp_default_server_announce();
1330 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1331 MAX_SERVER_STRING_LENGTH);
1332 info102->users = 0xffffffff;
1333 info102->disc = 0xf;
1334 info102->hidden = 0;
1335 info102->announce = 240;
1336 info102->anndelta = 3000;
1337 info102->licenses = 100000;
1338 info102->userpath = "C:\\";
1340 r->out.info->info102 = info102;
1344 struct srvsvc_NetSrvInfo101 *info101;
1346 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1351 info101->platform_id = PLATFORM_ID_NT;
1352 info101->server_name = lp_netbios_name();
1353 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1354 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1355 info101->server_type = lp_default_server_announce();
1356 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1357 MAX_SERVER_STRING_LENGTH);
1359 r->out.info->info101 = info101;
1363 struct srvsvc_NetSrvInfo100 *info100;
1365 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1370 info100->platform_id = PLATFORM_ID_NT;
1371 info100->server_name = lp_netbios_name();
1373 r->out.info->info100 = info100;
1378 status = WERR_UNKNOWN_LEVEL;
1382 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1387 /*******************************************************************
1388 _srvsvc_NetSrvSetInfo
1389 ********************************************************************/
1391 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1392 struct srvsvc_NetSrvSetInfo *r)
1394 WERROR status = WERR_OK;
1396 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1398 /* Set up the net server set info structure. */
1400 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1405 /*******************************************************************
1407 ********************************************************************/
1409 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1410 struct srvsvc_NetConnEnum *r)
1414 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1416 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1417 p->session_info->security_token)) {
1418 DEBUG(1, ("Enumerating connections only allowed for "
1419 "administrators\n"));
1420 return WERR_ACCESS_DENIED;
1423 switch (r->in.info_ctr->level) {
1425 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1426 r->in.resume_handle,
1427 r->out.totalentries);
1430 werr = init_srv_conn_info_1(r->in.path,
1431 r->in.info_ctr->ctr.ctr1,
1432 r->in.resume_handle,
1433 r->out.totalentries);
1436 return WERR_UNKNOWN_LEVEL;
1439 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1444 /*******************************************************************
1446 ********************************************************************/
1448 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1449 struct srvsvc_NetSessEnum *r)
1453 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1455 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1456 p->session_info->security_token)) {
1457 DEBUG(1, ("Enumerating sessions only allowed for "
1458 "administrators\n"));
1459 return WERR_ACCESS_DENIED;
1462 switch (r->in.info_ctr->level) {
1464 werr = init_srv_sess_info_0(p,
1465 r->in.info_ctr->ctr.ctr0,
1466 r->in.resume_handle,
1467 r->out.totalentries);
1470 werr = init_srv_sess_info_1(p,
1471 r->in.info_ctr->ctr.ctr1,
1472 r->in.resume_handle,
1473 r->out.totalentries);
1476 return WERR_UNKNOWN_LEVEL;
1479 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1484 /*******************************************************************
1486 ********************************************************************/
1488 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1489 struct srvsvc_NetSessDel *r)
1491 struct sessionid *session_list;
1492 int num_sessions, snum;
1493 const char *username;
1494 const char *machine;
1495 bool not_root = False;
1498 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1500 werr = WERR_ACCESS_DENIED;
1502 /* fail out now if you are not root or not a domain admin */
1504 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1505 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1506 DOMAIN_RID_ADMINS))) {
1511 username = r->in.user;
1512 machine = r->in.client;
1514 /* strip leading backslashes if any */
1515 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1519 num_sessions = find_sessions(p->mem_ctx, username, machine,
1522 for (snum = 0; snum < num_sessions; snum++) {
1526 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1531 ntstat = messaging_send(p->msg_ctx,
1532 session_list[snum].pid,
1533 MSG_SHUTDOWN, &data_blob_null);
1535 if (NT_STATUS_IS_OK(ntstat))
1542 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1549 /*******************************************************************
1550 _srvsvc_NetShareEnumAll
1551 ********************************************************************/
1553 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1554 struct srvsvc_NetShareEnumAll *r)
1558 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1560 if (!pipe_access_check(p)) {
1561 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1562 return WERR_ACCESS_DENIED;
1565 /* Create the list of shares for the response. */
1566 werr = init_srv_share_info_ctr(p,
1568 r->in.resume_handle,
1569 r->out.totalentries,
1572 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1577 /*******************************************************************
1578 _srvsvc_NetShareEnum
1579 ********************************************************************/
1581 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1582 struct srvsvc_NetShareEnum *r)
1586 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1588 if (!pipe_access_check(p)) {
1589 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1590 return WERR_ACCESS_DENIED;
1593 /* Create the list of shares for the response. */
1594 werr = init_srv_share_info_ctr(p,
1596 r->in.resume_handle,
1597 r->out.totalentries,
1600 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1605 /*******************************************************************
1606 _srvsvc_NetShareGetInfo
1607 ********************************************************************/
1609 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1610 struct srvsvc_NetShareGetInfo *r)
1612 WERROR status = WERR_OK;
1613 char *share_name = NULL;
1615 union srvsvc_NetShareInfo *info = r->out.info;
1617 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1619 if (!r->in.share_name) {
1620 return WERR_INVALID_NAME;
1623 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1628 return WERR_INVALID_NAME;
1631 switch (r->in.level) {
1633 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1634 W_ERROR_HAVE_NO_MEMORY(info->info0);
1635 init_srv_share_info_0(p, info->info0, snum);
1638 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1639 W_ERROR_HAVE_NO_MEMORY(info->info1);
1640 init_srv_share_info_1(p, info->info1, snum);
1643 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1644 W_ERROR_HAVE_NO_MEMORY(info->info2);
1645 init_srv_share_info_2(p, info->info2, snum);
1646 info->info2->current_users =
1647 count_current_connections(info->info2->name, false);
1650 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1651 W_ERROR_HAVE_NO_MEMORY(info->info501);
1652 init_srv_share_info_501(p, info->info501, snum);
1655 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1656 W_ERROR_HAVE_NO_MEMORY(info->info502);
1657 init_srv_share_info_502(p, info->info502, snum);
1660 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1661 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1662 init_srv_share_info_1004(p, info->info1004, snum);
1665 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1666 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1667 init_srv_share_info_1005(p, info->info1005, snum);
1670 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1671 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1672 init_srv_share_info_1006(p, info->info1006, snum);
1675 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1676 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1677 init_srv_share_info_1007(p, info->info1007, snum);
1680 init_srv_share_info_1501(p, &info->info1501, snum);
1683 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1685 status = WERR_UNKNOWN_LEVEL;
1689 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1694 /*******************************************************************
1695 _srvsvc_NetShareSetInfo. Modify share details.
1696 ********************************************************************/
1698 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1699 struct srvsvc_NetShareSetInfo *r)
1701 char *command = NULL;
1702 char *share_name = NULL;
1703 char *comment = NULL;
1704 const char *pathname = NULL;
1709 struct security_descriptor *psd = NULL;
1710 bool is_disk_op = False;
1711 const char *csc_policy = NULL;
1712 bool csc_policy_changed = false;
1713 const char *csc_policies[] = {"manual", "documents", "programs",
1715 uint32_t client_csc_policy;
1716 int max_connections = 0;
1717 TALLOC_CTX *ctx = p->mem_ctx;
1718 union srvsvc_NetShareInfo *info = r->in.info;
1720 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1722 if (!r->in.share_name) {
1723 return WERR_INVALID_NAME;
1726 if (r->out.parm_error) {
1727 *r->out.parm_error = 0;
1730 if ( strequal(r->in.share_name,"IPC$")
1731 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1732 || strequal(r->in.share_name,"global") )
1734 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1735 "modified by a remote user.\n",
1736 r->in.share_name ));
1737 return WERR_ACCESS_DENIED;
1740 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1745 /* Does this share exist ? */
1747 return WERR_NET_NAME_NOT_FOUND;
1749 /* No change to printer shares. */
1750 if (lp_printable(snum))
1751 return WERR_ACCESS_DENIED;
1753 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1755 /* fail out now if you are not root and not a disk op */
1757 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1758 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1759 "SeDiskOperatorPrivilege privilege needed to modify "
1761 (unsigned int)p->session_info->unix_token->uid,
1763 return WERR_ACCESS_DENIED;
1766 max_connections = lp_max_connections(snum);
1767 csc_policy = csc_policies[lp_csc_policy(snum)];
1769 switch (r->in.level) {
1771 pathname = lp_path(ctx, snum);
1772 comment = talloc_strdup(ctx, info->info1->comment);
1773 type = info->info1->type;
1777 comment = talloc_strdup(ctx, info->info2->comment);
1778 pathname = info->info2->path;
1779 type = info->info2->type;
1780 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1781 0 : info->info2->max_users;
1785 /* not supported on set but here for completeness */
1787 comment = talloc_strdup(ctx, info->info501->comment);
1788 type = info->info501->type;
1793 comment = talloc_strdup(ctx, info->info502->comment);
1794 pathname = info->info502->path;
1795 type = info->info502->type;
1796 psd = info->info502->sd_buf.sd;
1797 map_generic_share_sd_bits(psd);
1800 pathname = lp_path(ctx, snum);
1801 comment = talloc_strdup(ctx, info->info1004->comment);
1802 type = STYPE_DISKTREE;
1805 /* XP re-sets the csc policy even if it wasn't changed by the
1806 user, so we must compare it to see if it's what is set in
1807 smb.conf, so that we can contine other ops like setting
1809 client_csc_policy = (info->info1005->dfs_flags &
1810 SHARE_1005_CSC_POLICY_MASK) >>
1811 SHARE_1005_CSC_POLICY_SHIFT;
1813 if (client_csc_policy == lp_csc_policy(snum))
1816 csc_policy = csc_policies[client_csc_policy];
1817 csc_policy_changed = true;
1820 pathname = lp_path(ctx, snum);
1821 comment = lp_comment(ctx, snum);
1822 type = STYPE_DISKTREE;
1826 return WERR_ACCESS_DENIED;
1828 pathname = lp_path(ctx, snum);
1829 comment = lp_comment(ctx, snum);
1830 psd = info->info1501->sd;
1831 map_generic_share_sd_bits(psd);
1832 type = STYPE_DISKTREE;
1835 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1837 return WERR_UNKNOWN_LEVEL;
1840 /* We can only modify disk shares. */
1841 if (type != STYPE_DISKTREE) {
1842 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1845 return WERR_ACCESS_DENIED;
1848 if (comment == NULL) {
1852 /* Check if the pathname is valid. */
1853 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1854 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1856 return WERR_OBJECT_PATH_INVALID;
1859 /* Ensure share name, pathname and comment don't contain '"' characters. */
1860 string_replace(share_name, '"', ' ');
1861 string_replace(path, '"', ' ');
1862 string_replace(comment, '"', ' ');
1864 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1865 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1867 /* Only call modify function if something changed. */
1869 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1870 || (lp_max_connections(snum) != max_connections)
1871 || csc_policy_changed) {
1873 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1874 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1875 return WERR_ACCESS_DENIED;
1878 command = talloc_asprintf(p->mem_ctx,
1879 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1880 lp_change_share_command(talloc_tos()),
1881 get_dyn_CONFIGFILE(),
1891 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1893 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1898 if ( (ret = smbrun(command, NULL)) == 0 ) {
1899 /* Tell everyone we updated smb.conf. */
1900 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1907 /********* END SeDiskOperatorPrivilege BLOCK *********/
1909 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1912 TALLOC_FREE(command);
1915 return WERR_ACCESS_DENIED;
1917 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1921 /* Replace SD if changed. */
1923 struct security_descriptor *old_sd;
1926 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1928 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1929 if (!set_share_security(share_name, psd))
1930 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1935 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1940 /*******************************************************************
1941 _srvsvc_NetShareAdd.
1942 Call 'add_share_command "sharename" "pathname"
1943 "comment" "max connections = "
1944 ********************************************************************/
1946 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1947 struct srvsvc_NetShareAdd *r)
1949 char *command = NULL;
1950 char *share_name_in = NULL;
1951 char *share_name = NULL;
1952 char *comment = NULL;
1953 char *pathname = NULL;
1958 struct security_descriptor *psd = NULL;
1960 int max_connections = 0;
1962 TALLOC_CTX *ctx = p->mem_ctx;
1964 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1966 if (r->out.parm_error) {
1967 *r->out.parm_error = 0;
1970 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1972 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1973 return WERR_ACCESS_DENIED;
1975 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1976 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1977 return WERR_ACCESS_DENIED;
1980 switch (r->in.level) {
1982 /* No path. Not enough info in a level 0 to do anything. */
1983 return WERR_ACCESS_DENIED;
1985 /* Not enough info in a level 1 to do anything. */
1986 return WERR_ACCESS_DENIED;
1988 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1989 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1990 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1991 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1992 0 : r->in.info->info2->max_users;
1993 type = r->in.info->info2->type;
1996 /* No path. Not enough info in a level 501 to do anything. */
1997 return WERR_ACCESS_DENIED;
1999 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2000 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2001 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2002 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2003 0 : r->in.info->info502->max_users;
2004 type = r->in.info->info502->type;
2005 psd = r->in.info->info502->sd_buf.sd;
2006 map_generic_share_sd_bits(psd);
2009 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2015 return WERR_ACCESS_DENIED;
2017 /* DFS only level. */
2018 return WERR_ACCESS_DENIED;
2020 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2022 return WERR_UNKNOWN_LEVEL;
2025 /* check for invalid share names */
2027 if (!share_name_in || !validate_net_name(share_name_in,
2028 INVALID_SHARENAME_CHARS,
2029 strlen(share_name_in))) {
2030 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2031 share_name_in ? share_name_in : ""));
2032 return WERR_INVALID_NAME;
2035 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2036 || (lp_enable_asu_support() &&
2037 strequal(share_name_in,"ADMIN$"))) {
2038 return WERR_ACCESS_DENIED;
2041 snum = find_service(ctx, share_name_in, &share_name);
2046 /* Share already exists. */
2048 return WERR_FILE_EXISTS;
2051 /* We can only add disk shares. */
2052 if (type != STYPE_DISKTREE) {
2053 return WERR_ACCESS_DENIED;
2056 /* Check if the pathname is valid. */
2057 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2058 return WERR_OBJECT_PATH_INVALID;
2061 ret = sys_lstat(path, &st, false);
2062 if (ret == -1 && (errno != EACCES)) {
2064 * If path has any other than permission
2065 * problem, return WERR_BADFILE (as Windows
2068 return WERR_BADFILE;
2071 /* Ensure share name, pathname and comment don't contain '"' characters. */
2072 string_replace(share_name_in, '"', ' ');
2073 string_replace(share_name, '"', ' ');
2074 string_replace(path, '"', ' ');
2076 string_replace(comment, '"', ' ');
2079 command = talloc_asprintf(ctx,
2080 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2081 lp_add_share_command(talloc_tos()),
2082 get_dyn_CONFIGFILE(),
2085 comment ? comment : "",
2091 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2093 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2098 /* FIXME: use libnetconf here - gd */
2100 if ( (ret = smbrun(command, NULL)) == 0 ) {
2101 /* Tell everyone we updated smb.conf. */
2102 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2109 /********* END SeDiskOperatorPrivilege BLOCK *********/
2111 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2114 TALLOC_FREE(command);
2117 return WERR_ACCESS_DENIED;
2120 /* Note we use share_name here, not share_name_in as
2121 we need a canonicalized name for setting security. */
2122 if (!set_share_security(share_name, psd)) {
2123 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2129 * We don't call reload_services() here, the message will
2130 * cause this to be done before the next packet is read
2131 * from the client. JRA.
2134 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2139 /*******************************************************************
2141 Call "delete share command" with the share name as
2143 ********************************************************************/
2145 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2146 struct srvsvc_NetShareDel *r)
2148 char *command = NULL;
2149 char *share_name = NULL;
2153 TALLOC_CTX *ctx = p->mem_ctx;
2155 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2157 if (!r->in.share_name) {
2158 return WERR_NET_NAME_NOT_FOUND;
2161 if ( strequal(r->in.share_name,"IPC$")
2162 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2163 || strequal(r->in.share_name,"global") )
2165 return WERR_ACCESS_DENIED;
2168 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2174 return WERR_NO_SUCH_SHARE;
2177 /* No change to printer shares. */
2178 if (lp_printable(snum))
2179 return WERR_ACCESS_DENIED;
2181 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2183 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2184 return WERR_ACCESS_DENIED;
2186 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2187 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2188 return WERR_ACCESS_DENIED;
2191 command = talloc_asprintf(ctx,
2193 lp_delete_share_command(talloc_tos()),
2194 get_dyn_CONFIGFILE(),
2200 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2202 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2207 if ( (ret = smbrun(command, NULL)) == 0 ) {
2208 /* Tell everyone we updated smb.conf. */
2209 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2216 /********* END SeDiskOperatorPrivilege BLOCK *********/
2218 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2221 return WERR_ACCESS_DENIED;
2223 /* Delete the SD in the database. */
2224 delete_share_security(share_name);
2226 lp_killservice(snum);
2231 /*******************************************************************
2232 _srvsvc_NetShareDelSticky
2233 ********************************************************************/
2235 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2236 struct srvsvc_NetShareDelSticky *r)
2238 struct srvsvc_NetShareDel q;
2240 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2242 q.in.server_unc = r->in.server_unc;
2243 q.in.share_name = r->in.share_name;
2244 q.in.reserved = r->in.reserved;
2246 return _srvsvc_NetShareDel(p, &q);
2249 /*******************************************************************
2250 _srvsvc_NetRemoteTOD
2251 ********************************************************************/
2253 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2254 struct srvsvc_NetRemoteTOD *r)
2256 struct srvsvc_NetRemoteTODInfo *tod;
2258 time_t unixdate = time(NULL);
2260 /* We do this call first as if we do it *after* the gmtime call
2261 it overwrites the pointed-to values. JRA */
2263 uint32_t zone = get_time_zone(unixdate)/60;
2265 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2267 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2272 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2274 t = gmtime(&unixdate);
2277 tod->elapsed = unixdate;
2279 tod->hours = t->tm_hour;
2280 tod->mins = t->tm_min;
2281 tod->secs = t->tm_sec;
2283 tod->timezone = zone;
2284 tod->tinterval = 10000;
2285 tod->day = t->tm_mday;
2286 tod->month = t->tm_mon + 1;
2287 tod->year = 1900+t->tm_year;
2288 tod->weekday = t->tm_wday;
2290 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2295 /***********************************************************************************
2296 _srvsvc_NetGetFileSecurity
2297 Win9x NT tools get security descriptor.
2298 ***********************************************************************************/
2300 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2301 struct srvsvc_NetGetFileSecurity *r)
2303 struct smb_filename *smb_fname = NULL;
2305 char *servicename = NULL;
2309 connection_struct *conn = NULL;
2310 struct sec_desc_buf *sd_buf = NULL;
2311 files_struct *fsp = NULL;
2313 char *oldcwd = NULL;
2318 werr = WERR_NET_NAME_NOT_FOUND;
2321 snum = find_service(talloc_tos(), r->in.share, &servicename);
2327 DEBUG(10, ("Could not find service %s\n", servicename));
2328 werr = WERR_NET_NAME_NOT_FOUND;
2332 nt_status = create_conn_struct_cwd(talloc_tos(),
2333 server_event_context(),
2334 server_messaging_context(),
2336 snum, lp_path(talloc_tos(), snum),
2337 p->session_info, &oldcwd);
2338 if (!NT_STATUS_IS_OK(nt_status)) {
2339 DEBUG(10, ("create_conn_struct failed: %s\n",
2340 nt_errstr(nt_status)));
2341 werr = ntstatus_to_werror(nt_status);
2345 nt_status = filename_convert(talloc_tos(),
2352 if (!NT_STATUS_IS_OK(nt_status)) {
2353 werr = ntstatus_to_werror(nt_status);
2357 nt_status = SMB_VFS_CREATE_FILE(
2360 0, /* root_dir_fid */
2361 smb_fname, /* fname */
2362 FILE_READ_ATTRIBUTES, /* access_mask */
2363 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2364 FILE_OPEN, /* create_disposition*/
2365 0, /* create_options */
2366 0, /* file_attributes */
2367 INTERNAL_OPEN_ONLY, /* oplock_request */
2369 0, /* allocation_size */
2370 0, /* private_flags */
2375 NULL, NULL); /* create context */
2377 if (!NT_STATUS_IS_OK(nt_status)) {
2378 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2379 smb_fname_str_dbg(smb_fname)));
2380 werr = ntstatus_to_werror(nt_status);
2384 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2390 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2393 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2395 if (!NT_STATUS_IS_OK(nt_status)) {
2396 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2397 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2398 werr = ntstatus_to_werror(nt_status);
2399 TALLOC_FREE(sd_buf);
2403 if (sd_buf->sd->dacl) {
2404 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2407 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2409 sd_buf->sd_size = sd_size;
2411 *r->out.sd_buf = sd_buf;
2413 close_file(NULL, fsp, NORMAL_CLOSE);
2414 vfs_ChDir(conn, oldcwd);
2415 SMB_VFS_DISCONNECT(conn);
2423 close_file(NULL, fsp, NORMAL_CLOSE);
2427 vfs_ChDir(conn, oldcwd);
2431 SMB_VFS_DISCONNECT(conn);
2437 TALLOC_FREE(smb_fname);
2442 /***********************************************************************************
2443 _srvsvc_NetSetFileSecurity
2444 Win9x NT tools set security descriptor.
2445 ***********************************************************************************/
2447 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2448 struct srvsvc_NetSetFileSecurity *r)
2450 struct smb_filename *smb_fname = NULL;
2451 char *servicename = NULL;
2452 files_struct *fsp = NULL;
2456 connection_struct *conn = NULL;
2458 char *oldcwd = NULL;
2459 struct security_descriptor *psd = NULL;
2460 uint32_t security_info_sent = 0;
2465 werr = WERR_NET_NAME_NOT_FOUND;
2469 snum = find_service(talloc_tos(), r->in.share, &servicename);
2476 DEBUG(10, ("Could not find service %s\n", servicename));
2477 werr = WERR_NET_NAME_NOT_FOUND;
2481 nt_status = create_conn_struct_cwd(talloc_tos(),
2482 server_event_context(),
2483 server_messaging_context(),
2485 snum, lp_path(talloc_tos(), snum),
2486 p->session_info, &oldcwd);
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(talloc_tos(),
2501 if (!NT_STATUS_IS_OK(nt_status)) {
2502 werr = ntstatus_to_werror(nt_status);
2506 nt_status = SMB_VFS_CREATE_FILE(
2509 0, /* root_dir_fid */
2510 smb_fname, /* fname */
2511 FILE_WRITE_ATTRIBUTES, /* access_mask */
2512 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2513 FILE_OPEN, /* create_disposition*/
2514 0, /* create_options */
2515 0, /* file_attributes */
2516 INTERNAL_OPEN_ONLY, /* oplock_request */
2518 0, /* allocation_size */
2519 0, /* private_flags */
2524 NULL, NULL); /* create context */
2526 if (!NT_STATUS_IS_OK(nt_status)) {
2527 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2528 smb_fname_str_dbg(smb_fname)));
2529 werr = ntstatus_to_werror(nt_status);
2533 psd = r->in.sd_buf->sd;
2534 security_info_sent = r->in.securityinformation;
2536 nt_status = set_sd(fsp, psd, security_info_sent);
2538 if (!NT_STATUS_IS_OK(nt_status) ) {
2539 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2540 "on file %s\n", r->in.share));
2541 werr = WERR_ACCESS_DENIED;
2545 close_file(NULL, fsp, NORMAL_CLOSE);
2546 vfs_ChDir(conn, oldcwd);
2547 SMB_VFS_DISCONNECT(conn);
2555 close_file(NULL, fsp, NORMAL_CLOSE);
2559 vfs_ChDir(conn, oldcwd);
2563 SMB_VFS_DISCONNECT(conn);
2568 TALLOC_FREE(smb_fname);
2573 /***********************************************************************************
2574 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2575 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2576 These disks would the disks listed by this function.
2577 Users could then create shares relative to these disks. Watch out for moving these disks around.
2578 "Nigel Williams" <nigel@veritas.com>.
2579 ***********************************************************************************/
2581 static const char *server_disks[] = {"C:"};
2583 static uint32_t get_server_disk_count(void)
2585 return sizeof(server_disks)/sizeof(server_disks[0]);
2588 static uint32_t init_server_disk_enum(uint32_t *resume)
2590 uint32_t server_disk_count = get_server_disk_count();
2592 /*resume can be an offset into the list for now*/
2594 if(*resume & 0x80000000)
2597 if(*resume > server_disk_count)
2598 *resume = server_disk_count;
2600 return server_disk_count - *resume;
2603 static const char *next_server_disk_enum(uint32_t *resume)
2607 if(init_server_disk_enum(resume) == 0)
2610 disk = server_disks[*resume];
2614 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2619 /********************************************************************
2621 ********************************************************************/
2623 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2624 struct srvsvc_NetDiskEnum *r)
2627 const char *disk_name;
2628 TALLOC_CTX *ctx = p->mem_ctx;
2630 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2634 *r->out.totalentries = init_server_disk_enum(&resume);
2636 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2637 MAX_SERVER_DISK_ENTRIES);
2638 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2640 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2642 r->out.info->count = 0;
2644 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2646 r->out.info->count++;
2648 /*copy disk name into a unicode string*/
2650 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2651 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2654 /* add a terminating null string. Is this there if there is more data to come? */
2656 r->out.info->count++;
2658 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2659 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2661 if (r->out.resume_handle) {
2662 *r->out.resume_handle = resume;
2668 /********************************************************************
2669 _srvsvc_NetNameValidate
2670 ********************************************************************/
2672 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2673 struct srvsvc_NetNameValidate *r)
2675 switch (r->in.name_type) {
2677 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2678 strlen_m(r->in.name)))
2680 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2682 return WERR_INVALID_NAME;
2687 return WERR_UNKNOWN_LEVEL;
2693 /*******************************************************************
2694 ********************************************************************/
2696 struct enum_file_close_state {
2697 struct srvsvc_NetFileClose *r;
2698 struct messaging_context *msg_ctx;
2701 static int enum_file_close_fn(const struct share_mode_entry *e,
2702 const char *sharepath,
2707 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2708 struct enum_file_close_state *state =
2709 (struct enum_file_close_state *)private_data;
2710 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2712 if (fid != state->r->in.fid) {
2713 return 0; /* Not this file. */
2716 if (!process_exists(e->pid) ) {
2720 /* Ok - send the close message. */
2721 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2723 share_mode_str(talloc_tos(), 0, e) ));
2725 share_mode_entry_to_message(msg, e);
2727 state->r->out.result = ntstatus_to_werror(
2728 messaging_send_buf(state->msg_ctx,
2729 e->pid, MSG_SMB_CLOSE_FILE,
2730 (uint8_t *)msg, sizeof(msg)));
2735 /********************************************************************
2736 Close a file given a 32-bit file id.
2737 ********************************************************************/
2739 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2740 struct srvsvc_NetFileClose *r)
2742 struct enum_file_close_state state;
2745 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2747 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2749 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2750 return WERR_ACCESS_DENIED;
2753 /* enum_file_close_fn sends the close message to
2754 * the relevant smbd process. */
2756 r->out.result = WERR_BADFILE;
2758 state.msg_ctx = p->msg_ctx;
2759 share_entry_forall(enum_file_close_fn, &state);
2760 return r->out.result;
2763 /********************************************************************
2764 ********************************************************************/
2766 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2767 struct srvsvc_NetCharDevEnum *r)
2769 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2770 return WERR_NOT_SUPPORTED;
2773 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2774 struct srvsvc_NetCharDevGetInfo *r)
2776 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2777 return WERR_NOT_SUPPORTED;
2780 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2781 struct srvsvc_NetCharDevControl *r)
2783 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2784 return WERR_NOT_SUPPORTED;
2787 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2788 struct srvsvc_NetCharDevQEnum *r)
2790 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2791 return WERR_NOT_SUPPORTED;
2794 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2795 struct srvsvc_NetCharDevQGetInfo *r)
2797 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2798 return WERR_NOT_SUPPORTED;
2801 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2802 struct srvsvc_NetCharDevQSetInfo *r)
2804 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2805 return WERR_NOT_SUPPORTED;
2808 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2809 struct srvsvc_NetCharDevQPurge *r)
2811 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2812 return WERR_NOT_SUPPORTED;
2815 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2816 struct srvsvc_NetCharDevQPurgeSelf *r)
2818 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2819 return WERR_NOT_SUPPORTED;
2822 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2823 struct srvsvc_NetFileGetInfo *r)
2825 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2826 return WERR_NOT_SUPPORTED;
2829 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2830 struct srvsvc_NetShareCheck *r)
2832 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2833 return WERR_NOT_SUPPORTED;
2836 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2837 struct srvsvc_NetServerStatisticsGet *r)
2839 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2840 return WERR_NOT_SUPPORTED;
2843 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2844 struct srvsvc_NetTransportAdd *r)
2846 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2847 return WERR_NOT_SUPPORTED;
2850 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2851 struct srvsvc_NetTransportEnum *r)
2853 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2854 return WERR_NOT_SUPPORTED;
2857 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2858 struct srvsvc_NetTransportDel *r)
2860 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2861 return WERR_NOT_SUPPORTED;
2864 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2865 struct srvsvc_NetSetServiceBits *r)
2867 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2868 return WERR_NOT_SUPPORTED;
2871 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2872 struct srvsvc_NetPathType *r)
2874 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2875 return WERR_NOT_SUPPORTED;
2878 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2879 struct srvsvc_NetPathCanonicalize *r)
2881 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2882 return WERR_NOT_SUPPORTED;
2885 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2886 struct srvsvc_NetPathCompare *r)
2888 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2889 return WERR_NOT_SUPPORTED;
2892 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2893 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2895 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2896 return WERR_NOT_SUPPORTED;
2899 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2900 struct srvsvc_NetPRNameCompare *r)
2902 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2903 return WERR_NOT_SUPPORTED;
2906 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2907 struct srvsvc_NetShareDelStart *r)
2909 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2910 return WERR_NOT_SUPPORTED;
2913 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2914 struct srvsvc_NetShareDelCommit *r)
2916 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2917 return WERR_NOT_SUPPORTED;
2920 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2921 struct srvsvc_NetServerTransportAddEx *r)
2923 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2924 return WERR_NOT_SUPPORTED;
2927 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2928 struct srvsvc_NetServerSetServiceBitsEx *r)
2930 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2931 return WERR_NOT_SUPPORTED;
2934 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2935 struct srvsvc_NETRDFSGETVERSION *r)
2937 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2938 return WERR_NOT_SUPPORTED;
2941 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2942 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2944 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2945 return WERR_NOT_SUPPORTED;
2948 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2949 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2951 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2952 return WERR_NOT_SUPPORTED;
2955 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2956 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2958 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2959 return WERR_NOT_SUPPORTED;
2962 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2963 struct srvsvc_NETRDFSSETSERVERINFO *r)
2965 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2966 return WERR_NOT_SUPPORTED;
2969 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2970 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2972 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2973 return WERR_NOT_SUPPORTED;
2976 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2977 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2979 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2980 return WERR_NOT_SUPPORTED;
2983 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2984 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2986 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2987 return WERR_NOT_SUPPORTED;
2990 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2991 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2993 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2994 return WERR_NOT_SUPPORTED;
2997 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2998 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3000 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3001 return WERR_NOT_SUPPORTED;
3004 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3005 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3007 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3008 return WERR_NOT_SUPPORTED;