2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Guenther Deschner 2008.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
27 #include "system/passwd.h"
28 #include "lib/util/server_id.h"
30 #include "../librpc/gen_ndr/srv_srvsvc.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/open_files.h"
34 #include "dbwrap/dbwrap.h"
36 #include "../lib/util/util_pw.h"
37 #include "smbd/smbd.h"
38 #include "smbd/globals.h"
42 #include "lib/conn_tdb.h"
44 extern const struct generic_mapping file_generic_mapping;
47 #define DBGC_CLASS DBGC_RPC_SRV
49 #define MAX_SERVER_DISK_ENTRIES 15
51 /* Use for enumerating connections, pipes, & files */
53 struct file_enum_count {
56 struct srvsvc_NetFileCtr3 *ctr3;
59 struct sess_file_info {
60 struct srvsvc_NetSessCtr1 *ctr;
61 struct sessionid *session_list;
62 uint32_t resume_handle;
66 struct share_file_stat {
67 struct srvsvc_NetConnInfo1 *netconn_arr;
68 struct server_id *svrid_arr;
69 const char *in_sharepath;
70 uint32_t resp_entries;
71 uint32_t total_entries;
74 struct share_conn_stat {
76 const char *sharename;
77 struct server_id *svrid_arr;
81 /*******************************************************************
82 ********************************************************************/
84 static int enum_file_fn(const struct share_mode_entry *e,
85 const char *sharepath,
90 struct file_enum_count *fenum =
91 (struct file_enum_count *)private_data;
93 struct srvsvc_NetFileInfo3 *f;
94 int i = fenum->ctr3->count;
96 struct byte_range_lock *brl;
98 char *fullpath = NULL;
100 const char *username;
102 /* If the pid was not found delete the entry from connections.tdb */
104 if ( !process_exists(e->pid) ) {
108 username = uidtoname(e->uid);
110 if ((fenum->username != NULL)
111 && !strequal(username, fenum->username)) {
115 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
116 struct srvsvc_NetFileInfo3, i+1);
118 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
121 fenum->ctr3->array = f;
123 /* need to count the number of locks on a file */
128 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
129 num_locks = brl_num_locks(brl);
133 if ( strcmp( fname, "." ) == 0 ) {
134 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
136 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s%s",
143 string_replace( fullpath, '/', '\\' );
145 /* mask out create (what ever that is) */
146 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
148 /* now fill in the srvsvc_NetFileInfo3 struct */
150 fenum->ctr3->array[i].fid =
151 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
152 fenum->ctr3->array[i].permissions = permissions;
153 fenum->ctr3->array[i].num_locks = num_locks;
154 fenum->ctr3->array[i].path = fullpath;
155 fenum->ctr3->array[i].user = username;
157 fenum->ctr3->count++;
162 /*******************************************************************
163 ********************************************************************/
165 static WERROR net_enum_files(TALLOC_CTX *ctx,
166 const char *username,
167 struct srvsvc_NetFileCtr3 **ctr3,
170 struct file_enum_count f_enum_cnt;
172 f_enum_cnt.ctx = ctx;
173 f_enum_cnt.username = username;
174 f_enum_cnt.ctr3 = *ctr3;
176 share_entry_forall( enum_file_fn, (void *)&f_enum_cnt );
178 *ctr3 = f_enum_cnt.ctr3;
183 /*******************************************************************
184 Utility function to get the 'type' of a share from an snum.
185 ********************************************************************/
186 static enum srvsvc_ShareType get_share_type(int snum)
188 /* work out the share type */
189 enum srvsvc_ShareType type = STYPE_DISKTREE;
191 if (lp_printable(snum)) {
192 type = lp_administrative_share(snum)
193 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
195 if (strequal(lp_fstype(snum), "IPC")) {
196 type = lp_administrative_share(snum)
197 ? STYPE_IPC_HIDDEN : STYPE_IPC;
202 /*******************************************************************
203 Fill in a share info level 0 structure.
204 ********************************************************************/
206 static void init_srv_share_info_0(struct pipes_struct *p,
207 struct srvsvc_NetShareInfo0 *r, int snum)
209 r->name = lp_servicename(talloc_tos(), snum);
212 /*******************************************************************
213 Fill in a share info level 1 structure.
214 ********************************************************************/
216 static void init_srv_share_info_1(struct pipes_struct *p,
217 struct srvsvc_NetShareInfo1 *r,
220 char *net_name = lp_servicename(talloc_tos(), snum);
221 char *remark = lp_comment(p->mem_ctx, snum);
224 remark = talloc_sub_advanced(
225 p->mem_ctx, lp_servicename(talloc_tos(), snum),
226 get_current_username(), lp_path(talloc_tos(), snum),
227 p->session_info->unix_token->uid, get_current_username(),
232 r->type = get_share_type(snum);
233 r->comment = remark ? remark : "";
236 /*******************************************************************
237 Fill in a share info level 2 structure.
238 ********************************************************************/
240 static void init_srv_share_info_2(struct pipes_struct *p,
241 struct srvsvc_NetShareInfo2 *r,
246 int max_connections = lp_max_connections(snum);
247 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
248 char *net_name = lp_servicename(talloc_tos(), snum);
250 remark = lp_comment(p->mem_ctx, snum);
252 remark = talloc_sub_advanced(
253 p->mem_ctx, lp_servicename(talloc_tos(), snum),
254 get_current_username(), lp_path(talloc_tos(), snum),
255 p->session_info->unix_token->uid, get_current_username(),
258 path = talloc_asprintf(p->mem_ctx,
259 "C:%s", lp_path(talloc_tos(), snum));
263 * Change / to \\ so that win2k will see it as a valid path.
264 * This was added to enable use of browsing in win2k add
268 string_replace(path, '/', '\\');
272 r->type = get_share_type(snum);
273 r->comment = remark ? remark : "";
275 r->max_users = max_uses;
276 r->current_users = 0; /* computed later */
277 r->path = path ? path : "";
281 /*******************************************************************
282 Map any generic bits to file specific bits.
283 ********************************************************************/
285 static void map_generic_share_sd_bits(struct security_descriptor *psd)
288 struct security_acl *ps_dacl = NULL;
297 for (i = 0; i < ps_dacl->num_aces; i++) {
298 struct security_ace *psa = &ps_dacl->aces[i];
299 uint32_t orig_mask = psa->access_mask;
301 se_map_generic(&psa->access_mask, &file_generic_mapping);
302 psa->access_mask |= orig_mask;
306 /*******************************************************************
307 Fill in a share info level 501 structure.
308 ********************************************************************/
310 static void init_srv_share_info_501(struct pipes_struct *p,
311 struct srvsvc_NetShareInfo501 *r, int snum)
313 const char *net_name = lp_servicename(talloc_tos(), snum);
314 char *remark = lp_comment(p->mem_ctx, snum);
317 remark = talloc_sub_advanced(
318 p->mem_ctx, lp_servicename(talloc_tos(), snum),
319 get_current_username(), lp_path(talloc_tos(), snum),
320 p->session_info->unix_token->uid, get_current_username(),
325 r->type = get_share_type(snum);
326 r->comment = remark ? remark : "";
329 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
332 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
335 /*******************************************************************
336 Fill in a share info level 502 structure.
337 ********************************************************************/
339 static void init_srv_share_info_502(struct pipes_struct *p,
340 struct srvsvc_NetShareInfo502 *r, int snum)
342 const char *net_name = lp_servicename(talloc_tos(), snum);
344 struct security_descriptor *sd = NULL;
345 struct sec_desc_buf *sd_buf = NULL;
347 TALLOC_CTX *ctx = p->mem_ctx;
348 char *remark = lp_comment(ctx, snum);
351 remark = talloc_sub_advanced(
352 p->mem_ctx, lp_servicename(talloc_tos(), snum),
353 get_current_username(), lp_path(talloc_tos(), snum),
354 p->session_info->unix_token->uid, get_current_username(),
357 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
360 * Change / to \\ so that win2k will see it as a valid path. This was added to
361 * enable use of browsing in win2k add share dialog.
363 string_replace(path, '/', '\\');
366 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
368 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
371 r->type = get_share_type(snum);
372 r->comment = remark ? remark : "";
374 r->max_users = (uint32_t)-1;
375 r->current_users = 1; /* ??? */
376 r->path = path ? path : "";
381 /***************************************************************************
382 Fill in a share info level 1004 structure.
383 ***************************************************************************/
385 static void init_srv_share_info_1004(struct pipes_struct *p,
386 struct srvsvc_NetShareInfo1004 *r,
389 char *remark = lp_comment(p->mem_ctx, snum);
392 remark = talloc_sub_advanced(
393 p->mem_ctx, lp_servicename(talloc_tos(), snum),
394 get_current_username(), lp_path(talloc_tos(), snum),
395 p->session_info->unix_token->uid, get_current_username(),
399 r->comment = remark ? remark : "";
402 /***************************************************************************
403 Fill in a share info level 1005 structure.
404 ***************************************************************************/
406 static void init_srv_share_info_1005(struct pipes_struct *p,
407 struct srvsvc_NetShareInfo1005 *r,
410 uint32_t dfs_flags = 0;
412 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
413 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
416 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
418 r->dfs_flags = dfs_flags;
421 /***************************************************************************
422 Fill in a share info level 1006 structure.
423 ***************************************************************************/
425 static void init_srv_share_info_1006(struct pipes_struct *p,
426 struct srvsvc_NetShareInfo1006 *r,
429 r->max_users = (uint32_t)-1;
432 /***************************************************************************
433 Fill in a share info level 1007 structure.
434 ***************************************************************************/
436 static void init_srv_share_info_1007(struct pipes_struct *p,
437 struct srvsvc_NetShareInfo1007 *r,
441 r->alternate_directory_name = "";
444 /*******************************************************************
445 Fill in a share info level 1501 structure.
446 ********************************************************************/
448 static void init_srv_share_info_1501(struct pipes_struct *p,
449 struct sec_desc_buf **r,
452 struct security_descriptor *sd;
453 struct sec_desc_buf *sd_buf = NULL;
455 TALLOC_CTX *ctx = p->mem_ctx;
457 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
459 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
465 /*******************************************************************
466 True if it ends in '$'.
467 ********************************************************************/
469 static bool is_hidden_share(int snum)
471 const char *net_name = lp_servicename(talloc_tos(), snum);
473 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
476 /*******************************************************************
477 Verify user is allowed to view share, access based enumeration
478 ********************************************************************/
479 static bool is_enumeration_allowed(struct pipes_struct *p,
482 if (!lp_access_based_share_enum(snum)) {
486 if (!user_ok_token(p->session_info->unix_info->unix_name,
487 p->session_info->info->domain_name,
488 p->session_info->security_token, snum)) {
492 return share_access_check(p->session_info->security_token,
493 lp_servicename(talloc_tos(), snum),
494 FILE_READ_DATA, NULL);
497 /****************************************************************************
498 Count an entry against the respective service.
499 ****************************************************************************/
501 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
503 union srvsvc_NetShareCtr *ctr = NULL;
504 struct srvsvc_NetShareInfo2 *info2 = NULL;
505 int share_entries = 0;
508 ctr = (union srvsvc_NetShareCtr *) udp;
511 share_entries = ctr->ctr2->count;
512 info2 = &ctr->ctr2->array[0];
514 for (i = 0; i < share_entries; i++, info2++) {
515 if (strequal(tcon->share_name, info2->name)) {
516 info2->current_users++;
524 /****************************************************************************
525 Count the entries belonging to all services in the connection db.
526 ****************************************************************************/
528 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
531 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
533 if (!NT_STATUS_IS_OK(status)) {
534 DEBUG(0,("count_connections_for_all_shares: traverse of "
535 "smbXsrv_tcon_global.tdb failed - %s\n",
540 /*******************************************************************
541 Fill in a share info structure.
542 ********************************************************************/
544 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
545 struct srvsvc_NetShareInfoCtr *info_ctr,
546 uint32_t *resume_handle_p,
547 uint32_t *total_entries,
551 int alloc_entries = 0;
552 int num_services = 0;
554 TALLOC_CTX *ctx = p->mem_ctx;
556 int valid_share_count = 0;
558 union srvsvc_NetShareCtr ctr;
559 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
561 DEBUG(5,("init_srv_share_info_ctr\n"));
563 /* Ensure all the usershares are loaded. */
565 delete_and_reload_printers(server_event_context(), p->msg_ctx);
566 load_usershare_shares(NULL, connections_snum_used);
567 load_registry_shares();
568 num_services = lp_numservices();
571 allowed = talloc_zero_array(ctx, bool, num_services);
572 W_ERROR_HAVE_NO_MEMORY(allowed);
574 /* Count the number of entries. */
575 for (snum = 0; snum < num_services; snum++) {
576 if (lp_browseable(snum) && lp_snum_ok(snum) &&
577 is_enumeration_allowed(p, snum) &&
578 (all_shares || !is_hidden_share(snum)) ) {
579 DEBUG(10, ("counting service %s\n",
580 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
581 allowed[snum] = true;
584 DEBUG(10, ("NOT counting service %s\n",
585 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
589 if (!num_entries || (resume_handle >= num_entries)) {
593 /* Calculate alloc entries. */
594 alloc_entries = num_entries - resume_handle;
595 switch (info_ctr->level) {
597 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
598 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
600 ctr.ctr0->count = alloc_entries;
601 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
602 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
604 for (snum = 0; snum < num_services; snum++) {
606 (resume_handle <= (i + valid_share_count++)) ) {
607 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
614 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
615 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
617 ctr.ctr1->count = alloc_entries;
618 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
619 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
621 for (snum = 0; snum < num_services; snum++) {
623 (resume_handle <= (i + valid_share_count++)) ) {
624 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
631 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
632 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
634 ctr.ctr2->count = alloc_entries;
635 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
636 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
638 for (snum = 0; snum < num_services; snum++) {
640 (resume_handle <= (i + valid_share_count++)) ) {
641 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
645 count_connections_for_all_shares(&ctr);
649 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
650 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
652 ctr.ctr501->count = alloc_entries;
653 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
654 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
656 for (snum = 0; snum < num_services; snum++) {
658 (resume_handle <= (i + valid_share_count++)) ) {
659 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
666 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
667 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
669 ctr.ctr502->count = alloc_entries;
670 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
671 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
673 for (snum = 0; snum < num_services; snum++) {
675 (resume_handle <= (i + valid_share_count++)) ) {
676 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
683 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
684 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
686 ctr.ctr1004->count = alloc_entries;
687 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
688 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
690 for (snum = 0; snum < num_services; snum++) {
692 (resume_handle <= (i + valid_share_count++)) ) {
693 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
700 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
701 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
703 ctr.ctr1005->count = alloc_entries;
704 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
705 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
707 for (snum = 0; snum < num_services; snum++) {
709 (resume_handle <= (i + valid_share_count++)) ) {
710 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
717 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
718 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
720 ctr.ctr1006->count = alloc_entries;
721 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
722 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
724 for (snum = 0; snum < num_services; snum++) {
726 (resume_handle <= (i + valid_share_count++)) ) {
727 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
734 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
735 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
737 ctr.ctr1007->count = alloc_entries;
738 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
739 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
741 for (snum = 0; snum < num_services; snum++) {
743 (resume_handle <= (i + valid_share_count++)) ) {
744 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
751 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
752 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
754 ctr.ctr1501->count = alloc_entries;
755 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
756 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
758 for (snum = 0; snum < num_services; snum++) {
760 (resume_handle <= (i + valid_share_count++)) ) {
761 struct sec_desc_buf *sd_buf = NULL;
762 init_srv_share_info_1501(p, &sd_buf, snum);
763 ctr.ctr1501->array[i++] = *sd_buf;
770 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
772 return WERR_INVALID_LEVEL;
775 *total_entries = alloc_entries;
776 if (resume_handle_p) {
778 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
780 *resume_handle_p = num_entries;
789 /*******************************************************************
790 fill in a sess info level 0 structure.
791 ********************************************************************/
793 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
794 struct srvsvc_NetSessCtr0 *ctr0,
795 uint32_t *resume_handle_p,
796 uint32_t *total_entries)
798 struct sessionid *session_list;
799 uint32_t num_entries = 0;
800 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
801 *total_entries = list_sessions(p->mem_ctx, &session_list);
803 DEBUG(5,("init_srv_sess_info_0\n"));
806 if (resume_handle_p) {
807 *resume_handle_p = 0;
812 for (; resume_handle < *total_entries; resume_handle++) {
814 ctr0->array = talloc_realloc(p->mem_ctx,
816 struct srvsvc_NetSessInfo0,
818 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
820 ctr0->array[num_entries].client =
821 session_list[resume_handle].remote_machine;
826 ctr0->count = num_entries;
828 if (resume_handle_p) {
829 if (*resume_handle_p >= *total_entries) {
830 *resume_handle_p = 0;
832 *resume_handle_p = resume_handle;
839 /***********************************************************************
840 * find out the session on which this file is open and bump up its count
841 **********************************************************************/
843 static int count_sess_files_fn(const struct share_mode_entry *e,
844 const char *sharepath,
849 struct sess_file_info *info = data;
850 uint32_t rh = info->resume_handle;
853 for (i=0; i < info->num_entries; i++) {
854 /* rh+info->num_entries is safe, as we've
856 *total_entries > resume_handle &&
857 info->num_entries = *total_entries - resume_handle;
858 inside init_srv_sess_info_1() below.
860 struct sessionid *sess = &info->session_list[rh + i];
861 if ((e->uid == sess->uid) &&
862 serverid_equal(&e->pid, &sess->pid)) {
864 info->ctr->array[i].num_open++;
871 /*******************************************************************
872 * count the num of open files on all sessions
873 *******************************************************************/
875 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
876 struct sessionid *session_list,
877 uint32_t resume_handle,
878 uint32_t num_entries)
880 struct sess_file_info s_file_info;
882 s_file_info.ctr = ctr1;
883 s_file_info.session_list = session_list;
884 s_file_info.resume_handle = resume_handle;
885 s_file_info.num_entries = num_entries;
887 share_entry_forall(count_sess_files_fn, &s_file_info);
890 /*******************************************************************
891 fill in a sess info level 1 structure.
892 ********************************************************************/
894 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
895 struct srvsvc_NetSessCtr1 *ctr1,
896 uint32_t *resume_handle_p,
897 uint32_t *total_entries)
899 struct sessionid *session_list;
900 uint32_t num_entries = 0;
901 time_t now = time(NULL);
902 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
907 if (resume_handle_p) {
908 *resume_handle_p = 0;
913 *total_entries = list_sessions(p->mem_ctx, &session_list);
915 if (resume_handle >= *total_entries) {
916 if (resume_handle_p) {
917 *resume_handle_p = 0;
922 /* We know num_entries must be positive, due to
923 the check resume_handle >= *total_entries above. */
925 num_entries = *total_entries - resume_handle;
927 ctr1->array = talloc_zero_array(p->mem_ctx,
928 struct srvsvc_NetSessInfo1,
931 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
933 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
934 uint32_t connect_time;
937 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
938 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
940 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
941 ctr1->array[num_entries].user = session_list[resume_handle].username;
942 ctr1->array[num_entries].num_open = 0;/* computed later */
943 ctr1->array[num_entries].time = connect_time;
944 ctr1->array[num_entries].idle_time = 0;
945 ctr1->array[num_entries].user_flags = guest;
948 ctr1->count = num_entries;
950 /* count open files on all sessions in single tdb traversal */
951 net_count_files_for_all_sess(ctr1, session_list,
952 resume_handle_p ? *resume_handle_p : 0,
955 if (resume_handle_p) {
956 if (*resume_handle_p >= *total_entries) {
957 *resume_handle_p = 0;
959 *resume_handle_p = resume_handle;
966 /*******************************************************************
967 find the share connection on which this open exists.
968 ********************************************************************/
970 static int share_file_fn(const struct share_mode_entry *e,
971 const char *sharepath,
976 struct share_file_stat *sfs = data;
978 uint32_t offset = sfs->total_entries - sfs->resp_entries;
980 if (strequal(sharepath, sfs->in_sharepath)) {
981 for (i=0; i < sfs->resp_entries; i++) {
982 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
983 sfs->netconn_arr[i].num_open ++;
991 /*******************************************************************
992 count number of open files on given share connections.
993 ********************************************************************/
995 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
996 struct server_id *svrid_arr, char *sharepath,
997 uint32_t resp_entries, uint32_t total_entries)
999 struct share_file_stat sfs;
1001 sfs.netconn_arr = arr;
1002 sfs.svrid_arr = svrid_arr;
1003 sfs.in_sharepath = sharepath;
1004 sfs.resp_entries = resp_entries;
1005 sfs.total_entries = total_entries;
1007 share_entry_forall(share_file_fn, &sfs);
1010 /****************************************************************************
1011 process an entry from the connection db.
1012 ****************************************************************************/
1014 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
1017 struct share_conn_stat *scs = data;
1019 if (!process_exists(tcon->server_id)) {
1023 if (strequal(tcon->share_name, scs->sharename)) {
1024 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1027 if (!scs->svrid_arr) {
1031 scs->svrid_arr[scs->count] = tcon->server_id;
1038 /****************************************************************************
1039 Count the connections to a share. Build an array of serverid's owning these
1041 ****************************************************************************/
1043 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1044 struct server_id **arr)
1046 struct share_conn_stat scs;
1050 scs.sharename = sharename;
1051 scs.svrid_arr = NULL;
1054 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 DEBUG(0,("count_share_conns: traverse of "
1058 "smbXsrv_tcon_global.tdb failed - %s\n",
1059 nt_errstr(status)));
1063 *arr = scs.svrid_arr;
1067 /*******************************************************************
1068 fill in a conn info level 0 structure.
1069 ********************************************************************/
1071 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1072 uint32_t *resume_handle_p,
1073 uint32_t *total_entries)
1075 uint32_t num_entries = 0;
1076 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1078 DEBUG(5,("init_srv_conn_info_0\n"));
1081 if (resume_handle_p) {
1082 *resume_handle_p = 0;
1091 for (; resume_handle < *total_entries; resume_handle++) {
1093 ctr0->array = talloc_realloc(talloc_tos(),
1095 struct srvsvc_NetConnInfo0,
1098 return WERR_NOT_ENOUGH_MEMORY;
1101 ctr0->array[num_entries].conn_id = *total_entries;
1103 /* move on to creating next connection */
1107 ctr0->count = num_entries;
1108 *total_entries = num_entries;
1110 if (resume_handle_p) {
1111 if (*resume_handle_p >= *total_entries) {
1112 *resume_handle_p = 0;
1114 *resume_handle_p = resume_handle;
1121 /*******************************************************************
1122 fill in a conn info level 1 structure.
1123 ********************************************************************/
1125 static WERROR init_srv_conn_info_1(const char *name,
1126 struct srvsvc_NetConnCtr1 *ctr1,
1127 uint32_t *resume_handle_p,
1128 uint32_t *total_entries)
1130 uint32_t num_entries = 0;
1132 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1133 char *share_name = NULL;
1134 struct server_id *svrid_arr = NULL;
1136 DEBUG(5,("init_srv_conn_info_1\n"));
1139 if (resume_handle_p) {
1140 *resume_handle_p = 0;
1145 /* check if this is a server name or a share name */
1146 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1147 (name[1] == '\\')) {
1149 /* 'name' is a server name - this part is unimplemented */
1152 /* 'name' is a share name */
1153 snum = find_service(talloc_tos(), name, &share_name);
1156 return WERR_NOT_ENOUGH_MEMORY;
1160 return WERR_INVALID_NAME;
1164 * count the num of connections to this share. Also,
1165 * build a list of serverid's that own these
1166 * connections. The serverid list is used later to
1167 * identify the share connection on which an open exists.
1170 *total_entries = count_share_conns(talloc_tos(),
1175 if (resume_handle >= *total_entries) {
1176 if (resume_handle_p) {
1177 *resume_handle_p = 0;
1183 * We know num_entries must be positive, due to
1184 * the check resume_handle >= *total_entries above.
1187 num_entries = *total_entries - resume_handle;
1191 ctr1->array = talloc_zero_array(talloc_tos(),
1192 struct srvsvc_NetConnInfo1,
1195 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1197 for (num_entries = 0; resume_handle < *total_entries;
1198 num_entries++, resume_handle++) {
1200 ctr1->array[num_entries].conn_id = *total_entries;
1201 ctr1->array[num_entries].conn_type = 0x3;
1204 * if these are connections to a share, we are going to
1205 * compute the opens on them later. If it's for the server,
1206 * it's unimplemented.
1210 ctr1->array[num_entries].num_open = 1;
1213 ctr1->array[num_entries].num_users = 1;
1214 ctr1->array[num_entries].conn_time = 3;
1215 ctr1->array[num_entries].user = "dummy_user";
1216 ctr1->array[num_entries].share = "IPC$";
1219 /* now compute open files on the share connections */
1224 * the locking tdb, which has the open files information,
1225 * does not store share name or share (service) number, but
1226 * just the share path. So, we can compute open files only
1227 * on the share path. If more than one shares are defined
1228 * on a share path, open files on all of them are included
1231 * To have the correct behavior in case multiple shares
1232 * are defined on the same path, changes to tdb records
1233 * would be required. That would be lot more effort, so
1234 * this seems a good stopgap fix.
1237 count_share_opens(ctr1->array, svrid_arr,
1238 lp_path(talloc_tos(), snum),
1239 num_entries, *total_entries);
1243 ctr1->count = num_entries;
1244 *total_entries = num_entries;
1246 if (resume_handle_p) {
1247 *resume_handle_p = resume_handle;
1253 /*******************************************************************
1255 *******************************************************************/
1257 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1258 struct srvsvc_NetFileEnum *r)
1260 TALLOC_CTX *ctx = NULL;
1261 struct srvsvc_NetFileCtr3 *ctr3;
1262 uint32_t resume_hnd = 0;
1265 switch (r->in.info_ctr->level) {
1269 return WERR_INVALID_LEVEL;
1272 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1273 p->session_info->security_token)) {
1274 DEBUG(1, ("Enumerating files only allowed for "
1275 "administrators\n"));
1276 return WERR_ACCESS_DENIED;
1280 ctr3 = r->in.info_ctr->ctr.ctr3;
1282 werr = WERR_INVALID_PARAMETER;
1286 /* TODO -- Windows enumerates
1288 (c) open directories and files */
1290 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1291 if (!W_ERROR_IS_OK(werr)) {
1295 *r->out.totalentries = ctr3->count;
1296 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1297 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1305 /*******************************************************************
1306 _srvsvc_NetSrvGetInfo
1307 ********************************************************************/
1309 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1310 struct srvsvc_NetSrvGetInfo *r)
1312 WERROR status = WERR_OK;
1314 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1316 if (!pipe_access_check(p)) {
1317 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1318 return WERR_ACCESS_DENIED;
1321 switch (r->in.level) {
1323 /* Technically level 102 should only be available to
1324 Administrators but there isn't anything super-secret
1325 here, as most of it is made up. */
1328 struct srvsvc_NetSrvInfo102 *info102;
1330 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1332 return WERR_NOT_ENOUGH_MEMORY;
1335 info102->platform_id = PLATFORM_ID_NT;
1336 info102->server_name = lp_netbios_name();
1337 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1338 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1339 info102->server_type = lp_default_server_announce();
1340 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1341 MAX_SERVER_STRING_LENGTH);
1342 info102->users = 0xffffffff;
1343 info102->disc = 0xf;
1344 info102->hidden = 0;
1345 info102->announce = 240;
1346 info102->anndelta = 3000;
1347 info102->licenses = 100000;
1348 info102->userpath = "C:\\";
1350 r->out.info->info102 = info102;
1354 struct srvsvc_NetSrvInfo101 *info101;
1356 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1358 return WERR_NOT_ENOUGH_MEMORY;
1361 info101->platform_id = PLATFORM_ID_NT;
1362 info101->server_name = lp_netbios_name();
1363 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1364 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1365 info101->server_type = lp_default_server_announce();
1366 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1367 MAX_SERVER_STRING_LENGTH);
1369 r->out.info->info101 = info101;
1373 struct srvsvc_NetSrvInfo100 *info100;
1375 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1377 return WERR_NOT_ENOUGH_MEMORY;
1380 info100->platform_id = PLATFORM_ID_NT;
1381 info100->server_name = lp_netbios_name();
1383 r->out.info->info100 = info100;
1388 status = WERR_INVALID_LEVEL;
1392 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1397 /*******************************************************************
1398 _srvsvc_NetSrvSetInfo
1399 ********************************************************************/
1401 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1402 struct srvsvc_NetSrvSetInfo *r)
1404 WERROR status = WERR_OK;
1406 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1408 /* Set up the net server set info structure. */
1410 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1415 /*******************************************************************
1417 ********************************************************************/
1419 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1420 struct srvsvc_NetConnEnum *r)
1424 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1426 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1427 p->session_info->security_token)) {
1428 DEBUG(1, ("Enumerating connections only allowed for "
1429 "administrators\n"));
1430 return WERR_ACCESS_DENIED;
1433 switch (r->in.info_ctr->level) {
1435 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1436 r->in.resume_handle,
1437 r->out.totalentries);
1440 werr = init_srv_conn_info_1(r->in.path,
1441 r->in.info_ctr->ctr.ctr1,
1442 r->in.resume_handle,
1443 r->out.totalentries);
1446 return WERR_INVALID_LEVEL;
1449 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1454 /*******************************************************************
1456 ********************************************************************/
1458 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1459 struct srvsvc_NetSessEnum *r)
1463 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1465 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1466 p->session_info->security_token)) {
1467 DEBUG(1, ("Enumerating sessions only allowed for "
1468 "administrators\n"));
1469 return WERR_ACCESS_DENIED;
1472 switch (r->in.info_ctr->level) {
1474 werr = init_srv_sess_info_0(p,
1475 r->in.info_ctr->ctr.ctr0,
1476 r->in.resume_handle,
1477 r->out.totalentries);
1480 werr = init_srv_sess_info_1(p,
1481 r->in.info_ctr->ctr.ctr1,
1482 r->in.resume_handle,
1483 r->out.totalentries);
1486 return WERR_INVALID_LEVEL;
1489 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1494 /*******************************************************************
1496 ********************************************************************/
1498 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1499 struct srvsvc_NetSessDel *r)
1501 struct sessionid *session_list;
1502 int num_sessions, snum;
1503 const char *username;
1504 const char *machine;
1505 bool not_root = False;
1508 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1510 werr = WERR_ACCESS_DENIED;
1512 /* fail out now if you are not root or not a domain admin */
1514 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1515 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1516 DOMAIN_RID_ADMINS))) {
1521 username = r->in.user;
1522 machine = r->in.client;
1524 /* strip leading backslashes if any */
1525 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1529 num_sessions = find_sessions(p->mem_ctx, username, machine,
1532 for (snum = 0; snum < num_sessions; snum++) {
1536 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1541 ntstat = messaging_send(p->msg_ctx,
1542 session_list[snum].pid,
1543 MSG_SHUTDOWN, &data_blob_null);
1545 if (NT_STATUS_IS_OK(ntstat))
1552 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1559 /*******************************************************************
1560 _srvsvc_NetShareEnumAll
1561 ********************************************************************/
1563 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1564 struct srvsvc_NetShareEnumAll *r)
1568 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1570 if (!pipe_access_check(p)) {
1571 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1572 return WERR_ACCESS_DENIED;
1575 /* Create the list of shares for the response. */
1576 werr = init_srv_share_info_ctr(p,
1578 r->in.resume_handle,
1579 r->out.totalentries,
1582 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1587 /*******************************************************************
1588 _srvsvc_NetShareEnum
1589 ********************************************************************/
1591 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1592 struct srvsvc_NetShareEnum *r)
1596 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1598 if (!pipe_access_check(p)) {
1599 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1600 return WERR_ACCESS_DENIED;
1603 /* Create the list of shares for the response. */
1604 werr = init_srv_share_info_ctr(p,
1606 r->in.resume_handle,
1607 r->out.totalentries,
1610 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1615 /*******************************************************************
1616 _srvsvc_NetShareGetInfo
1617 ********************************************************************/
1619 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1620 struct srvsvc_NetShareGetInfo *r)
1622 WERROR status = WERR_OK;
1623 char *share_name = NULL;
1625 union srvsvc_NetShareInfo *info = r->out.info;
1627 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1629 if (!r->in.share_name) {
1630 return WERR_INVALID_NAME;
1633 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1635 return WERR_NOT_ENOUGH_MEMORY;
1638 return WERR_INVALID_NAME;
1641 switch (r->in.level) {
1643 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1644 W_ERROR_HAVE_NO_MEMORY(info->info0);
1645 init_srv_share_info_0(p, info->info0, snum);
1648 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1649 W_ERROR_HAVE_NO_MEMORY(info->info1);
1650 init_srv_share_info_1(p, info->info1, snum);
1653 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1654 W_ERROR_HAVE_NO_MEMORY(info->info2);
1655 init_srv_share_info_2(p, info->info2, snum);
1656 info->info2->current_users =
1657 count_current_connections(info->info2->name, false);
1660 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1661 W_ERROR_HAVE_NO_MEMORY(info->info501);
1662 init_srv_share_info_501(p, info->info501, snum);
1665 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1666 W_ERROR_HAVE_NO_MEMORY(info->info502);
1667 init_srv_share_info_502(p, info->info502, snum);
1670 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1671 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1672 init_srv_share_info_1004(p, info->info1004, snum);
1675 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1676 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1677 init_srv_share_info_1005(p, info->info1005, snum);
1680 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1681 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1682 init_srv_share_info_1006(p, info->info1006, snum);
1685 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1686 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1687 init_srv_share_info_1007(p, info->info1007, snum);
1690 init_srv_share_info_1501(p, &info->info1501, snum);
1693 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1695 status = WERR_INVALID_LEVEL;
1699 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1704 /*******************************************************************
1705 _srvsvc_NetShareSetInfo. Modify share details.
1706 ********************************************************************/
1708 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1709 struct srvsvc_NetShareSetInfo *r)
1711 char *command = NULL;
1712 char *share_name = NULL;
1713 char *comment = NULL;
1714 const char *pathname = NULL;
1719 struct security_descriptor *psd = NULL;
1720 bool is_disk_op = False;
1721 const char *csc_policy = NULL;
1722 bool csc_policy_changed = false;
1723 const char *csc_policies[] = {"manual", "documents", "programs",
1725 uint32_t client_csc_policy;
1726 int max_connections = 0;
1727 TALLOC_CTX *ctx = p->mem_ctx;
1728 union srvsvc_NetShareInfo *info = r->in.info;
1730 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1732 if (!r->in.share_name) {
1733 return WERR_INVALID_NAME;
1736 if (r->out.parm_error) {
1737 *r->out.parm_error = 0;
1740 if ( strequal(r->in.share_name,"IPC$")
1741 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1742 || strequal(r->in.share_name,"global") )
1744 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1745 "modified by a remote user.\n",
1746 r->in.share_name ));
1747 return WERR_ACCESS_DENIED;
1750 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1752 return WERR_NOT_ENOUGH_MEMORY;
1755 /* Does this share exist ? */
1757 return WERR_NERR_NETNAMENOTFOUND;
1759 /* No change to printer shares. */
1760 if (lp_printable(snum))
1761 return WERR_ACCESS_DENIED;
1763 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1765 /* fail out now if you are not root and not a disk op */
1767 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1768 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1769 "SeDiskOperatorPrivilege privilege needed to modify "
1771 (unsigned int)p->session_info->unix_token->uid,
1773 return WERR_ACCESS_DENIED;
1776 max_connections = lp_max_connections(snum);
1777 csc_policy = csc_policies[lp_csc_policy(snum)];
1779 switch (r->in.level) {
1781 pathname = lp_path(ctx, snum);
1782 comment = talloc_strdup(ctx, info->info1->comment);
1783 type = info->info1->type;
1787 comment = talloc_strdup(ctx, info->info2->comment);
1788 pathname = info->info2->path;
1789 type = info->info2->type;
1790 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1791 0 : info->info2->max_users;
1795 /* not supported on set but here for completeness */
1797 comment = talloc_strdup(ctx, info->info501->comment);
1798 type = info->info501->type;
1803 comment = talloc_strdup(ctx, info->info502->comment);
1804 pathname = info->info502->path;
1805 type = info->info502->type;
1806 psd = info->info502->sd_buf.sd;
1807 map_generic_share_sd_bits(psd);
1810 pathname = lp_path(ctx, snum);
1811 comment = talloc_strdup(ctx, info->info1004->comment);
1812 type = STYPE_DISKTREE;
1815 /* XP re-sets the csc policy even if it wasn't changed by the
1816 user, so we must compare it to see if it's what is set in
1817 smb.conf, so that we can contine other ops like setting
1819 client_csc_policy = (info->info1005->dfs_flags &
1820 SHARE_1005_CSC_POLICY_MASK) >>
1821 SHARE_1005_CSC_POLICY_SHIFT;
1823 if (client_csc_policy == lp_csc_policy(snum))
1826 csc_policy = csc_policies[client_csc_policy];
1827 csc_policy_changed = true;
1830 pathname = lp_path(ctx, snum);
1831 comment = lp_comment(ctx, snum);
1832 type = STYPE_DISKTREE;
1836 return WERR_ACCESS_DENIED;
1838 pathname = lp_path(ctx, snum);
1839 comment = lp_comment(ctx, snum);
1840 psd = info->info1501->sd;
1841 map_generic_share_sd_bits(psd);
1842 type = STYPE_DISKTREE;
1845 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1847 return WERR_INVALID_LEVEL;
1850 /* We can only modify disk shares. */
1851 if (type != STYPE_DISKTREE) {
1852 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1855 return WERR_ACCESS_DENIED;
1858 if (comment == NULL) {
1859 return WERR_NOT_ENOUGH_MEMORY;
1862 /* Check if the pathname is valid. */
1863 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1864 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1866 return WERR_BAD_PATHNAME;
1869 /* Ensure share name, pathname and comment don't contain '"' characters. */
1870 string_replace(share_name, '"', ' ');
1871 string_replace(path, '"', ' ');
1872 string_replace(comment, '"', ' ');
1874 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1875 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1877 /* Only call modify function if something changed. */
1879 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1880 || (lp_max_connections(snum) != max_connections)
1881 || csc_policy_changed) {
1883 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1884 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1885 return WERR_ACCESS_DENIED;
1888 command = talloc_asprintf(p->mem_ctx,
1889 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1890 lp_change_share_command(talloc_tos()),
1891 get_dyn_CONFIGFILE(),
1898 return WERR_NOT_ENOUGH_MEMORY;
1901 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1903 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1908 ret = smbrun(command, NULL, NULL);
1910 /* Tell everyone we updated smb.conf. */
1911 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1918 /********* END SeDiskOperatorPrivilege BLOCK *********/
1920 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1923 TALLOC_FREE(command);
1926 return WERR_ACCESS_DENIED;
1928 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1932 /* Replace SD if changed. */
1934 struct security_descriptor *old_sd;
1937 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1939 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1940 if (!set_share_security(share_name, psd))
1941 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1946 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1951 /*******************************************************************
1952 _srvsvc_NetShareAdd.
1953 Call 'add_share_command "sharename" "pathname"
1954 "comment" "max connections = "
1955 ********************************************************************/
1957 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1958 struct srvsvc_NetShareAdd *r)
1960 char *command = NULL;
1961 char *share_name_in = NULL;
1962 char *share_name = NULL;
1963 char *comment = NULL;
1964 char *pathname = NULL;
1969 struct security_descriptor *psd = NULL;
1971 int max_connections = 0;
1973 TALLOC_CTX *ctx = p->mem_ctx;
1975 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1977 if (r->out.parm_error) {
1978 *r->out.parm_error = 0;
1981 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1983 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1984 return WERR_ACCESS_DENIED;
1986 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1987 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1988 return WERR_ACCESS_DENIED;
1991 switch (r->in.level) {
1993 /* No path. Not enough info in a level 0 to do anything. */
1994 return WERR_ACCESS_DENIED;
1996 /* Not enough info in a level 1 to do anything. */
1997 return WERR_ACCESS_DENIED;
1999 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
2000 comment = talloc_strdup(ctx, r->in.info->info2->comment);
2001 pathname = talloc_strdup(ctx, r->in.info->info2->path);
2002 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
2003 0 : r->in.info->info2->max_users;
2004 type = r->in.info->info2->type;
2007 /* No path. Not enough info in a level 501 to do anything. */
2008 return WERR_ACCESS_DENIED;
2010 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
2011 comment = talloc_strdup(ctx, r->in.info->info502->comment);
2012 pathname = talloc_strdup(ctx, r->in.info->info502->path);
2013 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
2014 0 : r->in.info->info502->max_users;
2015 type = r->in.info->info502->type;
2016 psd = r->in.info->info502->sd_buf.sd;
2017 map_generic_share_sd_bits(psd);
2020 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2026 return WERR_ACCESS_DENIED;
2028 /* DFS only level. */
2029 return WERR_ACCESS_DENIED;
2031 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2033 return WERR_INVALID_LEVEL;
2036 /* check for invalid share names */
2038 if (!share_name_in || !validate_net_name(share_name_in,
2039 INVALID_SHARENAME_CHARS,
2040 strlen(share_name_in))) {
2041 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2042 share_name_in ? share_name_in : ""));
2043 return WERR_INVALID_NAME;
2046 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2047 || (lp_enable_asu_support() &&
2048 strequal(share_name_in,"ADMIN$"))) {
2049 return WERR_ACCESS_DENIED;
2052 snum = find_service(ctx, share_name_in, &share_name);
2054 return WERR_NOT_ENOUGH_MEMORY;
2057 /* Share already exists. */
2059 return WERR_FILE_EXISTS;
2062 /* We can only add disk shares. */
2063 if (type != STYPE_DISKTREE) {
2064 return WERR_ACCESS_DENIED;
2067 /* Check if the pathname is valid. */
2068 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2069 return WERR_BAD_PATHNAME;
2072 ret = sys_lstat(path, &st, false);
2073 if (ret == -1 && (errno != EACCES)) {
2075 * If path has any other than permission
2076 * problem, return WERR_FILE_NOT_FOUND (as Windows
2079 return WERR_FILE_NOT_FOUND;
2082 /* Ensure share name, pathname and comment don't contain '"' characters. */
2083 string_replace(share_name_in, '"', ' ');
2084 string_replace(share_name, '"', ' ');
2085 string_replace(path, '"', ' ');
2087 string_replace(comment, '"', ' ');
2090 command = talloc_asprintf(ctx,
2091 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2092 lp_add_share_command(talloc_tos()),
2093 get_dyn_CONFIGFILE(),
2096 comment ? comment : "",
2099 return WERR_NOT_ENOUGH_MEMORY;
2102 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2104 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2109 /* FIXME: use libnetconf here - gd */
2111 ret = smbrun(command, NULL, NULL);
2113 /* Tell everyone we updated smb.conf. */
2114 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2121 /********* END SeDiskOperatorPrivilege BLOCK *********/
2123 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2126 TALLOC_FREE(command);
2129 return WERR_ACCESS_DENIED;
2132 /* Note we use share_name here, not share_name_in as
2133 we need a canonicalized name for setting security. */
2134 if (!set_share_security(share_name, psd)) {
2135 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2141 * We don't call reload_services() here, the message will
2142 * cause this to be done before the next packet is read
2143 * from the client. JRA.
2146 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2151 /*******************************************************************
2153 Call "delete share command" with the share name as
2155 ********************************************************************/
2157 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2158 struct srvsvc_NetShareDel *r)
2160 char *command = NULL;
2161 char *share_name = NULL;
2165 TALLOC_CTX *ctx = p->mem_ctx;
2167 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2169 if (!r->in.share_name) {
2170 return WERR_NERR_NETNAMENOTFOUND;
2173 if ( strequal(r->in.share_name,"IPC$")
2174 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2175 || strequal(r->in.share_name,"global") )
2177 return WERR_ACCESS_DENIED;
2180 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2182 return WERR_NOT_ENOUGH_MEMORY;
2186 return WERR_BAD_NET_NAME;
2189 /* No change to printer shares. */
2190 if (lp_printable(snum))
2191 return WERR_ACCESS_DENIED;
2193 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2195 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2196 return WERR_ACCESS_DENIED;
2198 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2199 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2200 return WERR_ACCESS_DENIED;
2203 command = talloc_asprintf(ctx,
2205 lp_delete_share_command(talloc_tos()),
2206 get_dyn_CONFIGFILE(),
2209 return WERR_NOT_ENOUGH_MEMORY;
2212 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2214 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2219 ret = smbrun(command, NULL, NULL);
2221 /* Tell everyone we updated smb.conf. */
2222 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2229 /********* END SeDiskOperatorPrivilege BLOCK *********/
2231 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2234 return WERR_ACCESS_DENIED;
2236 /* Delete the SD in the database. */
2237 delete_share_security(share_name);
2239 lp_killservice(snum);
2244 /*******************************************************************
2245 _srvsvc_NetShareDelSticky
2246 ********************************************************************/
2248 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2249 struct srvsvc_NetShareDelSticky *r)
2251 struct srvsvc_NetShareDel q;
2253 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2255 q.in.server_unc = r->in.server_unc;
2256 q.in.share_name = r->in.share_name;
2257 q.in.reserved = r->in.reserved;
2259 return _srvsvc_NetShareDel(p, &q);
2262 /*******************************************************************
2263 _srvsvc_NetRemoteTOD
2264 ********************************************************************/
2266 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2267 struct srvsvc_NetRemoteTOD *r)
2269 struct srvsvc_NetRemoteTODInfo *tod;
2271 time_t unixdate = time(NULL);
2273 /* We do this call first as if we do it *after* the gmtime call
2274 it overwrites the pointed-to values. JRA */
2276 uint32_t zone = get_time_zone(unixdate)/60;
2278 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2280 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2281 return WERR_NOT_ENOUGH_MEMORY;
2285 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2287 t = gmtime(&unixdate);
2290 tod->elapsed = unixdate;
2292 tod->hours = t->tm_hour;
2293 tod->mins = t->tm_min;
2294 tod->secs = t->tm_sec;
2296 tod->timezone = zone;
2297 tod->tinterval = 10000;
2298 tod->day = t->tm_mday;
2299 tod->month = t->tm_mon + 1;
2300 tod->year = 1900+t->tm_year;
2301 tod->weekday = t->tm_wday;
2303 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2308 /***********************************************************************************
2309 _srvsvc_NetGetFileSecurity
2310 Win9x NT tools get security descriptor.
2311 ***********************************************************************************/
2313 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2314 struct srvsvc_NetGetFileSecurity *r)
2316 struct smb_filename *smb_fname = NULL;
2318 char *servicename = NULL;
2322 connection_struct *conn = NULL;
2323 struct sec_desc_buf *sd_buf = NULL;
2324 files_struct *fsp = NULL;
2326 char *oldcwd = NULL;
2327 uint32_t ucf_flags = 0;
2332 werr = WERR_NERR_NETNAMENOTFOUND;
2335 snum = find_service(talloc_tos(), r->in.share, &servicename);
2337 werr = WERR_NOT_ENOUGH_MEMORY;
2341 DEBUG(10, ("Could not find service %s\n", servicename));
2342 werr = WERR_NERR_NETNAMENOTFOUND;
2346 nt_status = create_conn_struct_cwd(talloc_tos(),
2347 server_event_context(),
2348 server_messaging_context(),
2350 snum, lp_path(talloc_tos(), snum),
2351 p->session_info, &oldcwd);
2352 if (!NT_STATUS_IS_OK(nt_status)) {
2353 DEBUG(10, ("create_conn_struct failed: %s\n",
2354 nt_errstr(nt_status)));
2355 werr = ntstatus_to_werror(nt_status);
2359 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(),
2514 if (!NT_STATUS_IS_OK(nt_status)) {
2515 werr = ntstatus_to_werror(nt_status);
2519 nt_status = SMB_VFS_CREATE_FILE(
2522 0, /* root_dir_fid */
2523 smb_fname, /* fname */
2524 FILE_WRITE_ATTRIBUTES, /* access_mask */
2525 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2526 FILE_OPEN, /* create_disposition*/
2527 0, /* create_options */
2528 0, /* file_attributes */
2529 INTERNAL_OPEN_ONLY, /* oplock_request */
2531 0, /* allocation_size */
2532 0, /* private_flags */
2537 NULL, NULL); /* create context */
2539 if (!NT_STATUS_IS_OK(nt_status)) {
2540 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2541 smb_fname_str_dbg(smb_fname)));
2542 werr = ntstatus_to_werror(nt_status);
2546 psd = r->in.sd_buf->sd;
2547 security_info_sent = r->in.securityinformation;
2549 nt_status = set_sd(fsp, psd, security_info_sent);
2551 if (!NT_STATUS_IS_OK(nt_status) ) {
2552 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2553 "on file %s\n", r->in.share));
2554 werr = WERR_ACCESS_DENIED;
2558 close_file(NULL, fsp, NORMAL_CLOSE);
2559 vfs_ChDir(conn, oldcwd);
2560 SMB_VFS_DISCONNECT(conn);
2568 close_file(NULL, fsp, NORMAL_CLOSE);
2572 vfs_ChDir(conn, oldcwd);
2576 SMB_VFS_DISCONNECT(conn);
2581 TALLOC_FREE(smb_fname);
2586 /***********************************************************************************
2587 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2588 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2589 These disks would the disks listed by this function.
2590 Users could then create shares relative to these disks. Watch out for moving these disks around.
2591 "Nigel Williams" <nigel@veritas.com>.
2592 ***********************************************************************************/
2594 static const char *server_disks[] = {"C:"};
2596 static uint32_t get_server_disk_count(void)
2598 return sizeof(server_disks)/sizeof(server_disks[0]);
2601 static uint32_t init_server_disk_enum(uint32_t *resume)
2603 uint32_t server_disk_count = get_server_disk_count();
2605 /*resume can be an offset into the list for now*/
2607 if(*resume & 0x80000000)
2610 if(*resume > server_disk_count)
2611 *resume = server_disk_count;
2613 return server_disk_count - *resume;
2616 static const char *next_server_disk_enum(uint32_t *resume)
2620 if(init_server_disk_enum(resume) == 0)
2623 disk = server_disks[*resume];
2627 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2632 /********************************************************************
2634 ********************************************************************/
2636 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2637 struct srvsvc_NetDiskEnum *r)
2640 const char *disk_name;
2641 TALLOC_CTX *ctx = p->mem_ctx;
2643 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2647 *r->out.totalentries = init_server_disk_enum(&resume);
2649 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2650 MAX_SERVER_DISK_ENTRIES);
2651 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2653 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2655 r->out.info->count = 0;
2657 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2659 r->out.info->count++;
2661 /*copy disk name into a unicode string*/
2663 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2664 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2667 /* add a terminating null string. Is this there if there is more data to come? */
2669 r->out.info->count++;
2671 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2672 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2674 if (r->out.resume_handle) {
2675 *r->out.resume_handle = resume;
2681 /********************************************************************
2682 _srvsvc_NetNameValidate
2683 ********************************************************************/
2685 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2686 struct srvsvc_NetNameValidate *r)
2688 switch (r->in.name_type) {
2690 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2691 strlen_m(r->in.name)))
2693 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2695 return WERR_INVALID_NAME;
2700 return WERR_INVALID_LEVEL;
2706 /*******************************************************************
2707 ********************************************************************/
2709 struct enum_file_close_state {
2710 struct srvsvc_NetFileClose *r;
2711 struct messaging_context *msg_ctx;
2714 static int enum_file_close_fn(const struct share_mode_entry *e,
2715 const char *sharepath,
2720 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2721 struct enum_file_close_state *state =
2722 (struct enum_file_close_state *)private_data;
2723 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2725 if (fid != state->r->in.fid) {
2726 return 0; /* Not this file. */
2729 if (!process_exists(e->pid) ) {
2733 /* Ok - send the close message. */
2734 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2736 share_mode_str(talloc_tos(), 0, e) ));
2738 share_mode_entry_to_message(msg, e);
2740 state->r->out.result = ntstatus_to_werror(
2741 messaging_send_buf(state->msg_ctx,
2742 e->pid, MSG_SMB_CLOSE_FILE,
2743 (uint8_t *)msg, sizeof(msg)));
2748 /********************************************************************
2749 Close a file given a 32-bit file id.
2750 ********************************************************************/
2752 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2753 struct srvsvc_NetFileClose *r)
2755 struct enum_file_close_state state;
2758 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2760 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2762 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2763 return WERR_ACCESS_DENIED;
2766 /* enum_file_close_fn sends the close message to
2767 * the relevant smbd process. */
2769 r->out.result = WERR_FILE_NOT_FOUND;
2771 state.msg_ctx = p->msg_ctx;
2772 share_entry_forall(enum_file_close_fn, &state);
2773 return r->out.result;
2776 /********************************************************************
2777 ********************************************************************/
2779 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2780 struct srvsvc_NetCharDevEnum *r)
2782 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2783 return WERR_NOT_SUPPORTED;
2786 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2787 struct srvsvc_NetCharDevGetInfo *r)
2789 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2790 return WERR_NOT_SUPPORTED;
2793 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2794 struct srvsvc_NetCharDevControl *r)
2796 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2797 return WERR_NOT_SUPPORTED;
2800 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2801 struct srvsvc_NetCharDevQEnum *r)
2803 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2804 return WERR_NOT_SUPPORTED;
2807 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2808 struct srvsvc_NetCharDevQGetInfo *r)
2810 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2811 return WERR_NOT_SUPPORTED;
2814 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2815 struct srvsvc_NetCharDevQSetInfo *r)
2817 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2818 return WERR_NOT_SUPPORTED;
2821 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2822 struct srvsvc_NetCharDevQPurge *r)
2824 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2825 return WERR_NOT_SUPPORTED;
2828 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2829 struct srvsvc_NetCharDevQPurgeSelf *r)
2831 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2832 return WERR_NOT_SUPPORTED;
2835 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2836 struct srvsvc_NetFileGetInfo *r)
2838 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2839 return WERR_NOT_SUPPORTED;
2842 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2843 struct srvsvc_NetShareCheck *r)
2845 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2846 return WERR_NOT_SUPPORTED;
2849 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2850 struct srvsvc_NetServerStatisticsGet *r)
2852 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2853 return WERR_NOT_SUPPORTED;
2856 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2857 struct srvsvc_NetTransportAdd *r)
2859 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2860 return WERR_NOT_SUPPORTED;
2863 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2864 struct srvsvc_NetTransportEnum *r)
2866 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2867 return WERR_NOT_SUPPORTED;
2870 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2871 struct srvsvc_NetTransportDel *r)
2873 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2874 return WERR_NOT_SUPPORTED;
2877 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2878 struct srvsvc_NetSetServiceBits *r)
2880 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2881 return WERR_NOT_SUPPORTED;
2884 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2885 struct srvsvc_NetPathType *r)
2887 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2888 return WERR_NOT_SUPPORTED;
2891 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2892 struct srvsvc_NetPathCanonicalize *r)
2894 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2895 return WERR_NOT_SUPPORTED;
2898 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2899 struct srvsvc_NetPathCompare *r)
2901 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2902 return WERR_NOT_SUPPORTED;
2905 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2906 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2908 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2909 return WERR_NOT_SUPPORTED;
2912 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2913 struct srvsvc_NetPRNameCompare *r)
2915 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2916 return WERR_NOT_SUPPORTED;
2919 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2920 struct srvsvc_NetShareDelStart *r)
2922 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2923 return WERR_NOT_SUPPORTED;
2926 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2927 struct srvsvc_NetShareDelCommit *r)
2929 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2930 return WERR_NOT_SUPPORTED;
2933 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2934 struct srvsvc_NetServerTransportAddEx *r)
2936 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2937 return WERR_NOT_SUPPORTED;
2940 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2941 struct srvsvc_NetServerSetServiceBitsEx *r)
2943 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2944 return WERR_NOT_SUPPORTED;
2947 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2948 struct srvsvc_NETRDFSGETVERSION *r)
2950 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2951 return WERR_NOT_SUPPORTED;
2954 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2955 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2957 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2958 return WERR_NOT_SUPPORTED;
2961 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2962 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2964 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2965 return WERR_NOT_SUPPORTED;
2968 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2969 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2971 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2972 return WERR_NOT_SUPPORTED;
2975 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2976 struct srvsvc_NETRDFSSETSERVERINFO *r)
2978 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2979 return WERR_NOT_SUPPORTED;
2982 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2983 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2985 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2986 return WERR_NOT_SUPPORTED;
2989 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2990 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2992 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2993 return WERR_NOT_SUPPORTED;
2996 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2997 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2999 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3000 return WERR_NOT_SUPPORTED;
3003 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
3004 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
3006 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3007 return WERR_NOT_SUPPORTED;
3010 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
3011 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
3013 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3014 return WERR_NOT_SUPPORTED;
3017 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
3018 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
3020 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3021 return WERR_NOT_SUPPORTED;