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"
41 #include "lib/conn_tdb.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(const struct share_mode_entry *e,
84 const char *sharepath,
89 struct file_enum_count *fenum =
90 (struct file_enum_count *)private_data;
92 struct srvsvc_NetFileInfo3 *f;
93 int i = fenum->ctr3->count;
95 struct byte_range_lock *brl;
97 char *fullpath = NULL;
101 /* If the pid was not found delete the entry from connections.tdb */
103 if ( !process_exists(e->pid) ) {
107 username = uidtoname(e->uid);
109 if ((fenum->username != NULL)
110 && !strequal(username, fenum->username)) {
114 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
115 struct srvsvc_NetFileInfo3, i+1);
117 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
120 fenum->ctr3->array = f;
122 /* need to count the number of locks on a file */
127 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
128 num_locks = brl_num_locks(brl);
132 if ( strcmp( fname, "." ) == 0 ) {
133 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
135 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s%s",
142 string_replace( fullpath, '/', '\\' );
144 /* mask out create (what ever that is) */
145 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
147 /* now fill in the srvsvc_NetFileInfo3 struct */
149 fenum->ctr3->array[i].fid =
150 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
151 fenum->ctr3->array[i].permissions = permissions;
152 fenum->ctr3->array[i].num_locks = num_locks;
153 fenum->ctr3->array[i].path = fullpath;
154 fenum->ctr3->array[i].user = username;
156 fenum->ctr3->count++;
161 /*******************************************************************
162 ********************************************************************/
164 static WERROR net_enum_files(TALLOC_CTX *ctx,
165 const char *username,
166 struct srvsvc_NetFileCtr3 **ctr3,
169 struct file_enum_count f_enum_cnt;
171 f_enum_cnt.ctx = ctx;
172 f_enum_cnt.username = username;
173 f_enum_cnt.ctr3 = *ctr3;
175 share_entry_forall( enum_file_fn, (void *)&f_enum_cnt );
177 *ctr3 = f_enum_cnt.ctr3;
182 /*******************************************************************
183 Utility function to get the 'type' of a share from an snum.
184 ********************************************************************/
185 static enum srvsvc_ShareType get_share_type(int snum)
187 /* work out the share type */
188 enum srvsvc_ShareType type = STYPE_DISKTREE;
190 if (lp_printable(snum)) {
191 type = lp_administrative_share(snum)
192 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
194 if (strequal(lp_fstype(snum), "IPC")) {
195 type = lp_administrative_share(snum)
196 ? STYPE_IPC_HIDDEN : STYPE_IPC;
201 /*******************************************************************
202 Fill in a share info level 0 structure.
203 ********************************************************************/
205 static void init_srv_share_info_0(struct pipes_struct *p,
206 struct srvsvc_NetShareInfo0 *r, int snum)
208 r->name = lp_servicename(talloc_tos(), snum);
211 /*******************************************************************
212 Fill in a share info level 1 structure.
213 ********************************************************************/
215 static void init_srv_share_info_1(struct pipes_struct *p,
216 struct srvsvc_NetShareInfo1 *r,
219 char *net_name = lp_servicename(talloc_tos(), snum);
220 char *remark = lp_comment(p->mem_ctx, snum);
223 remark = talloc_sub_advanced(
224 p->mem_ctx, lp_servicename(talloc_tos(), snum),
225 get_current_username(), lp_path(talloc_tos(), snum),
226 p->session_info->unix_token->uid, get_current_username(),
231 r->type = get_share_type(snum);
232 r->comment = remark ? remark : "";
235 /*******************************************************************
236 Fill in a share info level 2 structure.
237 ********************************************************************/
239 static void init_srv_share_info_2(struct pipes_struct *p,
240 struct srvsvc_NetShareInfo2 *r,
245 int max_connections = lp_max_connections(snum);
246 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
247 char *net_name = lp_servicename(talloc_tos(), snum);
249 remark = lp_comment(p->mem_ctx, snum);
251 remark = talloc_sub_advanced(
252 p->mem_ctx, lp_servicename(talloc_tos(), snum),
253 get_current_username(), lp_path(talloc_tos(), snum),
254 p->session_info->unix_token->uid, get_current_username(),
257 path = talloc_asprintf(p->mem_ctx,
258 "C:%s", lp_path(talloc_tos(), snum));
262 * Change / to \\ so that win2k will see it as a valid path.
263 * This was added to enable use of browsing in win2k add
267 string_replace(path, '/', '\\');
271 r->type = get_share_type(snum);
272 r->comment = remark ? remark : "";
274 r->max_users = max_uses;
275 r->current_users = 0; /* computed later */
276 r->path = path ? path : "";
280 /*******************************************************************
281 Map any generic bits to file specific bits.
282 ********************************************************************/
284 static void map_generic_share_sd_bits(struct security_descriptor *psd)
287 struct security_acl *ps_dacl = NULL;
296 for (i = 0; i < ps_dacl->num_aces; i++) {
297 struct security_ace *psa = &ps_dacl->aces[i];
298 uint32_t orig_mask = psa->access_mask;
300 se_map_generic(&psa->access_mask, &file_generic_mapping);
301 psa->access_mask |= orig_mask;
305 /*******************************************************************
306 Fill in a share info level 501 structure.
307 ********************************************************************/
309 static void init_srv_share_info_501(struct pipes_struct *p,
310 struct srvsvc_NetShareInfo501 *r, int snum)
312 const char *net_name = lp_servicename(talloc_tos(), snum);
313 char *remark = lp_comment(p->mem_ctx, snum);
316 remark = talloc_sub_advanced(
317 p->mem_ctx, lp_servicename(talloc_tos(), snum),
318 get_current_username(), lp_path(talloc_tos(), snum),
319 p->session_info->unix_token->uid, get_current_username(),
324 r->type = get_share_type(snum);
325 r->comment = remark ? remark : "";
328 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
331 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
334 /*******************************************************************
335 Fill in a share info level 502 structure.
336 ********************************************************************/
338 static void init_srv_share_info_502(struct pipes_struct *p,
339 struct srvsvc_NetShareInfo502 *r, int snum)
341 const char *net_name = lp_servicename(talloc_tos(), snum);
343 struct security_descriptor *sd = NULL;
344 struct sec_desc_buf *sd_buf = NULL;
346 TALLOC_CTX *ctx = p->mem_ctx;
347 char *remark = lp_comment(ctx, snum);
350 remark = talloc_sub_advanced(
351 p->mem_ctx, lp_servicename(talloc_tos(), snum),
352 get_current_username(), lp_path(talloc_tos(), snum),
353 p->session_info->unix_token->uid, get_current_username(),
356 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
359 * Change / to \\ so that win2k will see it as a valid path. This was added to
360 * enable use of browsing in win2k add share dialog.
362 string_replace(path, '/', '\\');
365 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
367 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
370 r->type = get_share_type(snum);
371 r->comment = remark ? remark : "";
373 r->max_users = (uint32_t)-1;
374 r->current_users = 1; /* ??? */
375 r->path = path ? path : "";
380 /***************************************************************************
381 Fill in a share info level 1004 structure.
382 ***************************************************************************/
384 static void init_srv_share_info_1004(struct pipes_struct *p,
385 struct srvsvc_NetShareInfo1004 *r,
388 char *remark = lp_comment(p->mem_ctx, snum);
391 remark = talloc_sub_advanced(
392 p->mem_ctx, lp_servicename(talloc_tos(), snum),
393 get_current_username(), lp_path(talloc_tos(), snum),
394 p->session_info->unix_token->uid, get_current_username(),
398 r->comment = remark ? remark : "";
401 /***************************************************************************
402 Fill in a share info level 1005 structure.
403 ***************************************************************************/
405 static void init_srv_share_info_1005(struct pipes_struct *p,
406 struct srvsvc_NetShareInfo1005 *r,
409 uint32_t dfs_flags = 0;
411 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
412 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
415 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
417 r->dfs_flags = dfs_flags;
420 /***************************************************************************
421 Fill in a share info level 1006 structure.
422 ***************************************************************************/
424 static void init_srv_share_info_1006(struct pipes_struct *p,
425 struct srvsvc_NetShareInfo1006 *r,
428 r->max_users = (uint32_t)-1;
431 /***************************************************************************
432 Fill in a share info level 1007 structure.
433 ***************************************************************************/
435 static void init_srv_share_info_1007(struct pipes_struct *p,
436 struct srvsvc_NetShareInfo1007 *r,
440 r->alternate_directory_name = "";
443 /*******************************************************************
444 Fill in a share info level 1501 structure.
445 ********************************************************************/
447 static void init_srv_share_info_1501(struct pipes_struct *p,
448 struct sec_desc_buf **r,
451 struct security_descriptor *sd;
452 struct sec_desc_buf *sd_buf = NULL;
454 TALLOC_CTX *ctx = p->mem_ctx;
456 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
458 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
464 /*******************************************************************
465 True if it ends in '$'.
466 ********************************************************************/
468 static bool is_hidden_share(int snum)
470 const char *net_name = lp_servicename(talloc_tos(), snum);
472 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
475 /*******************************************************************
476 Verify user is allowed to view share, access based enumeration
477 ********************************************************************/
478 static bool is_enumeration_allowed(struct pipes_struct *p,
481 if (!lp_access_based_share_enum(snum)) {
485 if (!user_ok_token(p->session_info->unix_info->unix_name,
486 p->session_info->info->domain_name,
487 p->session_info->security_token, snum)) {
491 return share_access_check(p->session_info->security_token,
492 lp_servicename(talloc_tos(), snum),
493 FILE_READ_DATA, NULL);
496 /****************************************************************************
497 Count an entry against the respective service.
498 ****************************************************************************/
500 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
502 union srvsvc_NetShareCtr *ctr = NULL;
503 struct srvsvc_NetShareInfo2 *info2 = NULL;
504 int share_entries = 0;
507 ctr = (union srvsvc_NetShareCtr *) udp;
510 share_entries = ctr->ctr2->count;
511 info2 = &ctr->ctr2->array[0];
513 for (i = 0; i < share_entries; i++, info2++) {
514 if (strequal(tcon->share_name, info2->name)) {
515 info2->current_users++;
523 /****************************************************************************
524 Count the entries belonging to all services in the connection db.
525 ****************************************************************************/
527 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
530 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
532 if (!NT_STATUS_IS_OK(status)) {
533 DEBUG(0,("count_connections_for_all_shares: traverse of "
534 "smbXsrv_tcon_global.tdb failed - %s\n",
539 /*******************************************************************
540 Fill in a share info structure.
541 ********************************************************************/
543 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
544 struct srvsvc_NetShareInfoCtr *info_ctr,
545 uint32_t *resume_handle_p,
546 uint32_t *total_entries,
550 int alloc_entries = 0;
551 int num_services = 0;
553 TALLOC_CTX *ctx = p->mem_ctx;
555 int valid_share_count = 0;
557 union srvsvc_NetShareCtr ctr;
558 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
560 DEBUG(5,("init_srv_share_info_ctr\n"));
562 /* Ensure all the usershares are loaded. */
564 delete_and_reload_printers(server_event_context(), p->msg_ctx);
565 load_usershare_shares(NULL, connections_snum_used);
566 load_registry_shares();
567 num_services = lp_numservices();
570 allowed = talloc_zero_array(ctx, bool, num_services);
571 W_ERROR_HAVE_NO_MEMORY(allowed);
573 /* Count the number of entries. */
574 for (snum = 0; snum < num_services; snum++) {
575 if (lp_browseable(snum) && lp_snum_ok(snum) &&
576 is_enumeration_allowed(p, snum) &&
577 (all_shares || !is_hidden_share(snum)) ) {
578 DEBUG(10, ("counting service %s\n",
579 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
580 allowed[snum] = true;
583 DEBUG(10, ("NOT counting service %s\n",
584 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
588 if (!num_entries || (resume_handle >= num_entries)) {
592 /* Calculate alloc entries. */
593 alloc_entries = num_entries - resume_handle;
594 switch (info_ctr->level) {
596 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
597 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
599 ctr.ctr0->count = alloc_entries;
600 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
601 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
603 for (snum = 0; snum < num_services; snum++) {
605 (resume_handle <= (i + valid_share_count++)) ) {
606 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
613 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
614 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
616 ctr.ctr1->count = alloc_entries;
617 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
618 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
620 for (snum = 0; snum < num_services; snum++) {
622 (resume_handle <= (i + valid_share_count++)) ) {
623 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
630 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
631 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
633 ctr.ctr2->count = alloc_entries;
634 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
635 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
637 for (snum = 0; snum < num_services; snum++) {
639 (resume_handle <= (i + valid_share_count++)) ) {
640 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
644 count_connections_for_all_shares(&ctr);
648 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
649 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
651 ctr.ctr501->count = alloc_entries;
652 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
653 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
655 for (snum = 0; snum < num_services; snum++) {
657 (resume_handle <= (i + valid_share_count++)) ) {
658 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
665 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
666 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
668 ctr.ctr502->count = alloc_entries;
669 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
670 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
672 for (snum = 0; snum < num_services; snum++) {
674 (resume_handle <= (i + valid_share_count++)) ) {
675 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
682 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
683 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
685 ctr.ctr1004->count = alloc_entries;
686 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
687 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
689 for (snum = 0; snum < num_services; snum++) {
691 (resume_handle <= (i + valid_share_count++)) ) {
692 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
699 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
700 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
702 ctr.ctr1005->count = alloc_entries;
703 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
704 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
706 for (snum = 0; snum < num_services; snum++) {
708 (resume_handle <= (i + valid_share_count++)) ) {
709 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
716 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
717 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
719 ctr.ctr1006->count = alloc_entries;
720 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
721 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
723 for (snum = 0; snum < num_services; snum++) {
725 (resume_handle <= (i + valid_share_count++)) ) {
726 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
733 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
734 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
736 ctr.ctr1007->count = alloc_entries;
737 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
738 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
740 for (snum = 0; snum < num_services; snum++) {
742 (resume_handle <= (i + valid_share_count++)) ) {
743 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
750 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
751 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
753 ctr.ctr1501->count = alloc_entries;
754 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
755 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
757 for (snum = 0; snum < num_services; snum++) {
759 (resume_handle <= (i + valid_share_count++)) ) {
760 struct sec_desc_buf *sd_buf = NULL;
761 init_srv_share_info_1501(p, &sd_buf, snum);
762 ctr.ctr1501->array[i++] = *sd_buf;
769 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
771 return WERR_INVALID_LEVEL;
774 *total_entries = alloc_entries;
775 if (resume_handle_p) {
777 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
779 *resume_handle_p = num_entries;
788 /*******************************************************************
789 fill in a sess info level 0 structure.
790 ********************************************************************/
792 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
793 struct srvsvc_NetSessCtr0 *ctr0,
794 uint32_t *resume_handle_p,
795 uint32_t *total_entries)
797 struct sessionid *session_list;
798 uint32_t num_entries = 0;
799 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
800 *total_entries = list_sessions(p->mem_ctx, &session_list);
802 DEBUG(5,("init_srv_sess_info_0\n"));
805 if (resume_handle_p) {
806 *resume_handle_p = 0;
811 for (; resume_handle < *total_entries; resume_handle++) {
813 ctr0->array = talloc_realloc(p->mem_ctx,
815 struct srvsvc_NetSessInfo0,
817 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
819 ctr0->array[num_entries].client =
820 session_list[resume_handle].remote_machine;
825 ctr0->count = num_entries;
827 if (resume_handle_p) {
828 if (*resume_handle_p >= *total_entries) {
829 *resume_handle_p = 0;
831 *resume_handle_p = resume_handle;
838 /***********************************************************************
839 * find out the session on which this file is open and bump up its count
840 **********************************************************************/
842 static int count_sess_files_fn(const struct share_mode_entry *e,
843 const char *sharepath,
848 struct sess_file_info *info = data;
849 uint32_t rh = info->resume_handle;
852 for (i=0; i < info->num_entries; i++) {
853 /* rh+info->num_entries is safe, as we've
855 *total_entries > resume_handle &&
856 info->num_entries = *total_entries - resume_handle;
857 inside init_srv_sess_info_1() below.
859 struct sessionid *sess = &info->session_list[rh + i];
860 if ((e->uid == sess->uid) &&
861 serverid_equal(&e->pid, &sess->pid)) {
863 info->ctr->array[i].num_open++;
870 /*******************************************************************
871 * count the num of open files on all sessions
872 *******************************************************************/
874 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
875 struct sessionid *session_list,
876 uint32_t resume_handle,
877 uint32_t num_entries)
879 struct sess_file_info s_file_info;
881 s_file_info.ctr = ctr1;
882 s_file_info.session_list = session_list;
883 s_file_info.resume_handle = resume_handle;
884 s_file_info.num_entries = num_entries;
886 share_entry_forall(count_sess_files_fn, &s_file_info);
889 /*******************************************************************
890 fill in a sess info level 1 structure.
891 ********************************************************************/
893 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
894 struct srvsvc_NetSessCtr1 *ctr1,
895 uint32_t *resume_handle_p,
896 uint32_t *total_entries)
898 struct sessionid *session_list;
899 uint32_t num_entries = 0;
900 time_t now = time(NULL);
901 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
906 if (resume_handle_p) {
907 *resume_handle_p = 0;
912 *total_entries = list_sessions(p->mem_ctx, &session_list);
914 if (resume_handle >= *total_entries) {
915 if (resume_handle_p) {
916 *resume_handle_p = 0;
921 /* We know num_entries must be positive, due to
922 the check resume_handle >= *total_entries above. */
924 num_entries = *total_entries - resume_handle;
926 ctr1->array = talloc_zero_array(p->mem_ctx,
927 struct srvsvc_NetSessInfo1,
930 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
932 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
933 uint32_t connect_time;
936 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
937 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
939 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
940 ctr1->array[num_entries].user = session_list[resume_handle].username;
941 ctr1->array[num_entries].num_open = 0;/* computed later */
942 ctr1->array[num_entries].time = connect_time;
943 ctr1->array[num_entries].idle_time = 0;
944 ctr1->array[num_entries].user_flags = guest;
947 ctr1->count = num_entries;
949 /* count open files on all sessions in single tdb traversal */
950 net_count_files_for_all_sess(ctr1, session_list,
951 resume_handle_p ? *resume_handle_p : 0,
954 if (resume_handle_p) {
955 if (*resume_handle_p >= *total_entries) {
956 *resume_handle_p = 0;
958 *resume_handle_p = resume_handle;
965 /*******************************************************************
966 find the share connection on which this open exists.
967 ********************************************************************/
969 static int share_file_fn(const struct share_mode_entry *e,
970 const char *sharepath,
975 struct share_file_stat *sfs = data;
977 uint32_t offset = sfs->total_entries - sfs->resp_entries;
979 if (strequal(sharepath, sfs->in_sharepath)) {
980 for (i=0; i < sfs->resp_entries; i++) {
981 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
982 sfs->netconn_arr[i].num_open ++;
990 /*******************************************************************
991 count number of open files on given share connections.
992 ********************************************************************/
994 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
995 struct server_id *svrid_arr, char *sharepath,
996 uint32_t resp_entries, uint32_t total_entries)
998 struct share_file_stat sfs;
1000 sfs.netconn_arr = arr;
1001 sfs.svrid_arr = svrid_arr;
1002 sfs.in_sharepath = sharepath;
1003 sfs.resp_entries = resp_entries;
1004 sfs.total_entries = total_entries;
1006 share_entry_forall(share_file_fn, &sfs);
1009 /****************************************************************************
1010 process an entry from the connection db.
1011 ****************************************************************************/
1013 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
1016 struct share_conn_stat *scs = data;
1018 if (!process_exists(tcon->server_id)) {
1022 if (strequal(tcon->share_name, scs->sharename)) {
1023 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1026 if (!scs->svrid_arr) {
1030 scs->svrid_arr[scs->count] = tcon->server_id;
1037 /****************************************************************************
1038 Count the connections to a share. Build an array of serverid's owning these
1040 ****************************************************************************/
1042 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1043 struct server_id **arr)
1045 struct share_conn_stat scs;
1049 scs.sharename = sharename;
1050 scs.svrid_arr = NULL;
1053 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1055 if (!NT_STATUS_IS_OK(status)) {
1056 DEBUG(0,("count_share_conns: traverse of "
1057 "smbXsrv_tcon_global.tdb failed - %s\n",
1058 nt_errstr(status)));
1062 *arr = scs.svrid_arr;
1066 /*******************************************************************
1067 fill in a conn info level 0 structure.
1068 ********************************************************************/
1070 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1071 uint32_t *resume_handle_p,
1072 uint32_t *total_entries)
1074 uint32_t num_entries = 0;
1075 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1077 DEBUG(5,("init_srv_conn_info_0\n"));
1080 if (resume_handle_p) {
1081 *resume_handle_p = 0;
1090 for (; resume_handle < *total_entries; resume_handle++) {
1092 ctr0->array = talloc_realloc(talloc_tos(),
1094 struct srvsvc_NetConnInfo0,
1097 return WERR_NOT_ENOUGH_MEMORY;
1100 ctr0->array[num_entries].conn_id = *total_entries;
1102 /* move on to creating next connection */
1106 ctr0->count = num_entries;
1107 *total_entries = num_entries;
1109 if (resume_handle_p) {
1110 if (*resume_handle_p >= *total_entries) {
1111 *resume_handle_p = 0;
1113 *resume_handle_p = resume_handle;
1120 /*******************************************************************
1121 fill in a conn info level 1 structure.
1122 ********************************************************************/
1124 static WERROR init_srv_conn_info_1(const char *name,
1125 struct srvsvc_NetConnCtr1 *ctr1,
1126 uint32_t *resume_handle_p,
1127 uint32_t *total_entries)
1129 uint32_t num_entries = 0;
1131 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1132 char *share_name = NULL;
1133 struct server_id *svrid_arr = NULL;
1135 DEBUG(5,("init_srv_conn_info_1\n"));
1138 if (resume_handle_p) {
1139 *resume_handle_p = 0;
1144 /* check if this is a server name or a share name */
1145 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1146 (name[1] == '\\')) {
1148 /* 'name' is a server name - this part is unimplemented */
1151 /* 'name' is a share name */
1152 snum = find_service(talloc_tos(), name, &share_name);
1155 return WERR_NOT_ENOUGH_MEMORY;
1159 return WERR_INVALID_NAME;
1163 * count the num of connections to this share. Also,
1164 * build a list of serverid's that own these
1165 * connections. The serverid list is used later to
1166 * identify the share connection on which an open exists.
1169 *total_entries = count_share_conns(talloc_tos(),
1174 if (resume_handle >= *total_entries) {
1175 if (resume_handle_p) {
1176 *resume_handle_p = 0;
1182 * We know num_entries must be positive, due to
1183 * the check resume_handle >= *total_entries above.
1186 num_entries = *total_entries - resume_handle;
1190 ctr1->array = talloc_zero_array(talloc_tos(),
1191 struct srvsvc_NetConnInfo1,
1194 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1196 for (num_entries = 0; resume_handle < *total_entries;
1197 num_entries++, resume_handle++) {
1199 ctr1->array[num_entries].conn_id = *total_entries;
1200 ctr1->array[num_entries].conn_type = 0x3;
1203 * if these are connections to a share, we are going to
1204 * compute the opens on them later. If it's for the server,
1205 * it's unimplemented.
1209 ctr1->array[num_entries].num_open = 1;
1212 ctr1->array[num_entries].num_users = 1;
1213 ctr1->array[num_entries].conn_time = 3;
1214 ctr1->array[num_entries].user = "dummy_user";
1215 ctr1->array[num_entries].share = "IPC$";
1218 /* now compute open files on the share connections */
1223 * the locking tdb, which has the open files information,
1224 * does not store share name or share (service) number, but
1225 * just the share path. So, we can compute open files only
1226 * on the share path. If more than one shares are defined
1227 * on a share path, open files on all of them are included
1230 * To have the correct behavior in case multiple shares
1231 * are defined on the same path, changes to tdb records
1232 * would be required. That would be lot more effort, so
1233 * this seems a good stopgap fix.
1236 count_share_opens(ctr1->array, svrid_arr,
1237 lp_path(talloc_tos(), snum),
1238 num_entries, *total_entries);
1242 ctr1->count = num_entries;
1243 *total_entries = num_entries;
1245 if (resume_handle_p) {
1246 *resume_handle_p = resume_handle;
1252 /*******************************************************************
1254 *******************************************************************/
1256 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1257 struct srvsvc_NetFileEnum *r)
1259 TALLOC_CTX *ctx = NULL;
1260 struct srvsvc_NetFileCtr3 *ctr3;
1261 uint32_t resume_hnd = 0;
1264 switch (r->in.info_ctr->level) {
1268 return WERR_INVALID_LEVEL;
1271 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1272 p->session_info->security_token)) {
1273 DEBUG(1, ("Enumerating files only allowed for "
1274 "administrators\n"));
1275 return WERR_ACCESS_DENIED;
1279 ctr3 = r->in.info_ctr->ctr.ctr3;
1281 werr = WERR_INVALID_PARAMETER;
1285 /* TODO -- Windows enumerates
1287 (c) open directories and files */
1289 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1290 if (!W_ERROR_IS_OK(werr)) {
1294 *r->out.totalentries = ctr3->count;
1295 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1296 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1304 /*******************************************************************
1305 _srvsvc_NetSrvGetInfo
1306 ********************************************************************/
1308 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1309 struct srvsvc_NetSrvGetInfo *r)
1311 WERROR status = WERR_OK;
1313 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1315 if (!pipe_access_check(p)) {
1316 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1317 return WERR_ACCESS_DENIED;
1320 switch (r->in.level) {
1322 /* Technically level 102 should only be available to
1323 Administrators but there isn't anything super-secret
1324 here, as most of it is made up. */
1327 struct srvsvc_NetSrvInfo102 *info102;
1329 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1331 return WERR_NOT_ENOUGH_MEMORY;
1334 info102->platform_id = PLATFORM_ID_NT;
1335 info102->server_name = lp_netbios_name();
1336 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1337 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1338 info102->server_type = lp_default_server_announce();
1339 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1340 MAX_SERVER_STRING_LENGTH);
1341 info102->users = 0xffffffff;
1342 info102->disc = 0xf;
1343 info102->hidden = 0;
1344 info102->announce = 240;
1345 info102->anndelta = 3000;
1346 info102->licenses = 100000;
1347 info102->userpath = "C:\\";
1349 r->out.info->info102 = info102;
1353 struct srvsvc_NetSrvInfo101 *info101;
1355 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1357 return WERR_NOT_ENOUGH_MEMORY;
1360 info101->platform_id = PLATFORM_ID_NT;
1361 info101->server_name = lp_netbios_name();
1362 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1363 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1364 info101->server_type = lp_default_server_announce();
1365 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1366 MAX_SERVER_STRING_LENGTH);
1368 r->out.info->info101 = info101;
1372 struct srvsvc_NetSrvInfo100 *info100;
1374 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1376 return WERR_NOT_ENOUGH_MEMORY;
1379 info100->platform_id = PLATFORM_ID_NT;
1380 info100->server_name = lp_netbios_name();
1382 r->out.info->info100 = info100;
1387 status = WERR_INVALID_LEVEL;
1391 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1396 /*******************************************************************
1397 _srvsvc_NetSrvSetInfo
1398 ********************************************************************/
1400 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1401 struct srvsvc_NetSrvSetInfo *r)
1403 WERROR status = WERR_OK;
1405 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1407 /* Set up the net server set info structure. */
1409 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1414 /*******************************************************************
1416 ********************************************************************/
1418 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1419 struct srvsvc_NetConnEnum *r)
1423 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1425 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1426 p->session_info->security_token)) {
1427 DEBUG(1, ("Enumerating connections only allowed for "
1428 "administrators\n"));
1429 return WERR_ACCESS_DENIED;
1432 switch (r->in.info_ctr->level) {
1434 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1435 r->in.resume_handle,
1436 r->out.totalentries);
1439 werr = init_srv_conn_info_1(r->in.path,
1440 r->in.info_ctr->ctr.ctr1,
1441 r->in.resume_handle,
1442 r->out.totalentries);
1445 return WERR_INVALID_LEVEL;
1448 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1453 /*******************************************************************
1455 ********************************************************************/
1457 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1458 struct srvsvc_NetSessEnum *r)
1462 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1464 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1465 p->session_info->security_token)) {
1466 DEBUG(1, ("Enumerating sessions only allowed for "
1467 "administrators\n"));
1468 return WERR_ACCESS_DENIED;
1471 switch (r->in.info_ctr->level) {
1473 werr = init_srv_sess_info_0(p,
1474 r->in.info_ctr->ctr.ctr0,
1475 r->in.resume_handle,
1476 r->out.totalentries);
1479 werr = init_srv_sess_info_1(p,
1480 r->in.info_ctr->ctr.ctr1,
1481 r->in.resume_handle,
1482 r->out.totalentries);
1485 return WERR_INVALID_LEVEL;
1488 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1493 /*******************************************************************
1495 ********************************************************************/
1497 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1498 struct srvsvc_NetSessDel *r)
1500 struct sessionid *session_list;
1501 int num_sessions, snum;
1502 const char *username;
1503 const char *machine;
1504 bool not_root = False;
1507 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1509 werr = WERR_ACCESS_DENIED;
1511 /* fail out now if you are not root or not a domain admin */
1513 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1514 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1515 DOMAIN_RID_ADMINS))) {
1520 username = r->in.user;
1521 machine = r->in.client;
1523 /* strip leading backslashes if any */
1524 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1528 num_sessions = find_sessions(p->mem_ctx, username, machine,
1531 for (snum = 0; snum < num_sessions; snum++) {
1535 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1540 ntstat = messaging_send(p->msg_ctx,
1541 session_list[snum].pid,
1542 MSG_SHUTDOWN, &data_blob_null);
1544 if (NT_STATUS_IS_OK(ntstat))
1551 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1558 /*******************************************************************
1559 _srvsvc_NetShareEnumAll
1560 ********************************************************************/
1562 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1563 struct srvsvc_NetShareEnumAll *r)
1567 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1569 if (!pipe_access_check(p)) {
1570 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1571 return WERR_ACCESS_DENIED;
1574 /* Create the list of shares for the response. */
1575 werr = init_srv_share_info_ctr(p,
1577 r->in.resume_handle,
1578 r->out.totalentries,
1581 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1586 /*******************************************************************
1587 _srvsvc_NetShareEnum
1588 ********************************************************************/
1590 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1591 struct srvsvc_NetShareEnum *r)
1595 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1597 if (!pipe_access_check(p)) {
1598 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1599 return WERR_ACCESS_DENIED;
1602 /* Create the list of shares for the response. */
1603 werr = init_srv_share_info_ctr(p,
1605 r->in.resume_handle,
1606 r->out.totalentries,
1609 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1614 /*******************************************************************
1615 _srvsvc_NetShareGetInfo
1616 ********************************************************************/
1618 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1619 struct srvsvc_NetShareGetInfo *r)
1621 WERROR status = WERR_OK;
1622 char *share_name = NULL;
1624 union srvsvc_NetShareInfo *info = r->out.info;
1626 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1628 if (!r->in.share_name) {
1629 return WERR_INVALID_NAME;
1632 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1634 return WERR_NOT_ENOUGH_MEMORY;
1637 return WERR_INVALID_NAME;
1640 switch (r->in.level) {
1642 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1643 W_ERROR_HAVE_NO_MEMORY(info->info0);
1644 init_srv_share_info_0(p, info->info0, snum);
1647 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1648 W_ERROR_HAVE_NO_MEMORY(info->info1);
1649 init_srv_share_info_1(p, info->info1, snum);
1652 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1653 W_ERROR_HAVE_NO_MEMORY(info->info2);
1654 init_srv_share_info_2(p, info->info2, snum);
1655 info->info2->current_users =
1656 count_current_connections(info->info2->name, false);
1659 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1660 W_ERROR_HAVE_NO_MEMORY(info->info501);
1661 init_srv_share_info_501(p, info->info501, snum);
1664 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1665 W_ERROR_HAVE_NO_MEMORY(info->info502);
1666 init_srv_share_info_502(p, info->info502, snum);
1669 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1670 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1671 init_srv_share_info_1004(p, info->info1004, snum);
1674 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1675 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1676 init_srv_share_info_1005(p, info->info1005, snum);
1679 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1680 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1681 init_srv_share_info_1006(p, info->info1006, snum);
1684 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1685 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1686 init_srv_share_info_1007(p, info->info1007, snum);
1689 init_srv_share_info_1501(p, &info->info1501, snum);
1692 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1694 status = WERR_INVALID_LEVEL;
1698 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1703 /*******************************************************************
1704 _srvsvc_NetShareSetInfo. Modify share details.
1705 ********************************************************************/
1707 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1708 struct srvsvc_NetShareSetInfo *r)
1710 char *command = NULL;
1711 char *share_name = NULL;
1712 char *comment = NULL;
1713 const char *pathname = NULL;
1718 struct security_descriptor *psd = NULL;
1719 bool is_disk_op = False;
1720 const char *csc_policy = NULL;
1721 bool csc_policy_changed = false;
1722 const char *csc_policies[] = {"manual", "documents", "programs",
1724 uint32_t client_csc_policy;
1725 int max_connections = 0;
1726 TALLOC_CTX *ctx = p->mem_ctx;
1727 union srvsvc_NetShareInfo *info = r->in.info;
1729 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1731 if (!r->in.share_name) {
1732 return WERR_INVALID_NAME;
1735 if (r->out.parm_error) {
1736 *r->out.parm_error = 0;
1739 if ( strequal(r->in.share_name,"IPC$")
1740 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1741 || strequal(r->in.share_name,"global") )
1743 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1744 "modified by a remote user.\n",
1745 r->in.share_name ));
1746 return WERR_ACCESS_DENIED;
1749 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1751 return WERR_NOT_ENOUGH_MEMORY;
1754 /* Does this share exist ? */
1756 return WERR_NERR_NETNAMENOTFOUND;
1758 /* No change to printer shares. */
1759 if (lp_printable(snum))
1760 return WERR_ACCESS_DENIED;
1762 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1764 /* fail out now if you are not root and not a disk op */
1766 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1767 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1768 "SeDiskOperatorPrivilege privilege needed to modify "
1770 (unsigned int)p->session_info->unix_token->uid,
1772 return WERR_ACCESS_DENIED;
1775 max_connections = lp_max_connections(snum);
1776 csc_policy = csc_policies[lp_csc_policy(snum)];
1778 switch (r->in.level) {
1780 pathname = lp_path(ctx, snum);
1781 comment = talloc_strdup(ctx, info->info1->comment);
1782 type = info->info1->type;
1786 comment = talloc_strdup(ctx, info->info2->comment);
1787 pathname = info->info2->path;
1788 type = info->info2->type;
1789 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1790 0 : info->info2->max_users;
1794 /* not supported on set but here for completeness */
1796 comment = talloc_strdup(ctx, info->info501->comment);
1797 type = info->info501->type;
1802 comment = talloc_strdup(ctx, info->info502->comment);
1803 pathname = info->info502->path;
1804 type = info->info502->type;
1805 psd = info->info502->sd_buf.sd;
1806 map_generic_share_sd_bits(psd);
1809 pathname = lp_path(ctx, snum);
1810 comment = talloc_strdup(ctx, info->info1004->comment);
1811 type = STYPE_DISKTREE;
1814 /* XP re-sets the csc policy even if it wasn't changed by the
1815 user, so we must compare it to see if it's what is set in
1816 smb.conf, so that we can contine other ops like setting
1818 client_csc_policy = (info->info1005->dfs_flags &
1819 SHARE_1005_CSC_POLICY_MASK) >>
1820 SHARE_1005_CSC_POLICY_SHIFT;
1822 if (client_csc_policy == lp_csc_policy(snum))
1825 csc_policy = csc_policies[client_csc_policy];
1826 csc_policy_changed = true;
1829 pathname = lp_path(ctx, snum);
1830 comment = lp_comment(ctx, snum);
1831 type = STYPE_DISKTREE;
1835 return WERR_ACCESS_DENIED;
1837 pathname = lp_path(ctx, snum);
1838 comment = lp_comment(ctx, snum);
1839 psd = info->info1501->sd;
1840 map_generic_share_sd_bits(psd);
1841 type = STYPE_DISKTREE;
1844 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1846 return WERR_INVALID_LEVEL;
1849 /* We can only modify disk shares. */
1850 if (type != STYPE_DISKTREE) {
1851 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1854 return WERR_ACCESS_DENIED;
1857 if (comment == NULL) {
1858 return WERR_NOT_ENOUGH_MEMORY;
1861 /* Check if the pathname is valid. */
1862 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1863 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1865 return WERR_BAD_PATHNAME;
1868 /* Ensure share name, pathname and comment don't contain '"' characters. */
1869 string_replace(share_name, '"', ' ');
1870 string_replace(path, '"', ' ');
1871 string_replace(comment, '"', ' ');
1873 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1874 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1876 /* Only call modify function if something changed. */
1878 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1879 || (lp_max_connections(snum) != max_connections)
1880 || csc_policy_changed) {
1882 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1883 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1884 return WERR_ACCESS_DENIED;
1887 command = talloc_asprintf(p->mem_ctx,
1888 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1889 lp_change_share_command(talloc_tos()),
1890 get_dyn_CONFIGFILE(),
1897 return WERR_NOT_ENOUGH_MEMORY;
1900 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1902 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1907 ret = smbrun(command, NULL, NULL);
1909 /* Tell everyone we updated smb.conf. */
1910 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1917 /********* END SeDiskOperatorPrivilege BLOCK *********/
1919 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1922 TALLOC_FREE(command);
1925 return WERR_ACCESS_DENIED;
1927 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1931 /* Replace SD if changed. */
1933 struct security_descriptor *old_sd;
1936 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1938 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1939 if (!set_share_security(share_name, psd))
1940 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1945 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1950 /*******************************************************************
1951 _srvsvc_NetShareAdd.
1952 Call 'add_share_command "sharename" "pathname"
1953 "comment" "max connections = "
1954 ********************************************************************/
1956 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1957 struct srvsvc_NetShareAdd *r)
1959 char *command = NULL;
1960 char *share_name_in = NULL;
1961 char *share_name = NULL;
1962 char *comment = NULL;
1963 char *pathname = NULL;
1968 struct security_descriptor *psd = NULL;
1970 int max_connections = 0;
1972 TALLOC_CTX *ctx = p->mem_ctx;
1974 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1976 if (r->out.parm_error) {
1977 *r->out.parm_error = 0;
1980 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1982 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1983 return WERR_ACCESS_DENIED;
1985 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1986 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1987 return WERR_ACCESS_DENIED;
1990 switch (r->in.level) {
1992 /* No path. Not enough info in a level 0 to do anything. */
1993 return WERR_ACCESS_DENIED;
1995 /* Not enough info in a level 1 to do anything. */
1996 return WERR_ACCESS_DENIED;
1998 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1999 comment = talloc_strdup(ctx, r->in.info->info2->comment);
2000 pathname = talloc_strdup(ctx, r->in.info->info2->path);
2001 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
2002 0 : r->in.info->info2->max_users;
2003 type = r->in.info->info2->type;
2006 /* No path. Not enough info in a level 501 to do anything. */
2007 return WERR_ACCESS_DENIED;
2009 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2010 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2011 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2012 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2013 0 : r->in.info->info502->max_users;
2014 type = r->in.info->info502->type;
2015 psd = r->in.info->info502->sd_buf.sd;
2016 map_generic_share_sd_bits(psd);
2019 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2025 return WERR_ACCESS_DENIED;
2027 /* DFS only level. */
2028 return WERR_ACCESS_DENIED;
2030 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2032 return WERR_INVALID_LEVEL;
2035 /* check for invalid share names */
2037 if (!share_name_in || !validate_net_name(share_name_in,
2038 INVALID_SHARENAME_CHARS,
2039 strlen(share_name_in))) {
2040 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2041 share_name_in ? share_name_in : ""));
2042 return WERR_INVALID_NAME;
2045 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2046 || (lp_enable_asu_support() &&
2047 strequal(share_name_in,"ADMIN$"))) {
2048 return WERR_ACCESS_DENIED;
2051 snum = find_service(ctx, share_name_in, &share_name);
2053 return WERR_NOT_ENOUGH_MEMORY;
2056 /* Share already exists. */
2058 return WERR_FILE_EXISTS;
2061 /* We can only add disk shares. */
2062 if (type != STYPE_DISKTREE) {
2063 return WERR_ACCESS_DENIED;
2066 /* Check if the pathname is valid. */
2067 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2068 return WERR_BAD_PATHNAME;
2071 ret = sys_lstat(path, &st, false);
2072 if (ret == -1 && (errno != EACCES)) {
2074 * If path has any other than permission
2075 * problem, return WERR_FILE_NOT_FOUND (as Windows
2078 return WERR_FILE_NOT_FOUND;
2081 /* Ensure share name, pathname and comment don't contain '"' characters. */
2082 string_replace(share_name_in, '"', ' ');
2083 string_replace(share_name, '"', ' ');
2084 string_replace(path, '"', ' ');
2086 string_replace(comment, '"', ' ');
2089 command = talloc_asprintf(ctx,
2090 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2091 lp_add_share_command(talloc_tos()),
2092 get_dyn_CONFIGFILE(),
2095 comment ? comment : "",
2098 return WERR_NOT_ENOUGH_MEMORY;
2101 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2103 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2108 /* FIXME: use libnetconf here - gd */
2110 ret = smbrun(command, NULL, NULL);
2112 /* Tell everyone we updated smb.conf. */
2113 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2120 /********* END SeDiskOperatorPrivilege BLOCK *********/
2122 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2125 TALLOC_FREE(command);
2128 return WERR_ACCESS_DENIED;
2131 /* Note we use share_name here, not share_name_in as
2132 we need a canonicalized name for setting security. */
2133 if (!set_share_security(share_name, psd)) {
2134 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2140 * We don't call reload_services() here, the message will
2141 * cause this to be done before the next packet is read
2142 * from the client. JRA.
2145 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2150 /*******************************************************************
2152 Call "delete share command" with the share name as
2154 ********************************************************************/
2156 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2157 struct srvsvc_NetShareDel *r)
2159 char *command = NULL;
2160 char *share_name = NULL;
2164 TALLOC_CTX *ctx = p->mem_ctx;
2166 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2168 if (!r->in.share_name) {
2169 return WERR_NERR_NETNAMENOTFOUND;
2172 if ( strequal(r->in.share_name,"IPC$")
2173 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2174 || strequal(r->in.share_name,"global") )
2176 return WERR_ACCESS_DENIED;
2179 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2181 return WERR_NOT_ENOUGH_MEMORY;
2185 return WERR_BAD_NET_NAME;
2188 /* No change to printer shares. */
2189 if (lp_printable(snum))
2190 return WERR_ACCESS_DENIED;
2192 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2194 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2195 return WERR_ACCESS_DENIED;
2197 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2198 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2199 return WERR_ACCESS_DENIED;
2202 command = talloc_asprintf(ctx,
2204 lp_delete_share_command(talloc_tos()),
2205 get_dyn_CONFIGFILE(),
2208 return WERR_NOT_ENOUGH_MEMORY;
2211 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2213 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2218 ret = smbrun(command, NULL, NULL);
2220 /* Tell everyone we updated smb.conf. */
2221 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2228 /********* END SeDiskOperatorPrivilege BLOCK *********/
2230 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2233 return WERR_ACCESS_DENIED;
2235 /* Delete the SD in the database. */
2236 delete_share_security(share_name);
2238 lp_killservice(snum);
2243 /*******************************************************************
2244 _srvsvc_NetShareDelSticky
2245 ********************************************************************/
2247 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2248 struct srvsvc_NetShareDelSticky *r)
2250 struct srvsvc_NetShareDel q;
2252 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2254 q.in.server_unc = r->in.server_unc;
2255 q.in.share_name = r->in.share_name;
2256 q.in.reserved = r->in.reserved;
2258 return _srvsvc_NetShareDel(p, &q);
2261 /*******************************************************************
2262 _srvsvc_NetRemoteTOD
2263 ********************************************************************/
2265 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2266 struct srvsvc_NetRemoteTOD *r)
2268 struct srvsvc_NetRemoteTODInfo *tod;
2270 time_t unixdate = time(NULL);
2272 /* We do this call first as if we do it *after* the gmtime call
2273 it overwrites the pointed-to values. JRA */
2275 uint32_t zone = get_time_zone(unixdate)/60;
2277 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2279 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2280 return WERR_NOT_ENOUGH_MEMORY;
2284 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2286 t = gmtime(&unixdate);
2289 tod->elapsed = unixdate;
2291 tod->hours = t->tm_hour;
2292 tod->mins = t->tm_min;
2293 tod->secs = t->tm_sec;
2295 tod->timezone = zone;
2296 tod->tinterval = 10000;
2297 tod->day = t->tm_mday;
2298 tod->month = t->tm_mon + 1;
2299 tod->year = 1900+t->tm_year;
2300 tod->weekday = t->tm_wday;
2302 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2307 /***********************************************************************************
2308 _srvsvc_NetGetFileSecurity
2309 Win9x NT tools get security descriptor.
2310 ***********************************************************************************/
2312 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2313 struct srvsvc_NetGetFileSecurity *r)
2315 struct smb_filename *smb_fname = NULL;
2317 char *servicename = NULL;
2321 connection_struct *conn = NULL;
2322 struct sec_desc_buf *sd_buf = NULL;
2323 files_struct *fsp = NULL;
2325 char *oldcwd = NULL;
2326 uint32_t ucf_flags = 0;
2331 werr = WERR_NERR_NETNAMENOTFOUND;
2334 snum = find_service(talloc_tos(), r->in.share, &servicename);
2336 werr = WERR_NOT_ENOUGH_MEMORY;
2340 DEBUG(10, ("Could not find service %s\n", servicename));
2341 werr = WERR_NERR_NETNAMENOTFOUND;
2345 nt_status = create_conn_struct_cwd(talloc_tos(),
2346 server_event_context(),
2347 server_messaging_context(),
2349 snum, lp_path(talloc_tos(), snum),
2350 p->session_info, &oldcwd);
2351 if (!NT_STATUS_IS_OK(nt_status)) {
2352 DEBUG(10, ("create_conn_struct failed: %s\n",
2353 nt_errstr(nt_status)));
2354 werr = ntstatus_to_werror(nt_status);
2358 nt_status = filename_convert(talloc_tos(),
2365 if (!NT_STATUS_IS_OK(nt_status)) {
2366 werr = ntstatus_to_werror(nt_status);
2370 nt_status = SMB_VFS_CREATE_FILE(
2373 0, /* root_dir_fid */
2374 smb_fname, /* fname */
2375 FILE_READ_ATTRIBUTES, /* access_mask */
2376 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2377 FILE_OPEN, /* create_disposition*/
2378 0, /* create_options */
2379 0, /* file_attributes */
2380 INTERNAL_OPEN_ONLY, /* oplock_request */
2382 0, /* allocation_size */
2383 0, /* private_flags */
2388 NULL, NULL); /* create context */
2390 if (!NT_STATUS_IS_OK(nt_status)) {
2391 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2392 smb_fname_str_dbg(smb_fname)));
2393 werr = ntstatus_to_werror(nt_status);
2397 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2399 werr = WERR_NOT_ENOUGH_MEMORY;
2403 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2406 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2408 if (!NT_STATUS_IS_OK(nt_status)) {
2409 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2410 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2411 werr = ntstatus_to_werror(nt_status);
2412 TALLOC_FREE(sd_buf);
2416 if (sd_buf->sd->dacl) {
2417 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2420 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2422 sd_buf->sd_size = sd_size;
2424 *r->out.sd_buf = sd_buf;
2426 close_file(NULL, fsp, NORMAL_CLOSE);
2427 vfs_ChDir(conn, oldcwd);
2428 SMB_VFS_DISCONNECT(conn);
2436 close_file(NULL, fsp, NORMAL_CLOSE);
2440 vfs_ChDir(conn, oldcwd);
2444 SMB_VFS_DISCONNECT(conn);
2450 TALLOC_FREE(smb_fname);
2455 /***********************************************************************************
2456 _srvsvc_NetSetFileSecurity
2457 Win9x NT tools set security descriptor.
2458 ***********************************************************************************/
2460 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2461 struct srvsvc_NetSetFileSecurity *r)
2463 struct smb_filename *smb_fname = NULL;
2464 char *servicename = NULL;
2465 files_struct *fsp = NULL;
2469 connection_struct *conn = NULL;
2471 char *oldcwd = NULL;
2472 struct security_descriptor *psd = NULL;
2473 uint32_t security_info_sent = 0;
2474 uint32_t ucf_flags = 0;
2479 werr = WERR_NERR_NETNAMENOTFOUND;
2483 snum = find_service(talloc_tos(), r->in.share, &servicename);
2485 werr = WERR_NOT_ENOUGH_MEMORY;
2490 DEBUG(10, ("Could not find service %s\n", servicename));
2491 werr = WERR_NERR_NETNAMENOTFOUND;
2495 nt_status = create_conn_struct_cwd(talloc_tos(),
2496 server_event_context(),
2497 server_messaging_context(),
2499 snum, lp_path(talloc_tos(), snum),
2500 p->session_info, &oldcwd);
2501 if (!NT_STATUS_IS_OK(nt_status)) {
2502 DEBUG(10, ("create_conn_struct failed: %s\n",
2503 nt_errstr(nt_status)));
2504 werr = ntstatus_to_werror(nt_status);
2508 nt_status = filename_convert(talloc_tos(),
2515 if (!NT_STATUS_IS_OK(nt_status)) {
2516 werr = ntstatus_to_werror(nt_status);
2520 nt_status = SMB_VFS_CREATE_FILE(
2523 0, /* root_dir_fid */
2524 smb_fname, /* fname */
2525 FILE_WRITE_ATTRIBUTES, /* access_mask */
2526 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2527 FILE_OPEN, /* create_disposition*/
2528 0, /* create_options */
2529 0, /* file_attributes */
2530 INTERNAL_OPEN_ONLY, /* oplock_request */
2532 0, /* allocation_size */
2533 0, /* private_flags */
2538 NULL, NULL); /* create context */
2540 if (!NT_STATUS_IS_OK(nt_status)) {
2541 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2542 smb_fname_str_dbg(smb_fname)));
2543 werr = ntstatus_to_werror(nt_status);
2547 psd = r->in.sd_buf->sd;
2548 security_info_sent = r->in.securityinformation;
2550 nt_status = set_sd(fsp, psd, security_info_sent);
2552 if (!NT_STATUS_IS_OK(nt_status) ) {
2553 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2554 "on file %s\n", r->in.share));
2555 werr = WERR_ACCESS_DENIED;
2559 close_file(NULL, fsp, NORMAL_CLOSE);
2560 vfs_ChDir(conn, oldcwd);
2561 SMB_VFS_DISCONNECT(conn);
2569 close_file(NULL, fsp, NORMAL_CLOSE);
2573 vfs_ChDir(conn, oldcwd);
2577 SMB_VFS_DISCONNECT(conn);
2582 TALLOC_FREE(smb_fname);
2587 /***********************************************************************************
2588 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2589 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2590 These disks would the disks listed by this function.
2591 Users could then create shares relative to these disks. Watch out for moving these disks around.
2592 "Nigel Williams" <nigel@veritas.com>.
2593 ***********************************************************************************/
2595 static const char *server_disks[] = {"C:"};
2597 static uint32_t get_server_disk_count(void)
2599 return sizeof(server_disks)/sizeof(server_disks[0]);
2602 static uint32_t init_server_disk_enum(uint32_t *resume)
2604 uint32_t server_disk_count = get_server_disk_count();
2606 /*resume can be an offset into the list for now*/
2608 if(*resume & 0x80000000)
2611 if(*resume > server_disk_count)
2612 *resume = server_disk_count;
2614 return server_disk_count - *resume;
2617 static const char *next_server_disk_enum(uint32_t *resume)
2621 if(init_server_disk_enum(resume) == 0)
2624 disk = server_disks[*resume];
2628 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2633 /********************************************************************
2635 ********************************************************************/
2637 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2638 struct srvsvc_NetDiskEnum *r)
2641 const char *disk_name;
2642 TALLOC_CTX *ctx = p->mem_ctx;
2644 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2648 *r->out.totalentries = init_server_disk_enum(&resume);
2650 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2651 MAX_SERVER_DISK_ENTRIES);
2652 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2654 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2656 r->out.info->count = 0;
2658 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2660 r->out.info->count++;
2662 /*copy disk name into a unicode string*/
2664 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2665 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2668 /* add a terminating null string. Is this there if there is more data to come? */
2670 r->out.info->count++;
2672 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2673 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2675 if (r->out.resume_handle) {
2676 *r->out.resume_handle = resume;
2682 /********************************************************************
2683 _srvsvc_NetNameValidate
2684 ********************************************************************/
2686 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2687 struct srvsvc_NetNameValidate *r)
2689 switch (r->in.name_type) {
2691 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2692 strlen_m(r->in.name)))
2694 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2696 return WERR_INVALID_NAME;
2701 return WERR_INVALID_LEVEL;
2707 /*******************************************************************
2708 ********************************************************************/
2710 struct enum_file_close_state {
2711 struct srvsvc_NetFileClose *r;
2712 struct messaging_context *msg_ctx;
2715 static int enum_file_close_fn(const struct share_mode_entry *e,
2716 const char *sharepath,
2721 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2722 struct enum_file_close_state *state =
2723 (struct enum_file_close_state *)private_data;
2724 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2726 if (fid != state->r->in.fid) {
2727 return 0; /* Not this file. */
2730 if (!process_exists(e->pid) ) {
2734 /* Ok - send the close message. */
2735 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2737 share_mode_str(talloc_tos(), 0, e) ));
2739 share_mode_entry_to_message(msg, e);
2741 state->r->out.result = ntstatus_to_werror(
2742 messaging_send_buf(state->msg_ctx,
2743 e->pid, MSG_SMB_CLOSE_FILE,
2744 (uint8_t *)msg, sizeof(msg)));
2749 /********************************************************************
2750 Close a file given a 32-bit file id.
2751 ********************************************************************/
2753 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2754 struct srvsvc_NetFileClose *r)
2756 struct enum_file_close_state state;
2759 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2761 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2763 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2764 return WERR_ACCESS_DENIED;
2767 /* enum_file_close_fn sends the close message to
2768 * the relevant smbd process. */
2770 r->out.result = WERR_FILE_NOT_FOUND;
2772 state.msg_ctx = p->msg_ctx;
2773 share_entry_forall(enum_file_close_fn, &state);
2774 return r->out.result;
2777 /********************************************************************
2778 ********************************************************************/
2780 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2781 struct srvsvc_NetCharDevEnum *r)
2783 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2784 return WERR_NOT_SUPPORTED;
2787 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2788 struct srvsvc_NetCharDevGetInfo *r)
2790 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2791 return WERR_NOT_SUPPORTED;
2794 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2795 struct srvsvc_NetCharDevControl *r)
2797 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2798 return WERR_NOT_SUPPORTED;
2801 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2802 struct srvsvc_NetCharDevQEnum *r)
2804 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2805 return WERR_NOT_SUPPORTED;
2808 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2809 struct srvsvc_NetCharDevQGetInfo *r)
2811 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2812 return WERR_NOT_SUPPORTED;
2815 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2816 struct srvsvc_NetCharDevQSetInfo *r)
2818 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2819 return WERR_NOT_SUPPORTED;
2822 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2823 struct srvsvc_NetCharDevQPurge *r)
2825 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2826 return WERR_NOT_SUPPORTED;
2829 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2830 struct srvsvc_NetCharDevQPurgeSelf *r)
2832 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2833 return WERR_NOT_SUPPORTED;
2836 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2837 struct srvsvc_NetFileGetInfo *r)
2839 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2840 return WERR_NOT_SUPPORTED;
2843 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2844 struct srvsvc_NetShareCheck *r)
2846 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2847 return WERR_NOT_SUPPORTED;
2850 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2851 struct srvsvc_NetServerStatisticsGet *r)
2853 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2854 return WERR_NOT_SUPPORTED;
2857 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2858 struct srvsvc_NetTransportAdd *r)
2860 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2861 return WERR_NOT_SUPPORTED;
2864 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2865 struct srvsvc_NetTransportEnum *r)
2867 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2868 return WERR_NOT_SUPPORTED;
2871 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2872 struct srvsvc_NetTransportDel *r)
2874 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2875 return WERR_NOT_SUPPORTED;
2878 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2879 struct srvsvc_NetSetServiceBits *r)
2881 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2882 return WERR_NOT_SUPPORTED;
2885 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2886 struct srvsvc_NetPathType *r)
2888 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2889 return WERR_NOT_SUPPORTED;
2892 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2893 struct srvsvc_NetPathCanonicalize *r)
2895 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2896 return WERR_NOT_SUPPORTED;
2899 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2900 struct srvsvc_NetPathCompare *r)
2902 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2903 return WERR_NOT_SUPPORTED;
2906 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2907 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2909 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2910 return WERR_NOT_SUPPORTED;
2913 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2914 struct srvsvc_NetPRNameCompare *r)
2916 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2917 return WERR_NOT_SUPPORTED;
2920 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2921 struct srvsvc_NetShareDelStart *r)
2923 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2924 return WERR_NOT_SUPPORTED;
2927 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2928 struct srvsvc_NetShareDelCommit *r)
2930 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2931 return WERR_NOT_SUPPORTED;
2934 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2935 struct srvsvc_NetServerTransportAddEx *r)
2937 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2938 return WERR_NOT_SUPPORTED;
2941 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2942 struct srvsvc_NetServerSetServiceBitsEx *r)
2944 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2945 return WERR_NOT_SUPPORTED;
2948 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2949 struct srvsvc_NETRDFSGETVERSION *r)
2951 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2952 return WERR_NOT_SUPPORTED;
2955 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2956 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2958 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2959 return WERR_NOT_SUPPORTED;
2962 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2963 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2965 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2966 return WERR_NOT_SUPPORTED;
2969 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2970 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2972 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2973 return WERR_NOT_SUPPORTED;
2976 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2977 struct srvsvc_NETRDFSSETSERVERINFO *r)
2979 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2980 return WERR_NOT_SUPPORTED;
2983 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2984 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2986 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2987 return WERR_NOT_SUPPORTED;
2990 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2991 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2993 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2994 return WERR_NOT_SUPPORTED;
2997 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2998 struct srvsvc_NETRDFSMODIFYPREFIX *r)
3000 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3001 return WERR_NOT_SUPPORTED;
3004 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
3005 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
3007 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3008 return WERR_NOT_SUPPORTED;
3011 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3012 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3014 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3015 return WERR_NOT_SUPPORTED;
3018 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3019 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3021 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3022 return WERR_NOT_SUPPORTED;