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_UNKNOWN_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,
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);
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_UNKNOWN_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_PARAM;
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);
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);
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);
1379 info100->platform_id = PLATFORM_ID_NT;
1380 info100->server_name = lp_netbios_name();
1382 r->out.info->info100 = info100;
1387 status = WERR_UNKNOWN_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_UNKNOWN_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_UNKNOWN_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);
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_UNKNOWN_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);
1754 /* Does this share exist ? */
1756 return WERR_NET_NAME_NOT_FOUND;
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_UNKNOWN_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) {
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_OBJECT_PATH_INVALID;
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(),
1900 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1902 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1907 if ( (ret = smbrun(command, NULL)) == 0 ) {
1908 /* Tell everyone we updated smb.conf. */
1909 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1916 /********* END SeDiskOperatorPrivilege BLOCK *********/
1918 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1921 TALLOC_FREE(command);
1924 return WERR_ACCESS_DENIED;
1926 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1930 /* Replace SD if changed. */
1932 struct security_descriptor *old_sd;
1935 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1937 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1938 if (!set_share_security(share_name, psd))
1939 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1944 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1949 /*******************************************************************
1950 _srvsvc_NetShareAdd.
1951 Call 'add_share_command "sharename" "pathname"
1952 "comment" "max connections = "
1953 ********************************************************************/
1955 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1956 struct srvsvc_NetShareAdd *r)
1958 char *command = NULL;
1959 char *share_name_in = NULL;
1960 char *share_name = NULL;
1961 char *comment = NULL;
1962 char *pathname = NULL;
1967 struct security_descriptor *psd = NULL;
1969 int max_connections = 0;
1971 TALLOC_CTX *ctx = p->mem_ctx;
1973 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1975 if (r->out.parm_error) {
1976 *r->out.parm_error = 0;
1979 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1981 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1982 return WERR_ACCESS_DENIED;
1984 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1985 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1986 return WERR_ACCESS_DENIED;
1989 switch (r->in.level) {
1991 /* No path. Not enough info in a level 0 to do anything. */
1992 return WERR_ACCESS_DENIED;
1994 /* Not enough info in a level 1 to do anything. */
1995 return WERR_ACCESS_DENIED;
1997 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1998 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1999 pathname = talloc_strdup(ctx, r->in.info->info2->path);
2000 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
2001 0 : r->in.info->info2->max_users;
2002 type = r->in.info->info2->type;
2005 /* No path. Not enough info in a level 501 to do anything. */
2006 return WERR_ACCESS_DENIED;
2008 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2009 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2010 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2011 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2012 0 : r->in.info->info502->max_users;
2013 type = r->in.info->info502->type;
2014 psd = r->in.info->info502->sd_buf.sd;
2015 map_generic_share_sd_bits(psd);
2018 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2024 return WERR_ACCESS_DENIED;
2026 /* DFS only level. */
2027 return WERR_ACCESS_DENIED;
2029 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2031 return WERR_UNKNOWN_LEVEL;
2034 /* check for invalid share names */
2036 if (!share_name_in || !validate_net_name(share_name_in,
2037 INVALID_SHARENAME_CHARS,
2038 strlen(share_name_in))) {
2039 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2040 share_name_in ? share_name_in : ""));
2041 return WERR_INVALID_NAME;
2044 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2045 || (lp_enable_asu_support() &&
2046 strequal(share_name_in,"ADMIN$"))) {
2047 return WERR_ACCESS_DENIED;
2050 snum = find_service(ctx, share_name_in, &share_name);
2055 /* Share already exists. */
2057 return WERR_FILE_EXISTS;
2060 /* We can only add disk shares. */
2061 if (type != STYPE_DISKTREE) {
2062 return WERR_ACCESS_DENIED;
2065 /* Check if the pathname is valid. */
2066 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2067 return WERR_OBJECT_PATH_INVALID;
2070 ret = sys_lstat(path, &st, false);
2071 if (ret == -1 && (errno != EACCES)) {
2073 * If path has any other than permission
2074 * problem, return WERR_BADFILE (as Windows
2077 return WERR_BADFILE;
2080 /* Ensure share name, pathname and comment don't contain '"' characters. */
2081 string_replace(share_name_in, '"', ' ');
2082 string_replace(share_name, '"', ' ');
2083 string_replace(path, '"', ' ');
2085 string_replace(comment, '"', ' ');
2088 command = talloc_asprintf(ctx,
2089 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2090 lp_add_share_command(talloc_tos()),
2091 get_dyn_CONFIGFILE(),
2094 comment ? comment : "",
2100 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2102 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2107 /* FIXME: use libnetconf here - gd */
2109 if ( (ret = smbrun(command, NULL)) == 0 ) {
2110 /* Tell everyone we updated smb.conf. */
2111 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2118 /********* END SeDiskOperatorPrivilege BLOCK *********/
2120 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2123 TALLOC_FREE(command);
2126 return WERR_ACCESS_DENIED;
2129 /* Note we use share_name here, not share_name_in as
2130 we need a canonicalized name for setting security. */
2131 if (!set_share_security(share_name, psd)) {
2132 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2138 * We don't call reload_services() here, the message will
2139 * cause this to be done before the next packet is read
2140 * from the client. JRA.
2143 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2148 /*******************************************************************
2150 Call "delete share command" with the share name as
2152 ********************************************************************/
2154 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2155 struct srvsvc_NetShareDel *r)
2157 char *command = NULL;
2158 char *share_name = NULL;
2162 TALLOC_CTX *ctx = p->mem_ctx;
2164 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2166 if (!r->in.share_name) {
2167 return WERR_NET_NAME_NOT_FOUND;
2170 if ( strequal(r->in.share_name,"IPC$")
2171 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2172 || strequal(r->in.share_name,"global") )
2174 return WERR_ACCESS_DENIED;
2177 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2183 return WERR_NO_SUCH_SHARE;
2186 /* No change to printer shares. */
2187 if (lp_printable(snum))
2188 return WERR_ACCESS_DENIED;
2190 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2192 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2193 return WERR_ACCESS_DENIED;
2195 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2196 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2197 return WERR_ACCESS_DENIED;
2200 command = talloc_asprintf(ctx,
2202 lp_delete_share_command(talloc_tos()),
2203 get_dyn_CONFIGFILE(),
2209 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2211 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2216 if ( (ret = smbrun(command, NULL)) == 0 ) {
2217 /* Tell everyone we updated smb.conf. */
2218 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2225 /********* END SeDiskOperatorPrivilege BLOCK *********/
2227 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2230 return WERR_ACCESS_DENIED;
2232 /* Delete the SD in the database. */
2233 delete_share_security(share_name);
2235 lp_killservice(snum);
2240 /*******************************************************************
2241 _srvsvc_NetShareDelSticky
2242 ********************************************************************/
2244 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2245 struct srvsvc_NetShareDelSticky *r)
2247 struct srvsvc_NetShareDel q;
2249 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2251 q.in.server_unc = r->in.server_unc;
2252 q.in.share_name = r->in.share_name;
2253 q.in.reserved = r->in.reserved;
2255 return _srvsvc_NetShareDel(p, &q);
2258 /*******************************************************************
2259 _srvsvc_NetRemoteTOD
2260 ********************************************************************/
2262 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2263 struct srvsvc_NetRemoteTOD *r)
2265 struct srvsvc_NetRemoteTODInfo *tod;
2267 time_t unixdate = time(NULL);
2269 /* We do this call first as if we do it *after* the gmtime call
2270 it overwrites the pointed-to values. JRA */
2272 uint32_t zone = get_time_zone(unixdate)/60;
2274 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2276 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2281 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2283 t = gmtime(&unixdate);
2286 tod->elapsed = unixdate;
2288 tod->hours = t->tm_hour;
2289 tod->mins = t->tm_min;
2290 tod->secs = t->tm_sec;
2292 tod->timezone = zone;
2293 tod->tinterval = 10000;
2294 tod->day = t->tm_mday;
2295 tod->month = t->tm_mon + 1;
2296 tod->year = 1900+t->tm_year;
2297 tod->weekday = t->tm_wday;
2299 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2304 /***********************************************************************************
2305 _srvsvc_NetGetFileSecurity
2306 Win9x NT tools get security descriptor.
2307 ***********************************************************************************/
2309 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2310 struct srvsvc_NetGetFileSecurity *r)
2312 struct smb_filename *smb_fname = NULL;
2314 char *servicename = NULL;
2318 connection_struct *conn = NULL;
2319 struct sec_desc_buf *sd_buf = NULL;
2320 files_struct *fsp = NULL;
2322 char *oldcwd = NULL;
2323 uint32_t ucf_flags = 0;
2328 werr = WERR_NET_NAME_NOT_FOUND;
2331 snum = find_service(talloc_tos(), r->in.share, &servicename);
2337 DEBUG(10, ("Could not find service %s\n", servicename));
2338 werr = WERR_NET_NAME_NOT_FOUND;
2342 nt_status = create_conn_struct_cwd(talloc_tos(),
2343 server_event_context(),
2344 server_messaging_context(),
2346 snum, lp_path(talloc_tos(), snum),
2347 p->session_info, &oldcwd);
2348 if (!NT_STATUS_IS_OK(nt_status)) {
2349 DEBUG(10, ("create_conn_struct failed: %s\n",
2350 nt_errstr(nt_status)));
2351 werr = ntstatus_to_werror(nt_status);
2355 nt_status = filename_convert(talloc_tos(),
2362 if (!NT_STATUS_IS_OK(nt_status)) {
2363 werr = ntstatus_to_werror(nt_status);
2367 nt_status = SMB_VFS_CREATE_FILE(
2370 0, /* root_dir_fid */
2371 smb_fname, /* fname */
2372 FILE_READ_ATTRIBUTES, /* access_mask */
2373 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2374 FILE_OPEN, /* create_disposition*/
2375 0, /* create_options */
2376 0, /* file_attributes */
2377 INTERNAL_OPEN_ONLY, /* oplock_request */
2379 0, /* allocation_size */
2380 0, /* private_flags */
2385 NULL, NULL); /* create context */
2387 if (!NT_STATUS_IS_OK(nt_status)) {
2388 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2389 smb_fname_str_dbg(smb_fname)));
2390 werr = ntstatus_to_werror(nt_status);
2394 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2400 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2403 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2405 if (!NT_STATUS_IS_OK(nt_status)) {
2406 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2407 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2408 werr = ntstatus_to_werror(nt_status);
2409 TALLOC_FREE(sd_buf);
2413 if (sd_buf->sd->dacl) {
2414 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2417 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2419 sd_buf->sd_size = sd_size;
2421 *r->out.sd_buf = sd_buf;
2423 close_file(NULL, fsp, NORMAL_CLOSE);
2424 vfs_ChDir(conn, oldcwd);
2425 SMB_VFS_DISCONNECT(conn);
2433 close_file(NULL, fsp, NORMAL_CLOSE);
2437 vfs_ChDir(conn, oldcwd);
2441 SMB_VFS_DISCONNECT(conn);
2447 TALLOC_FREE(smb_fname);
2452 /***********************************************************************************
2453 _srvsvc_NetSetFileSecurity
2454 Win9x NT tools set security descriptor.
2455 ***********************************************************************************/
2457 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2458 struct srvsvc_NetSetFileSecurity *r)
2460 struct smb_filename *smb_fname = NULL;
2461 char *servicename = NULL;
2462 files_struct *fsp = NULL;
2466 connection_struct *conn = NULL;
2468 char *oldcwd = NULL;
2469 struct security_descriptor *psd = NULL;
2470 uint32_t security_info_sent = 0;
2471 uint32_t ucf_flags = 0;
2476 werr = WERR_NET_NAME_NOT_FOUND;
2480 snum = find_service(talloc_tos(), r->in.share, &servicename);
2487 DEBUG(10, ("Could not find service %s\n", servicename));
2488 werr = WERR_NET_NAME_NOT_FOUND;
2492 nt_status = create_conn_struct_cwd(talloc_tos(),
2493 server_event_context(),
2494 server_messaging_context(),
2496 snum, lp_path(talloc_tos(), snum),
2497 p->session_info, &oldcwd);
2498 if (!NT_STATUS_IS_OK(nt_status)) {
2499 DEBUG(10, ("create_conn_struct failed: %s\n",
2500 nt_errstr(nt_status)));
2501 werr = ntstatus_to_werror(nt_status);
2505 nt_status = filename_convert(talloc_tos(),
2512 if (!NT_STATUS_IS_OK(nt_status)) {
2513 werr = ntstatus_to_werror(nt_status);
2517 nt_status = SMB_VFS_CREATE_FILE(
2520 0, /* root_dir_fid */
2521 smb_fname, /* fname */
2522 FILE_WRITE_ATTRIBUTES, /* access_mask */
2523 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2524 FILE_OPEN, /* create_disposition*/
2525 0, /* create_options */
2526 0, /* file_attributes */
2527 INTERNAL_OPEN_ONLY, /* oplock_request */
2529 0, /* allocation_size */
2530 0, /* private_flags */
2535 NULL, NULL); /* create context */
2537 if (!NT_STATUS_IS_OK(nt_status)) {
2538 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2539 smb_fname_str_dbg(smb_fname)));
2540 werr = ntstatus_to_werror(nt_status);
2544 psd = r->in.sd_buf->sd;
2545 security_info_sent = r->in.securityinformation;
2547 nt_status = set_sd(fsp, psd, security_info_sent);
2549 if (!NT_STATUS_IS_OK(nt_status) ) {
2550 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2551 "on file %s\n", r->in.share));
2552 werr = WERR_ACCESS_DENIED;
2556 close_file(NULL, fsp, NORMAL_CLOSE);
2557 vfs_ChDir(conn, oldcwd);
2558 SMB_VFS_DISCONNECT(conn);
2566 close_file(NULL, fsp, NORMAL_CLOSE);
2570 vfs_ChDir(conn, oldcwd);
2574 SMB_VFS_DISCONNECT(conn);
2579 TALLOC_FREE(smb_fname);
2584 /***********************************************************************************
2585 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2586 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2587 These disks would the disks listed by this function.
2588 Users could then create shares relative to these disks. Watch out for moving these disks around.
2589 "Nigel Williams" <nigel@veritas.com>.
2590 ***********************************************************************************/
2592 static const char *server_disks[] = {"C:"};
2594 static uint32_t get_server_disk_count(void)
2596 return sizeof(server_disks)/sizeof(server_disks[0]);
2599 static uint32_t init_server_disk_enum(uint32_t *resume)
2601 uint32_t server_disk_count = get_server_disk_count();
2603 /*resume can be an offset into the list for now*/
2605 if(*resume & 0x80000000)
2608 if(*resume > server_disk_count)
2609 *resume = server_disk_count;
2611 return server_disk_count - *resume;
2614 static const char *next_server_disk_enum(uint32_t *resume)
2618 if(init_server_disk_enum(resume) == 0)
2621 disk = server_disks[*resume];
2625 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2630 /********************************************************************
2632 ********************************************************************/
2634 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2635 struct srvsvc_NetDiskEnum *r)
2638 const char *disk_name;
2639 TALLOC_CTX *ctx = p->mem_ctx;
2641 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2645 *r->out.totalentries = init_server_disk_enum(&resume);
2647 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2648 MAX_SERVER_DISK_ENTRIES);
2649 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2651 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2653 r->out.info->count = 0;
2655 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2657 r->out.info->count++;
2659 /*copy disk name into a unicode string*/
2661 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2662 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2665 /* add a terminating null string. Is this there if there is more data to come? */
2667 r->out.info->count++;
2669 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2670 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2672 if (r->out.resume_handle) {
2673 *r->out.resume_handle = resume;
2679 /********************************************************************
2680 _srvsvc_NetNameValidate
2681 ********************************************************************/
2683 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2684 struct srvsvc_NetNameValidate *r)
2686 switch (r->in.name_type) {
2688 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2689 strlen_m(r->in.name)))
2691 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2693 return WERR_INVALID_NAME;
2698 return WERR_UNKNOWN_LEVEL;
2704 /*******************************************************************
2705 ********************************************************************/
2707 struct enum_file_close_state {
2708 struct srvsvc_NetFileClose *r;
2709 struct messaging_context *msg_ctx;
2712 static int enum_file_close_fn(const struct share_mode_entry *e,
2713 const char *sharepath,
2718 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2719 struct enum_file_close_state *state =
2720 (struct enum_file_close_state *)private_data;
2721 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2723 if (fid != state->r->in.fid) {
2724 return 0; /* Not this file. */
2727 if (!process_exists(e->pid) ) {
2731 /* Ok - send the close message. */
2732 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2734 share_mode_str(talloc_tos(), 0, e) ));
2736 share_mode_entry_to_message(msg, e);
2738 state->r->out.result = ntstatus_to_werror(
2739 messaging_send_buf(state->msg_ctx,
2740 e->pid, MSG_SMB_CLOSE_FILE,
2741 (uint8_t *)msg, sizeof(msg)));
2746 /********************************************************************
2747 Close a file given a 32-bit file id.
2748 ********************************************************************/
2750 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2751 struct srvsvc_NetFileClose *r)
2753 struct enum_file_close_state state;
2756 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2758 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2760 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2761 return WERR_ACCESS_DENIED;
2764 /* enum_file_close_fn sends the close message to
2765 * the relevant smbd process. */
2767 r->out.result = WERR_BADFILE;
2769 state.msg_ctx = p->msg_ctx;
2770 share_entry_forall(enum_file_close_fn, &state);
2771 return r->out.result;
2774 /********************************************************************
2775 ********************************************************************/
2777 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2778 struct srvsvc_NetCharDevEnum *r)
2780 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2781 return WERR_NOT_SUPPORTED;
2784 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2785 struct srvsvc_NetCharDevGetInfo *r)
2787 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2788 return WERR_NOT_SUPPORTED;
2791 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2792 struct srvsvc_NetCharDevControl *r)
2794 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2795 return WERR_NOT_SUPPORTED;
2798 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2799 struct srvsvc_NetCharDevQEnum *r)
2801 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2802 return WERR_NOT_SUPPORTED;
2805 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2806 struct srvsvc_NetCharDevQGetInfo *r)
2808 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2809 return WERR_NOT_SUPPORTED;
2812 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2813 struct srvsvc_NetCharDevQSetInfo *r)
2815 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2816 return WERR_NOT_SUPPORTED;
2819 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2820 struct srvsvc_NetCharDevQPurge *r)
2822 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2823 return WERR_NOT_SUPPORTED;
2826 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2827 struct srvsvc_NetCharDevQPurgeSelf *r)
2829 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2830 return WERR_NOT_SUPPORTED;
2833 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2834 struct srvsvc_NetFileGetInfo *r)
2836 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2837 return WERR_NOT_SUPPORTED;
2840 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2841 struct srvsvc_NetShareCheck *r)
2843 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2844 return WERR_NOT_SUPPORTED;
2847 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2848 struct srvsvc_NetServerStatisticsGet *r)
2850 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2851 return WERR_NOT_SUPPORTED;
2854 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2855 struct srvsvc_NetTransportAdd *r)
2857 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2858 return WERR_NOT_SUPPORTED;
2861 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2862 struct srvsvc_NetTransportEnum *r)
2864 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2865 return WERR_NOT_SUPPORTED;
2868 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2869 struct srvsvc_NetTransportDel *r)
2871 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2872 return WERR_NOT_SUPPORTED;
2875 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2876 struct srvsvc_NetSetServiceBits *r)
2878 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2879 return WERR_NOT_SUPPORTED;
2882 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2883 struct srvsvc_NetPathType *r)
2885 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2886 return WERR_NOT_SUPPORTED;
2889 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2890 struct srvsvc_NetPathCanonicalize *r)
2892 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2893 return WERR_NOT_SUPPORTED;
2896 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2897 struct srvsvc_NetPathCompare *r)
2899 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2900 return WERR_NOT_SUPPORTED;
2903 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2904 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2906 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2907 return WERR_NOT_SUPPORTED;
2910 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2911 struct srvsvc_NetPRNameCompare *r)
2913 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2914 return WERR_NOT_SUPPORTED;
2917 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2918 struct srvsvc_NetShareDelStart *r)
2920 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2921 return WERR_NOT_SUPPORTED;
2924 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2925 struct srvsvc_NetShareDelCommit *r)
2927 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2928 return WERR_NOT_SUPPORTED;
2931 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2932 struct srvsvc_NetServerTransportAddEx *r)
2934 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2935 return WERR_NOT_SUPPORTED;
2938 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2939 struct srvsvc_NetServerSetServiceBitsEx *r)
2941 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2942 return WERR_NOT_SUPPORTED;
2945 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2946 struct srvsvc_NETRDFSGETVERSION *r)
2948 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2949 return WERR_NOT_SUPPORTED;
2952 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2953 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2955 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2956 return WERR_NOT_SUPPORTED;
2959 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2960 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2962 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2963 return WERR_NOT_SUPPORTED;
2966 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2967 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2969 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2970 return WERR_NOT_SUPPORTED;
2973 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2974 struct srvsvc_NETRDFSSETSERVERINFO *r)
2976 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2977 return WERR_NOT_SUPPORTED;
2980 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2981 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2983 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2984 return WERR_NOT_SUPPORTED;
2987 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2988 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2990 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2991 return WERR_NOT_SUPPORTED;
2994 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2995 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2997 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2998 return WERR_NOT_SUPPORTED;
3001 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
3002 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
3004 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3005 return WERR_NOT_SUPPORTED;
3008 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3009 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3011 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3012 return WERR_NOT_SUPPORTED;
3015 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3016 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3018 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3019 return WERR_NOT_SUPPORTED;