2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Guenther Deschner 2008.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
27 #include "system/passwd.h"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping;
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count {
54 struct srvsvc_NetFileCtr3 *ctr3;
57 struct sess_file_info {
58 struct srvsvc_NetSessCtr1 *ctr;
59 struct sessionid *session_list;
60 uint32_t resume_handle;
64 struct share_file_stat {
65 struct srvsvc_NetConnInfo1 *netconn_arr;
66 struct server_id *svrid_arr;
67 const char *in_sharepath;
68 uint32_t resp_entries;
69 uint32_t total_entries;
72 struct share_conn_stat {
74 const char *sharename;
75 struct server_id *svrid_arr;
79 /*******************************************************************
80 ********************************************************************/
82 static void enum_file_fn( const struct share_mode_entry *e,
83 const char *sharepath, const char *fname,
86 struct file_enum_count *fenum =
87 (struct file_enum_count *)private_data;
89 struct srvsvc_NetFileInfo3 *f;
90 int i = fenum->ctr3->count;
92 struct byte_range_lock *brl;
94 char *fullpath = NULL;
98 /* If the pid was not found delete the entry from connections.tdb */
100 if ( !process_exists(e->pid) ) {
104 username = uidtoname(e->uid);
106 if ((fenum->username != NULL)
107 && !strequal(username, fenum->username)) {
111 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
112 struct srvsvc_NetFileInfo3, i+1);
114 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
117 fenum->ctr3->array = f;
119 /* need to count the number of locks on a file */
124 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
125 num_locks = brl_num_locks(brl);
129 if ( strcmp( fname, "." ) == 0 ) {
130 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
132 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
138 string_replace( fullpath, '/', '\\' );
140 /* mask out create (what ever that is) */
141 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
143 /* now fill in the srvsvc_NetFileInfo3 struct */
145 fenum->ctr3->array[i].fid =
146 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
147 fenum->ctr3->array[i].permissions = permissions;
148 fenum->ctr3->array[i].num_locks = num_locks;
149 fenum->ctr3->array[i].path = fullpath;
150 fenum->ctr3->array[i].user = username;
152 fenum->ctr3->count++;
155 /*******************************************************************
156 ********************************************************************/
158 static WERROR net_enum_files(TALLOC_CTX *ctx,
159 const char *username,
160 struct srvsvc_NetFileCtr3 **ctr3,
163 struct file_enum_count f_enum_cnt;
165 f_enum_cnt.ctx = ctx;
166 f_enum_cnt.username = username;
167 f_enum_cnt.ctr3 = *ctr3;
169 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
171 *ctr3 = f_enum_cnt.ctr3;
176 /*******************************************************************
177 Utility function to get the 'type' of a share from an snum.
178 ********************************************************************/
179 static enum srvsvc_ShareType get_share_type(int snum)
181 /* work out the share type */
182 enum srvsvc_ShareType type = STYPE_DISKTREE;
184 if (lp_printable(snum)) {
185 type = lp_administrative_share(snum)
186 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
188 if (strequal(lp_fstype(snum), "IPC")) {
189 type = lp_administrative_share(snum)
190 ? STYPE_IPC_HIDDEN : STYPE_IPC;
195 /*******************************************************************
196 Fill in a share info level 0 structure.
197 ********************************************************************/
199 static void init_srv_share_info_0(struct pipes_struct *p,
200 struct srvsvc_NetShareInfo0 *r, int snum)
202 r->name = lp_servicename(talloc_tos(), snum);
205 /*******************************************************************
206 Fill in a share info level 1 structure.
207 ********************************************************************/
209 static void init_srv_share_info_1(struct pipes_struct *p,
210 struct srvsvc_NetShareInfo1 *r,
213 char *net_name = lp_servicename(talloc_tos(), snum);
214 char *remark = lp_comment(p->mem_ctx, snum);
217 remark = talloc_sub_advanced(
218 p->mem_ctx, lp_servicename(talloc_tos(), snum),
219 get_current_username(), lp_path(talloc_tos(), snum),
220 p->session_info->unix_token->uid, get_current_username(),
225 r->type = get_share_type(snum);
226 r->comment = remark ? remark : "";
229 /*******************************************************************
230 Fill in a share info level 2 structure.
231 ********************************************************************/
233 static void init_srv_share_info_2(struct pipes_struct *p,
234 struct srvsvc_NetShareInfo2 *r,
239 int max_connections = lp_max_connections(snum);
240 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
241 char *net_name = lp_servicename(talloc_tos(), snum);
243 remark = lp_comment(p->mem_ctx, snum);
245 remark = talloc_sub_advanced(
246 p->mem_ctx, lp_servicename(talloc_tos(), snum),
247 get_current_username(), lp_path(talloc_tos(), snum),
248 p->session_info->unix_token->uid, get_current_username(),
251 path = talloc_asprintf(p->mem_ctx,
252 "C:%s", lp_path(talloc_tos(), snum));
256 * Change / to \\ so that win2k will see it as a valid path.
257 * This was added to enable use of browsing in win2k add
261 string_replace(path, '/', '\\');
265 r->type = get_share_type(snum);
266 r->comment = remark ? remark : "";
268 r->max_users = max_uses;
269 r->current_users = 0; /* computed later */
270 r->path = path ? path : "";
274 /*******************************************************************
275 Map any generic bits to file specific bits.
276 ********************************************************************/
278 static void map_generic_share_sd_bits(struct security_descriptor *psd)
281 struct security_acl *ps_dacl = NULL;
290 for (i = 0; i < ps_dacl->num_aces; i++) {
291 struct security_ace *psa = &ps_dacl->aces[i];
292 uint32 orig_mask = psa->access_mask;
294 se_map_generic(&psa->access_mask, &file_generic_mapping);
295 psa->access_mask |= orig_mask;
299 /*******************************************************************
300 Fill in a share info level 501 structure.
301 ********************************************************************/
303 static void init_srv_share_info_501(struct pipes_struct *p,
304 struct srvsvc_NetShareInfo501 *r, int snum)
306 const char *net_name = lp_servicename(talloc_tos(), snum);
307 char *remark = lp_comment(p->mem_ctx, snum);
310 remark = talloc_sub_advanced(
311 p->mem_ctx, lp_servicename(talloc_tos(), snum),
312 get_current_username(), lp_path(talloc_tos(), snum),
313 p->session_info->unix_token->uid, get_current_username(),
318 r->type = get_share_type(snum);
319 r->comment = remark ? remark : "";
322 * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
325 r->csc_policy = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
328 /*******************************************************************
329 Fill in a share info level 502 structure.
330 ********************************************************************/
332 static void init_srv_share_info_502(struct pipes_struct *p,
333 struct srvsvc_NetShareInfo502 *r, int snum)
335 const char *net_name = lp_servicename(talloc_tos(), snum);
337 struct security_descriptor *sd = NULL;
338 struct sec_desc_buf *sd_buf = NULL;
340 TALLOC_CTX *ctx = p->mem_ctx;
341 char *remark = lp_comment(ctx, snum);
344 remark = talloc_sub_advanced(
345 p->mem_ctx, lp_servicename(talloc_tos(), snum),
346 get_current_username(), lp_path(talloc_tos(), snum),
347 p->session_info->unix_token->uid, get_current_username(),
350 path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), snum));
353 * Change / to \\ so that win2k will see it as a valid path. This was added to
354 * enable use of browsing in win2k add share dialog.
356 string_replace(path, '/', '\\');
359 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
361 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
364 r->type = get_share_type(snum);
365 r->comment = remark ? remark : "";
367 r->max_users = (uint32_t)-1;
368 r->current_users = 1; /* ??? */
369 r->path = path ? path : "";
374 /***************************************************************************
375 Fill in a share info level 1004 structure.
376 ***************************************************************************/
378 static void init_srv_share_info_1004(struct pipes_struct *p,
379 struct srvsvc_NetShareInfo1004 *r,
382 char *remark = lp_comment(p->mem_ctx, snum);
385 remark = talloc_sub_advanced(
386 p->mem_ctx, lp_servicename(talloc_tos(), snum),
387 get_current_username(), lp_path(talloc_tos(), snum),
388 p->session_info->unix_token->uid, get_current_username(),
392 r->comment = remark ? remark : "";
395 /***************************************************************************
396 Fill in a share info level 1005 structure.
397 ***************************************************************************/
399 static void init_srv_share_info_1005(struct pipes_struct *p,
400 struct srvsvc_NetShareInfo1005 *r,
403 uint32_t dfs_flags = 0;
405 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
406 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
409 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
411 r->dfs_flags = dfs_flags;
414 /***************************************************************************
415 Fill in a share info level 1006 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1006(struct pipes_struct *p,
419 struct srvsvc_NetShareInfo1006 *r,
422 r->max_users = (uint32_t)-1;
425 /***************************************************************************
426 Fill in a share info level 1007 structure.
427 ***************************************************************************/
429 static void init_srv_share_info_1007(struct pipes_struct *p,
430 struct srvsvc_NetShareInfo1007 *r,
434 r->alternate_directory_name = "";
437 /*******************************************************************
438 Fill in a share info level 1501 structure.
439 ********************************************************************/
441 static void init_srv_share_info_1501(struct pipes_struct *p,
442 struct sec_desc_buf **r,
445 struct security_descriptor *sd;
446 struct sec_desc_buf *sd_buf = NULL;
448 TALLOC_CTX *ctx = p->mem_ctx;
450 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
452 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
458 /*******************************************************************
459 True if it ends in '$'.
460 ********************************************************************/
462 static bool is_hidden_share(int snum)
464 const char *net_name = lp_servicename(talloc_tos(), snum);
466 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
469 /*******************************************************************
470 Verify user is allowed to view share, access based enumeration
471 ********************************************************************/
472 static bool is_enumeration_allowed(struct pipes_struct *p,
475 if (!lp_access_based_share_enum(snum))
478 return share_access_check(p->session_info->security_token,
479 lp_servicename(talloc_tos(), snum),
480 FILE_READ_DATA, NULL);
483 /****************************************************************************
484 Count an entry against the respective service.
485 ****************************************************************************/
487 static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
489 union srvsvc_NetShareCtr *ctr = NULL;
490 struct srvsvc_NetShareInfo2 *info2 = NULL;
491 int share_entries = 0;
494 ctr = (union srvsvc_NetShareCtr *) udp;
497 share_entries = ctr->ctr2->count;
498 info2 = &ctr->ctr2->array[0];
500 for (i = 0; i < share_entries; i++, info2++) {
501 if (strequal(tcon->share_name, info2->name)) {
502 info2->current_users++;
510 /****************************************************************************
511 Count the entries belonging to all services in the connection db.
512 ****************************************************************************/
514 static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
517 status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
519 if (!NT_STATUS_IS_OK(status)) {
520 DEBUG(0,("count_connections_for_all_shares: traverse of "
521 "smbXsrv_tcon_global.tdb failed - %s\n",
526 /*******************************************************************
527 Fill in a share info structure.
528 ********************************************************************/
530 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
531 struct srvsvc_NetShareInfoCtr *info_ctr,
532 uint32_t *resume_handle_p,
533 uint32_t *total_entries,
537 int alloc_entries = 0;
538 int num_services = 0;
540 TALLOC_CTX *ctx = p->mem_ctx;
542 int valid_share_count = 0;
544 union srvsvc_NetShareCtr ctr;
545 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
547 DEBUG(5,("init_srv_share_info_ctr\n"));
549 /* Ensure all the usershares are loaded. */
551 delete_and_reload_printers(server_event_context(), p->msg_ctx);
552 load_usershare_shares(NULL, connections_snum_used);
553 load_registry_shares();
554 num_services = lp_numservices();
557 allowed = talloc_zero_array(ctx, bool, num_services);
558 W_ERROR_HAVE_NO_MEMORY(allowed);
560 /* Count the number of entries. */
561 for (snum = 0; snum < num_services; snum++) {
562 if (lp_browseable(snum) && lp_snum_ok(snum) &&
563 is_enumeration_allowed(p, snum) &&
564 (all_shares || !is_hidden_share(snum)) ) {
565 DEBUG(10, ("counting service %s\n",
566 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
567 allowed[snum] = true;
570 DEBUG(10, ("NOT counting service %s\n",
571 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
575 if (!num_entries || (resume_handle >= num_entries)) {
579 /* Calculate alloc entries. */
580 alloc_entries = num_entries - resume_handle;
581 switch (info_ctr->level) {
583 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
584 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
586 ctr.ctr0->count = alloc_entries;
587 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
588 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
590 for (snum = 0; snum < num_services; snum++) {
592 (resume_handle <= (i + valid_share_count++)) ) {
593 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
600 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
601 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
603 ctr.ctr1->count = alloc_entries;
604 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
605 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
607 for (snum = 0; snum < num_services; snum++) {
609 (resume_handle <= (i + valid_share_count++)) ) {
610 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
617 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
618 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
620 ctr.ctr2->count = alloc_entries;
621 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
622 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
624 for (snum = 0; snum < num_services; snum++) {
626 (resume_handle <= (i + valid_share_count++)) ) {
627 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
631 count_connections_for_all_shares(&ctr);
635 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
636 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
638 ctr.ctr501->count = alloc_entries;
639 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
640 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
642 for (snum = 0; snum < num_services; snum++) {
644 (resume_handle <= (i + valid_share_count++)) ) {
645 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
652 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
653 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
655 ctr.ctr502->count = alloc_entries;
656 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
657 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
659 for (snum = 0; snum < num_services; snum++) {
661 (resume_handle <= (i + valid_share_count++)) ) {
662 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
669 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
670 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
672 ctr.ctr1004->count = alloc_entries;
673 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
674 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
676 for (snum = 0; snum < num_services; snum++) {
678 (resume_handle <= (i + valid_share_count++)) ) {
679 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
686 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
687 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
689 ctr.ctr1005->count = alloc_entries;
690 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
691 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
693 for (snum = 0; snum < num_services; snum++) {
695 (resume_handle <= (i + valid_share_count++)) ) {
696 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
703 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
704 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
706 ctr.ctr1006->count = alloc_entries;
707 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
708 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
710 for (snum = 0; snum < num_services; snum++) {
712 (resume_handle <= (i + valid_share_count++)) ) {
713 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
720 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
721 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
723 ctr.ctr1007->count = alloc_entries;
724 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
725 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
727 for (snum = 0; snum < num_services; snum++) {
729 (resume_handle <= (i + valid_share_count++)) ) {
730 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
737 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
738 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
740 ctr.ctr1501->count = alloc_entries;
741 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
742 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
744 for (snum = 0; snum < num_services; snum++) {
746 (resume_handle <= (i + valid_share_count++)) ) {
747 struct sec_desc_buf *sd_buf = NULL;
748 init_srv_share_info_1501(p, &sd_buf, snum);
749 ctr.ctr1501->array[i++] = *sd_buf;
756 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
758 return WERR_UNKNOWN_LEVEL;
761 *total_entries = alloc_entries;
762 if (resume_handle_p) {
764 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
766 *resume_handle_p = num_entries;
775 /*******************************************************************
776 fill in a sess info level 0 structure.
777 ********************************************************************/
779 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
780 struct srvsvc_NetSessCtr0 *ctr0,
781 uint32_t *resume_handle_p,
782 uint32_t *total_entries)
784 struct sessionid *session_list;
785 uint32_t num_entries = 0;
786 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
787 *total_entries = list_sessions(p->mem_ctx, &session_list);
789 DEBUG(5,("init_srv_sess_info_0\n"));
792 if (resume_handle_p) {
793 *resume_handle_p = 0;
798 for (; resume_handle < *total_entries; resume_handle++) {
800 ctr0->array = talloc_realloc(p->mem_ctx,
802 struct srvsvc_NetSessInfo0,
804 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
806 ctr0->array[num_entries].client =
807 session_list[resume_handle].remote_machine;
812 ctr0->count = num_entries;
814 if (resume_handle_p) {
815 if (*resume_handle_p >= *total_entries) {
816 *resume_handle_p = 0;
818 *resume_handle_p = resume_handle;
825 /***********************************************************************
826 * find out the session on which this file is open and bump up its count
827 **********************************************************************/
829 static void count_sess_files_fn(const struct share_mode_entry *e,
830 const char *sharepath, const char *fname,
833 struct sess_file_info *info = data;
834 uint32_t rh = info->resume_handle;
837 for (i=0; i < info->num_entries; i++) {
838 /* rh+info->num_entries is safe, as we've
840 *total_entries > resume_handle &&
841 info->num_entries = *total_entries - resume_handle;
842 inside init_srv_sess_info_1() below.
844 struct sessionid *sess = &info->session_list[rh + i];
845 if ((e->uid == sess->uid) &&
846 serverid_equal(&e->pid, &sess->pid)) {
848 info->ctr->array[i].num_open++;
854 /*******************************************************************
855 * count the num of open files on all sessions
856 *******************************************************************/
858 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
859 struct sessionid *session_list,
860 uint32_t resume_handle,
861 uint32_t num_entries)
863 struct sess_file_info s_file_info;
865 s_file_info.ctr = ctr1;
866 s_file_info.session_list = session_list;
867 s_file_info.resume_handle = resume_handle;
868 s_file_info.num_entries = num_entries;
870 share_mode_forall(count_sess_files_fn, &s_file_info);
873 /*******************************************************************
874 fill in a sess info level 1 structure.
875 ********************************************************************/
877 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
878 struct srvsvc_NetSessCtr1 *ctr1,
879 uint32_t *resume_handle_p,
880 uint32_t *total_entries)
882 struct sessionid *session_list;
883 uint32_t num_entries = 0;
884 time_t now = time(NULL);
885 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
890 if (resume_handle_p) {
891 *resume_handle_p = 0;
896 *total_entries = list_sessions(p->mem_ctx, &session_list);
898 if (resume_handle >= *total_entries) {
899 if (resume_handle_p) {
900 *resume_handle_p = 0;
905 /* We know num_entries must be positive, due to
906 the check resume_handle >= *total_entries above. */
908 num_entries = *total_entries - resume_handle;
910 ctr1->array = talloc_zero_array(p->mem_ctx,
911 struct srvsvc_NetSessInfo1,
914 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
916 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
920 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
921 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
923 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
924 ctr1->array[num_entries].user = session_list[resume_handle].username;
925 ctr1->array[num_entries].num_open = 0;/* computed later */
926 ctr1->array[num_entries].time = connect_time;
927 ctr1->array[num_entries].idle_time = 0;
928 ctr1->array[num_entries].user_flags = guest;
931 ctr1->count = num_entries;
933 /* count open files on all sessions in single tdb traversal */
934 net_count_files_for_all_sess(ctr1, session_list,
935 resume_handle_p ? *resume_handle_p : 0,
938 if (resume_handle_p) {
939 if (*resume_handle_p >= *total_entries) {
940 *resume_handle_p = 0;
942 *resume_handle_p = resume_handle;
949 /*******************************************************************
950 find the share connection on which this open exists.
951 ********************************************************************/
953 static void share_file_fn(const struct share_mode_entry *e,
954 const char *sharepath, const char *fname,
957 struct share_file_stat *sfs = data;
959 uint32_t offset = sfs->total_entries - sfs->resp_entries;
961 if (strequal(sharepath, sfs->in_sharepath)) {
962 for (i=0; i < sfs->resp_entries; i++) {
963 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
964 sfs->netconn_arr[i].num_open ++;
971 /*******************************************************************
972 count number of open files on given share connections.
973 ********************************************************************/
975 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
976 struct server_id *svrid_arr, char *sharepath,
977 uint32_t resp_entries, uint32_t total_entries)
979 struct share_file_stat sfs;
981 sfs.netconn_arr = arr;
982 sfs.svrid_arr = svrid_arr;
983 sfs.in_sharepath = sharepath;
984 sfs.resp_entries = resp_entries;
985 sfs.total_entries = total_entries;
987 share_mode_forall(share_file_fn, &sfs);
990 /****************************************************************************
991 process an entry from the connection db.
992 ****************************************************************************/
994 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
997 struct share_conn_stat *scs = data;
999 if (!process_exists(tcon->server_id)) {
1003 if (strequal(tcon->share_name, scs->sharename)) {
1004 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1007 if (!scs->svrid_arr) {
1011 scs->svrid_arr[scs->count] = tcon->server_id;
1018 /****************************************************************************
1019 Count the connections to a share. Build an array of serverid's owning these
1021 ****************************************************************************/
1023 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1024 struct server_id **arr)
1026 struct share_conn_stat scs;
1030 scs.sharename = sharename;
1031 scs.svrid_arr = NULL;
1034 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1036 if (!NT_STATUS_IS_OK(status)) {
1037 DEBUG(0,("count_share_conns: traverse of "
1038 "smbXsrv_tcon_global.tdb failed - %s\n",
1039 nt_errstr(status)));
1043 *arr = scs.svrid_arr;
1047 /*******************************************************************
1048 fill in a conn info level 0 structure.
1049 ********************************************************************/
1051 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1052 uint32_t *resume_handle_p,
1053 uint32_t *total_entries)
1055 uint32_t num_entries = 0;
1056 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1058 DEBUG(5,("init_srv_conn_info_0\n"));
1061 if (resume_handle_p) {
1062 *resume_handle_p = 0;
1071 for (; resume_handle < *total_entries; resume_handle++) {
1073 ctr0->array = talloc_realloc(talloc_tos(),
1075 struct srvsvc_NetConnInfo0,
1081 ctr0->array[num_entries].conn_id = *total_entries;
1083 /* move on to creating next connection */
1087 ctr0->count = num_entries;
1088 *total_entries = num_entries;
1090 if (resume_handle_p) {
1091 if (*resume_handle_p >= *total_entries) {
1092 *resume_handle_p = 0;
1094 *resume_handle_p = resume_handle;
1101 /*******************************************************************
1102 fill in a conn info level 1 structure.
1103 ********************************************************************/
1105 static WERROR init_srv_conn_info_1(const char *name,
1106 struct srvsvc_NetConnCtr1 *ctr1,
1107 uint32_t *resume_handle_p,
1108 uint32_t *total_entries)
1110 uint32_t num_entries = 0, snum = 0;
1111 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1112 char *share_name = NULL;
1113 struct server_id *svrid_arr = NULL;
1115 DEBUG(5,("init_srv_conn_info_1\n"));
1118 if (resume_handle_p) {
1119 *resume_handle_p = 0;
1124 /* check if this is a server name or a share name */
1125 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1126 (name[1] == '\\')) {
1128 /* 'name' is a server name - this part is unimplemented */
1131 /* 'name' is a share name */
1132 snum = find_service(talloc_tos(), name, &share_name);
1139 return WERR_INVALID_NAME;
1143 * count the num of connections to this share. Also,
1144 * build a list of serverid's that own these
1145 * connections. The serverid list is used later to
1146 * identify the share connection on which an open exists.
1149 *total_entries = count_share_conns(talloc_tos(),
1154 if (resume_handle >= *total_entries) {
1155 if (resume_handle_p) {
1156 *resume_handle_p = 0;
1162 * We know num_entries must be positive, due to
1163 * the check resume_handle >= *total_entries above.
1166 num_entries = *total_entries - resume_handle;
1170 ctr1->array = talloc_zero_array(talloc_tos(),
1171 struct srvsvc_NetConnInfo1,
1174 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1176 for (num_entries = 0; resume_handle < *total_entries;
1177 num_entries++, resume_handle++) {
1179 ctr1->array[num_entries].conn_id = *total_entries;
1180 ctr1->array[num_entries].conn_type = 0x3;
1183 * if these are connections to a share, we are going to
1184 * compute the opens on them later. If it's for the server,
1185 * it's unimplemented.
1189 ctr1->array[num_entries].num_open = 1;
1192 ctr1->array[num_entries].num_users = 1;
1193 ctr1->array[num_entries].conn_time = 3;
1194 ctr1->array[num_entries].user = "dummy_user";
1195 ctr1->array[num_entries].share = "IPC$";
1198 /* now compute open files on the share connections */
1203 * the locking tdb, which has the open files information,
1204 * does not store share name or share (service) number, but
1205 * just the share path. So, we can compute open files only
1206 * on the share path. If more than one shares are defined
1207 * on a share path, open files on all of them are included
1210 * To have the correct behavior in case multiple shares
1211 * are defined on the same path, changes to tdb records
1212 * would be required. That would be lot more effort, so
1213 * this seems a good stopgap fix.
1216 count_share_opens(ctr1->array, svrid_arr,
1217 lp_path(talloc_tos(), snum),
1218 num_entries, *total_entries);
1222 ctr1->count = num_entries;
1223 *total_entries = num_entries;
1225 if (resume_handle_p) {
1226 *resume_handle_p = resume_handle;
1232 /*******************************************************************
1234 *******************************************************************/
1236 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1237 struct srvsvc_NetFileEnum *r)
1239 TALLOC_CTX *ctx = NULL;
1240 struct srvsvc_NetFileCtr3 *ctr3;
1241 uint32_t resume_hnd = 0;
1244 switch (r->in.info_ctr->level) {
1248 return WERR_UNKNOWN_LEVEL;
1251 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1252 p->session_info->security_token)) {
1253 DEBUG(1, ("Enumerating files only allowed for "
1254 "administrators\n"));
1255 return WERR_ACCESS_DENIED;
1259 ctr3 = r->in.info_ctr->ctr.ctr3;
1261 werr = WERR_INVALID_PARAM;
1265 /* TODO -- Windows enumerates
1267 (c) open directories and files */
1269 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1270 if (!W_ERROR_IS_OK(werr)) {
1274 *r->out.totalentries = ctr3->count;
1275 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1276 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1284 /*******************************************************************
1285 _srvsvc_NetSrvGetInfo
1286 ********************************************************************/
1288 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1289 struct srvsvc_NetSrvGetInfo *r)
1291 WERROR status = WERR_OK;
1293 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1295 if (!pipe_access_check(p)) {
1296 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1297 return WERR_ACCESS_DENIED;
1300 switch (r->in.level) {
1302 /* Technically level 102 should only be available to
1303 Administrators but there isn't anything super-secret
1304 here, as most of it is made up. */
1307 struct srvsvc_NetSrvInfo102 *info102;
1309 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1314 info102->platform_id = PLATFORM_ID_NT;
1315 info102->server_name = lp_netbios_name();
1316 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1317 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1318 info102->server_type = lp_default_server_announce();
1319 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1320 MAX_SERVER_STRING_LENGTH);
1321 info102->users = 0xffffffff;
1322 info102->disc = 0xf;
1323 info102->hidden = 0;
1324 info102->announce = 240;
1325 info102->anndelta = 3000;
1326 info102->licenses = 100000;
1327 info102->userpath = "C:\\";
1329 r->out.info->info102 = info102;
1333 struct srvsvc_NetSrvInfo101 *info101;
1335 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1340 info101->platform_id = PLATFORM_ID_NT;
1341 info101->server_name = lp_netbios_name();
1342 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1343 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1344 info101->server_type = lp_default_server_announce();
1345 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1346 MAX_SERVER_STRING_LENGTH);
1348 r->out.info->info101 = info101;
1352 struct srvsvc_NetSrvInfo100 *info100;
1354 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1359 info100->platform_id = PLATFORM_ID_NT;
1360 info100->server_name = lp_netbios_name();
1362 r->out.info->info100 = info100;
1367 status = WERR_UNKNOWN_LEVEL;
1371 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1376 /*******************************************************************
1377 _srvsvc_NetSrvSetInfo
1378 ********************************************************************/
1380 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1381 struct srvsvc_NetSrvSetInfo *r)
1383 WERROR status = WERR_OK;
1385 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1387 /* Set up the net server set info structure. */
1389 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1394 /*******************************************************************
1396 ********************************************************************/
1398 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1399 struct srvsvc_NetConnEnum *r)
1403 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1405 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1406 p->session_info->security_token)) {
1407 DEBUG(1, ("Enumerating connections only allowed for "
1408 "administrators\n"));
1409 return WERR_ACCESS_DENIED;
1412 switch (r->in.info_ctr->level) {
1414 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1415 r->in.resume_handle,
1416 r->out.totalentries);
1419 werr = init_srv_conn_info_1(r->in.path,
1420 r->in.info_ctr->ctr.ctr1,
1421 r->in.resume_handle,
1422 r->out.totalentries);
1425 return WERR_UNKNOWN_LEVEL;
1428 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1433 /*******************************************************************
1435 ********************************************************************/
1437 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1438 struct srvsvc_NetSessEnum *r)
1442 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1444 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1445 p->session_info->security_token)) {
1446 DEBUG(1, ("Enumerating sessions only allowed for "
1447 "administrators\n"));
1448 return WERR_ACCESS_DENIED;
1451 switch (r->in.info_ctr->level) {
1453 werr = init_srv_sess_info_0(p,
1454 r->in.info_ctr->ctr.ctr0,
1455 r->in.resume_handle,
1456 r->out.totalentries);
1459 werr = init_srv_sess_info_1(p,
1460 r->in.info_ctr->ctr.ctr1,
1461 r->in.resume_handle,
1462 r->out.totalentries);
1465 return WERR_UNKNOWN_LEVEL;
1468 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1473 /*******************************************************************
1475 ********************************************************************/
1477 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1478 struct srvsvc_NetSessDel *r)
1480 struct sessionid *session_list;
1481 int num_sessions, snum;
1482 const char *username;
1483 const char *machine;
1484 bool not_root = False;
1487 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1489 werr = WERR_ACCESS_DENIED;
1491 /* fail out now if you are not root or not a domain admin */
1493 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1494 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1495 DOMAIN_RID_ADMINS))) {
1500 username = r->in.user;
1501 machine = r->in.client;
1503 /* strip leading backslashes if any */
1504 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1508 num_sessions = find_sessions(p->mem_ctx, username, machine,
1511 for (snum = 0; snum < num_sessions; snum++) {
1515 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1520 ntstat = messaging_send(p->msg_ctx,
1521 session_list[snum].pid,
1522 MSG_SHUTDOWN, &data_blob_null);
1524 if (NT_STATUS_IS_OK(ntstat))
1531 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1538 /*******************************************************************
1539 _srvsvc_NetShareEnumAll
1540 ********************************************************************/
1542 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1543 struct srvsvc_NetShareEnumAll *r)
1547 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1549 if (!pipe_access_check(p)) {
1550 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1551 return WERR_ACCESS_DENIED;
1554 /* Create the list of shares for the response. */
1555 werr = init_srv_share_info_ctr(p,
1557 r->in.resume_handle,
1558 r->out.totalentries,
1561 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1566 /*******************************************************************
1567 _srvsvc_NetShareEnum
1568 ********************************************************************/
1570 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1571 struct srvsvc_NetShareEnum *r)
1575 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1577 if (!pipe_access_check(p)) {
1578 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1579 return WERR_ACCESS_DENIED;
1582 /* Create the list of shares for the response. */
1583 werr = init_srv_share_info_ctr(p,
1585 r->in.resume_handle,
1586 r->out.totalentries,
1589 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1594 /*******************************************************************
1595 _srvsvc_NetShareGetInfo
1596 ********************************************************************/
1598 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1599 struct srvsvc_NetShareGetInfo *r)
1601 WERROR status = WERR_OK;
1602 char *share_name = NULL;
1604 union srvsvc_NetShareInfo *info = r->out.info;
1606 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1608 if (!r->in.share_name) {
1609 return WERR_INVALID_NAME;
1612 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1617 return WERR_INVALID_NAME;
1620 switch (r->in.level) {
1622 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1623 W_ERROR_HAVE_NO_MEMORY(info->info0);
1624 init_srv_share_info_0(p, info->info0, snum);
1627 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1628 W_ERROR_HAVE_NO_MEMORY(info->info1);
1629 init_srv_share_info_1(p, info->info1, snum);
1632 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1633 W_ERROR_HAVE_NO_MEMORY(info->info2);
1634 init_srv_share_info_2(p, info->info2, snum);
1635 info->info2->current_users =
1636 count_current_connections(info->info2->name, false);
1639 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1640 W_ERROR_HAVE_NO_MEMORY(info->info501);
1641 init_srv_share_info_501(p, info->info501, snum);
1644 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1645 W_ERROR_HAVE_NO_MEMORY(info->info502);
1646 init_srv_share_info_502(p, info->info502, snum);
1649 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1650 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1651 init_srv_share_info_1004(p, info->info1004, snum);
1654 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1655 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1656 init_srv_share_info_1005(p, info->info1005, snum);
1659 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1660 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1661 init_srv_share_info_1006(p, info->info1006, snum);
1664 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1665 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1666 init_srv_share_info_1007(p, info->info1007, snum);
1669 init_srv_share_info_1501(p, &info->info1501, snum);
1672 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1674 status = WERR_UNKNOWN_LEVEL;
1678 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1683 /*******************************************************************
1684 _srvsvc_NetShareSetInfo. Modify share details.
1685 ********************************************************************/
1687 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1688 struct srvsvc_NetShareSetInfo *r)
1690 char *command = NULL;
1691 char *share_name = NULL;
1692 char *comment = NULL;
1693 const char *pathname = NULL;
1698 struct security_descriptor *psd = NULL;
1699 bool is_disk_op = False;
1700 const char *csc_policy = NULL;
1701 bool csc_policy_changed = false;
1702 const char *csc_policies[] = {"manual", "documents", "programs",
1704 uint32_t client_csc_policy;
1705 int max_connections = 0;
1706 TALLOC_CTX *ctx = p->mem_ctx;
1707 union srvsvc_NetShareInfo *info = r->in.info;
1709 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1711 if (!r->in.share_name) {
1712 return WERR_INVALID_NAME;
1715 if (r->out.parm_error) {
1716 *r->out.parm_error = 0;
1719 if ( strequal(r->in.share_name,"IPC$")
1720 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1721 || strequal(r->in.share_name,"global") )
1723 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1724 "modified by a remote user.\n",
1725 r->in.share_name ));
1726 return WERR_ACCESS_DENIED;
1729 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1734 /* Does this share exist ? */
1736 return WERR_NET_NAME_NOT_FOUND;
1738 /* No change to printer shares. */
1739 if (lp_printable(snum))
1740 return WERR_ACCESS_DENIED;
1742 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1744 /* fail out now if you are not root and not a disk op */
1746 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1747 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1748 "SeDiskOperatorPrivilege privilege needed to modify "
1750 (unsigned int)p->session_info->unix_token->uid,
1752 return WERR_ACCESS_DENIED;
1755 max_connections = lp_max_connections(snum);
1756 csc_policy = csc_policies[lp_csc_policy(snum)];
1758 switch (r->in.level) {
1760 pathname = lp_path(ctx, snum);
1761 comment = talloc_strdup(ctx, info->info1->comment);
1762 type = info->info1->type;
1766 comment = talloc_strdup(ctx, info->info2->comment);
1767 pathname = info->info2->path;
1768 type = info->info2->type;
1769 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1770 0 : info->info2->max_users;
1774 /* not supported on set but here for completeness */
1776 comment = talloc_strdup(ctx, info->info501->comment);
1777 type = info->info501->type;
1782 comment = talloc_strdup(ctx, info->info502->comment);
1783 pathname = info->info502->path;
1784 type = info->info502->type;
1785 psd = info->info502->sd_buf.sd;
1786 map_generic_share_sd_bits(psd);
1789 pathname = lp_path(ctx, snum);
1790 comment = talloc_strdup(ctx, info->info1004->comment);
1791 type = STYPE_DISKTREE;
1794 /* XP re-sets the csc policy even if it wasn't changed by the
1795 user, so we must compare it to see if it's what is set in
1796 smb.conf, so that we can contine other ops like setting
1798 client_csc_policy = (info->info1005->dfs_flags &
1799 SHARE_1005_CSC_POLICY_MASK) >>
1800 SHARE_1005_CSC_POLICY_SHIFT;
1802 if (client_csc_policy == lp_csc_policy(snum))
1805 csc_policy = csc_policies[client_csc_policy];
1806 csc_policy_changed = true;
1809 pathname = lp_path(ctx, snum);
1810 comment = lp_comment(ctx, snum);
1811 type = STYPE_DISKTREE;
1815 return WERR_ACCESS_DENIED;
1817 pathname = lp_path(ctx, snum);
1818 comment = lp_comment(ctx, snum);
1819 psd = info->info1501->sd;
1820 map_generic_share_sd_bits(psd);
1821 type = STYPE_DISKTREE;
1824 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1826 return WERR_UNKNOWN_LEVEL;
1829 /* We can only modify disk shares. */
1830 if (type != STYPE_DISKTREE) {
1831 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1834 return WERR_ACCESS_DENIED;
1837 if (comment == NULL) {
1841 /* Check if the pathname is valid. */
1842 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1843 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1845 return WERR_OBJECT_PATH_INVALID;
1848 /* Ensure share name, pathname and comment don't contain '"' characters. */
1849 string_replace(share_name, '"', ' ');
1850 string_replace(path, '"', ' ');
1851 string_replace(comment, '"', ' ');
1853 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1854 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1856 /* Only call modify function if something changed. */
1858 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1859 || (lp_max_connections(snum) != max_connections)
1860 || csc_policy_changed) {
1862 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1863 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1864 return WERR_ACCESS_DENIED;
1867 command = talloc_asprintf(p->mem_ctx,
1868 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1869 lp_change_share_command(talloc_tos()),
1870 get_dyn_CONFIGFILE(),
1873 comment ? comment : "",
1880 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1882 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1887 if ( (ret = smbrun(command, NULL)) == 0 ) {
1888 /* Tell everyone we updated smb.conf. */
1889 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1896 /********* END SeDiskOperatorPrivilege BLOCK *********/
1898 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1901 TALLOC_FREE(command);
1904 return WERR_ACCESS_DENIED;
1906 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1910 /* Replace SD if changed. */
1912 struct security_descriptor *old_sd;
1915 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1917 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1918 if (!set_share_security(share_name, psd))
1919 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1924 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1929 /*******************************************************************
1930 _srvsvc_NetShareAdd.
1931 Call 'add_share_command "sharename" "pathname"
1932 "comment" "max connections = "
1933 ********************************************************************/
1935 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1936 struct srvsvc_NetShareAdd *r)
1938 char *command = NULL;
1939 char *share_name_in = NULL;
1940 char *share_name = NULL;
1941 char *comment = NULL;
1942 char *pathname = NULL;
1947 struct security_descriptor *psd = NULL;
1949 int max_connections = 0;
1951 TALLOC_CTX *ctx = p->mem_ctx;
1953 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1955 if (r->out.parm_error) {
1956 *r->out.parm_error = 0;
1959 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1961 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1962 return WERR_ACCESS_DENIED;
1964 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1965 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1966 return WERR_ACCESS_DENIED;
1969 switch (r->in.level) {
1971 /* No path. Not enough info in a level 0 to do anything. */
1972 return WERR_ACCESS_DENIED;
1974 /* Not enough info in a level 1 to do anything. */
1975 return WERR_ACCESS_DENIED;
1977 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1978 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1979 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1980 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1981 0 : r->in.info->info2->max_users;
1982 type = r->in.info->info2->type;
1985 /* No path. Not enough info in a level 501 to do anything. */
1986 return WERR_ACCESS_DENIED;
1988 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1989 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1990 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1991 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1992 0 : r->in.info->info502->max_users;
1993 type = r->in.info->info502->type;
1994 psd = r->in.info->info502->sd_buf.sd;
1995 map_generic_share_sd_bits(psd);
1998 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2004 return WERR_ACCESS_DENIED;
2006 /* DFS only level. */
2007 return WERR_ACCESS_DENIED;
2009 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2011 return WERR_UNKNOWN_LEVEL;
2014 /* check for invalid share names */
2016 if (!share_name_in || !validate_net_name(share_name_in,
2017 INVALID_SHARENAME_CHARS,
2018 strlen(share_name_in))) {
2019 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2020 share_name_in ? share_name_in : ""));
2021 return WERR_INVALID_NAME;
2024 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2025 || (lp_enable_asu_support() &&
2026 strequal(share_name_in,"ADMIN$"))) {
2027 return WERR_ACCESS_DENIED;
2030 snum = find_service(ctx, share_name_in, &share_name);
2035 /* Share already exists. */
2037 return WERR_FILE_EXISTS;
2040 /* We can only add disk shares. */
2041 if (type != STYPE_DISKTREE) {
2042 return WERR_ACCESS_DENIED;
2045 /* Check if the pathname is valid. */
2046 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2047 return WERR_OBJECT_PATH_INVALID;
2050 ret = sys_lstat(path, &st, false);
2051 if (ret == -1 && (errno != EACCES)) {
2053 * If path has any other than permission
2054 * problem, return WERR_BADFILE (as Windows
2057 return WERR_BADFILE;
2060 /* Ensure share name, pathname and comment don't contain '"' characters. */
2061 string_replace(share_name_in, '"', ' ');
2062 string_replace(share_name, '"', ' ');
2063 string_replace(path, '"', ' ');
2065 string_replace(comment, '"', ' ');
2068 command = talloc_asprintf(ctx,
2069 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2070 lp_add_share_command(talloc_tos()),
2071 get_dyn_CONFIGFILE(),
2074 comment ? comment : "",
2080 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2082 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2087 /* FIXME: use libnetconf here - gd */
2089 if ( (ret = smbrun(command, NULL)) == 0 ) {
2090 /* Tell everyone we updated smb.conf. */
2091 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2098 /********* END SeDiskOperatorPrivilege BLOCK *********/
2100 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2103 TALLOC_FREE(command);
2106 return WERR_ACCESS_DENIED;
2109 /* Note we use share_name here, not share_name_in as
2110 we need a canonicalized name for setting security. */
2111 if (!set_share_security(share_name, psd)) {
2112 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2118 * We don't call reload_services() here, the message will
2119 * cause this to be done before the next packet is read
2120 * from the client. JRA.
2123 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2128 /*******************************************************************
2130 Call "delete share command" with the share name as
2132 ********************************************************************/
2134 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2135 struct srvsvc_NetShareDel *r)
2137 char *command = NULL;
2138 char *share_name = NULL;
2142 struct share_params *params;
2143 TALLOC_CTX *ctx = p->mem_ctx;
2145 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2147 if (!r->in.share_name) {
2148 return WERR_NET_NAME_NOT_FOUND;
2151 if ( strequal(r->in.share_name,"IPC$")
2152 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2153 || strequal(r->in.share_name,"global") )
2155 return WERR_ACCESS_DENIED;
2158 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2164 return WERR_NO_SUCH_SHARE;
2167 if (!(params = get_share_params(p->mem_ctx, share_name))) {
2168 return WERR_NO_SUCH_SHARE;
2171 /* No change to printer shares. */
2172 if (lp_printable(snum))
2173 return WERR_ACCESS_DENIED;
2175 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2177 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2178 return WERR_ACCESS_DENIED;
2180 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2181 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2182 return WERR_ACCESS_DENIED;
2185 command = talloc_asprintf(ctx,
2187 lp_delete_share_command(talloc_tos()),
2188 get_dyn_CONFIGFILE(),
2189 lp_servicename(talloc_tos(), snum));
2194 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2196 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2201 if ( (ret = smbrun(command, NULL)) == 0 ) {
2202 /* Tell everyone we updated smb.conf. */
2203 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2210 /********* END SeDiskOperatorPrivilege BLOCK *********/
2212 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2215 return WERR_ACCESS_DENIED;
2217 /* Delete the SD in the database. */
2218 delete_share_security(lp_servicename(talloc_tos(), params->service));
2220 lp_killservice(params->service);
2225 /*******************************************************************
2226 _srvsvc_NetShareDelSticky
2227 ********************************************************************/
2229 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2230 struct srvsvc_NetShareDelSticky *r)
2232 struct srvsvc_NetShareDel q;
2234 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2236 q.in.server_unc = r->in.server_unc;
2237 q.in.share_name = r->in.share_name;
2238 q.in.reserved = r->in.reserved;
2240 return _srvsvc_NetShareDel(p, &q);
2243 /*******************************************************************
2244 _srvsvc_NetRemoteTOD
2245 ********************************************************************/
2247 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2248 struct srvsvc_NetRemoteTOD *r)
2250 struct srvsvc_NetRemoteTODInfo *tod;
2252 time_t unixdate = time(NULL);
2254 /* We do this call first as if we do it *after* the gmtime call
2255 it overwrites the pointed-to values. JRA */
2257 uint32 zone = get_time_zone(unixdate)/60;
2259 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2261 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2266 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2268 t = gmtime(&unixdate);
2271 tod->elapsed = unixdate;
2273 tod->hours = t->tm_hour;
2274 tod->mins = t->tm_min;
2275 tod->secs = t->tm_sec;
2277 tod->timezone = zone;
2278 tod->tinterval = 10000;
2279 tod->day = t->tm_mday;
2280 tod->month = t->tm_mon + 1;
2281 tod->year = 1900+t->tm_year;
2282 tod->weekday = t->tm_wday;
2284 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2289 /***********************************************************************************
2290 _srvsvc_NetGetFileSecurity
2291 Win9x NT tools get security descriptor.
2292 ***********************************************************************************/
2294 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2295 struct srvsvc_NetGetFileSecurity *r)
2297 struct smb_filename *smb_fname = NULL;
2299 char *servicename = NULL;
2303 connection_struct *conn = NULL;
2304 struct sec_desc_buf *sd_buf = NULL;
2305 files_struct *fsp = NULL;
2307 char *oldcwd = NULL;
2312 werr = WERR_NET_NAME_NOT_FOUND;
2315 snum = find_service(talloc_tos(), r->in.share, &servicename);
2321 DEBUG(10, ("Could not find service %s\n", servicename));
2322 werr = WERR_NET_NAME_NOT_FOUND;
2326 nt_status = create_conn_struct_cwd(talloc_tos(),
2327 server_event_context(),
2328 server_messaging_context(),
2330 snum, lp_path(talloc_tos(), snum),
2331 p->session_info, &oldcwd);
2332 if (!NT_STATUS_IS_OK(nt_status)) {
2333 DEBUG(10, ("create_conn_struct failed: %s\n",
2334 nt_errstr(nt_status)));
2335 werr = ntstatus_to_werror(nt_status);
2339 nt_status = filename_convert(talloc_tos(),
2346 if (!NT_STATUS_IS_OK(nt_status)) {
2347 werr = ntstatus_to_werror(nt_status);
2351 nt_status = SMB_VFS_CREATE_FILE(
2354 0, /* root_dir_fid */
2355 smb_fname, /* fname */
2356 FILE_READ_ATTRIBUTES, /* access_mask */
2357 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2358 FILE_OPEN, /* create_disposition*/
2359 0, /* create_options */
2360 0, /* file_attributes */
2361 INTERNAL_OPEN_ONLY, /* oplock_request */
2363 0, /* allocation_size */
2364 0, /* private_flags */
2370 if (!NT_STATUS_IS_OK(nt_status)) {
2371 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2372 smb_fname_str_dbg(smb_fname)));
2373 werr = ntstatus_to_werror(nt_status);
2377 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2383 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2386 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2388 if (!NT_STATUS_IS_OK(nt_status)) {
2389 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2390 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2391 werr = ntstatus_to_werror(nt_status);
2392 TALLOC_FREE(sd_buf);
2396 if (sd_buf->sd->dacl) {
2397 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2400 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2402 sd_buf->sd_size = sd_size;
2404 *r->out.sd_buf = sd_buf;
2406 close_file(NULL, fsp, NORMAL_CLOSE);
2407 vfs_ChDir(conn, oldcwd);
2408 SMB_VFS_DISCONNECT(conn);
2416 close_file(NULL, fsp, NORMAL_CLOSE);
2420 vfs_ChDir(conn, oldcwd);
2424 SMB_VFS_DISCONNECT(conn);
2430 TALLOC_FREE(smb_fname);
2435 /***********************************************************************************
2436 _srvsvc_NetSetFileSecurity
2437 Win9x NT tools set security descriptor.
2438 ***********************************************************************************/
2440 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2441 struct srvsvc_NetSetFileSecurity *r)
2443 struct smb_filename *smb_fname = NULL;
2444 char *servicename = NULL;
2445 files_struct *fsp = NULL;
2449 connection_struct *conn = NULL;
2451 char *oldcwd = NULL;
2452 struct security_descriptor *psd = NULL;
2453 uint32_t security_info_sent = 0;
2458 werr = WERR_NET_NAME_NOT_FOUND;
2462 snum = find_service(talloc_tos(), r->in.share, &servicename);
2469 DEBUG(10, ("Could not find service %s\n", servicename));
2470 werr = WERR_NET_NAME_NOT_FOUND;
2474 nt_status = create_conn_struct_cwd(talloc_tos(),
2475 server_event_context(),
2476 server_messaging_context(),
2478 snum, lp_path(talloc_tos(), snum),
2479 p->session_info, &oldcwd);
2480 if (!NT_STATUS_IS_OK(nt_status)) {
2481 DEBUG(10, ("create_conn_struct failed: %s\n",
2482 nt_errstr(nt_status)));
2483 werr = ntstatus_to_werror(nt_status);
2487 nt_status = filename_convert(talloc_tos(),
2494 if (!NT_STATUS_IS_OK(nt_status)) {
2495 werr = ntstatus_to_werror(nt_status);
2499 nt_status = SMB_VFS_CREATE_FILE(
2502 0, /* root_dir_fid */
2503 smb_fname, /* fname */
2504 FILE_WRITE_ATTRIBUTES, /* access_mask */
2505 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2506 FILE_OPEN, /* create_disposition*/
2507 0, /* create_options */
2508 0, /* file_attributes */
2509 INTERNAL_OPEN_ONLY, /* oplock_request */
2511 0, /* allocation_size */
2512 0, /* private_flags */
2518 if (!NT_STATUS_IS_OK(nt_status)) {
2519 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2520 smb_fname_str_dbg(smb_fname)));
2521 werr = ntstatus_to_werror(nt_status);
2525 psd = r->in.sd_buf->sd;
2526 security_info_sent = r->in.securityinformation;
2528 nt_status = set_sd(fsp, psd, security_info_sent);
2530 if (!NT_STATUS_IS_OK(nt_status) ) {
2531 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2532 "on file %s\n", r->in.share));
2533 werr = WERR_ACCESS_DENIED;
2537 close_file(NULL, fsp, NORMAL_CLOSE);
2538 vfs_ChDir(conn, oldcwd);
2539 SMB_VFS_DISCONNECT(conn);
2547 close_file(NULL, fsp, NORMAL_CLOSE);
2551 vfs_ChDir(conn, oldcwd);
2555 SMB_VFS_DISCONNECT(conn);
2560 TALLOC_FREE(smb_fname);
2565 /***********************************************************************************
2566 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2567 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2568 These disks would the disks listed by this function.
2569 Users could then create shares relative to these disks. Watch out for moving these disks around.
2570 "Nigel Williams" <nigel@veritas.com>.
2571 ***********************************************************************************/
2573 static const char *server_disks[] = {"C:"};
2575 static uint32 get_server_disk_count(void)
2577 return sizeof(server_disks)/sizeof(server_disks[0]);
2580 static uint32 init_server_disk_enum(uint32 *resume)
2582 uint32 server_disk_count = get_server_disk_count();
2584 /*resume can be an offset into the list for now*/
2586 if(*resume & 0x80000000)
2589 if(*resume > server_disk_count)
2590 *resume = server_disk_count;
2592 return server_disk_count - *resume;
2595 static const char *next_server_disk_enum(uint32 *resume)
2599 if(init_server_disk_enum(resume) == 0)
2602 disk = server_disks[*resume];
2606 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2611 /********************************************************************
2613 ********************************************************************/
2615 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2616 struct srvsvc_NetDiskEnum *r)
2619 const char *disk_name;
2620 TALLOC_CTX *ctx = p->mem_ctx;
2622 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2626 *r->out.totalentries = init_server_disk_enum(&resume);
2628 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2629 MAX_SERVER_DISK_ENTRIES);
2630 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2632 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2634 r->out.info->count = 0;
2636 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2638 r->out.info->count++;
2640 /*copy disk name into a unicode string*/
2642 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2643 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2646 /* add a terminating null string. Is this there if there is more data to come? */
2648 r->out.info->count++;
2650 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2651 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2653 if (r->out.resume_handle) {
2654 *r->out.resume_handle = resume;
2660 /********************************************************************
2661 _srvsvc_NetNameValidate
2662 ********************************************************************/
2664 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2665 struct srvsvc_NetNameValidate *r)
2667 switch (r->in.name_type) {
2669 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2670 strlen_m(r->in.name)))
2672 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2674 return WERR_INVALID_NAME;
2679 return WERR_UNKNOWN_LEVEL;
2685 /*******************************************************************
2686 ********************************************************************/
2688 struct enum_file_close_state {
2689 struct srvsvc_NetFileClose *r;
2690 struct messaging_context *msg_ctx;
2693 static void enum_file_close_fn( const struct share_mode_entry *e,
2694 const char *sharepath, const char *fname,
2695 void *private_data )
2697 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2698 struct enum_file_close_state *state =
2699 (struct enum_file_close_state *)private_data;
2700 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2702 if (fid != state->r->in.fid) {
2703 return; /* Not this file. */
2706 if (!process_exists(e->pid) ) {
2710 /* Ok - send the close message. */
2711 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2713 share_mode_str(talloc_tos(), 0, e) ));
2715 share_mode_entry_to_message(msg, e);
2717 state->r->out.result = ntstatus_to_werror(
2718 messaging_send_buf(state->msg_ctx,
2719 e->pid, MSG_SMB_CLOSE_FILE,
2720 (uint8 *)msg, sizeof(msg)));
2723 /********************************************************************
2724 Close a file given a 32-bit file id.
2725 ********************************************************************/
2727 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2728 struct srvsvc_NetFileClose *r)
2730 struct enum_file_close_state state;
2733 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2735 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2737 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2738 return WERR_ACCESS_DENIED;
2741 /* enum_file_close_fn sends the close message to
2742 * the relevant smbd process. */
2744 r->out.result = WERR_BADFILE;
2746 state.msg_ctx = p->msg_ctx;
2747 share_mode_forall(enum_file_close_fn, &state);
2748 return r->out.result;
2751 /********************************************************************
2752 ********************************************************************/
2754 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2755 struct srvsvc_NetCharDevEnum *r)
2757 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2758 return WERR_NOT_SUPPORTED;
2761 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2762 struct srvsvc_NetCharDevGetInfo *r)
2764 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2765 return WERR_NOT_SUPPORTED;
2768 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2769 struct srvsvc_NetCharDevControl *r)
2771 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2772 return WERR_NOT_SUPPORTED;
2775 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2776 struct srvsvc_NetCharDevQEnum *r)
2778 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2779 return WERR_NOT_SUPPORTED;
2782 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2783 struct srvsvc_NetCharDevQGetInfo *r)
2785 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2786 return WERR_NOT_SUPPORTED;
2789 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2790 struct srvsvc_NetCharDevQSetInfo *r)
2792 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2793 return WERR_NOT_SUPPORTED;
2796 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2797 struct srvsvc_NetCharDevQPurge *r)
2799 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2800 return WERR_NOT_SUPPORTED;
2803 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2804 struct srvsvc_NetCharDevQPurgeSelf *r)
2806 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2807 return WERR_NOT_SUPPORTED;
2810 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2811 struct srvsvc_NetFileGetInfo *r)
2813 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2814 return WERR_NOT_SUPPORTED;
2817 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2818 struct srvsvc_NetShareCheck *r)
2820 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2821 return WERR_NOT_SUPPORTED;
2824 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2825 struct srvsvc_NetServerStatisticsGet *r)
2827 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2828 return WERR_NOT_SUPPORTED;
2831 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2832 struct srvsvc_NetTransportAdd *r)
2834 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2835 return WERR_NOT_SUPPORTED;
2838 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2839 struct srvsvc_NetTransportEnum *r)
2841 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2842 return WERR_NOT_SUPPORTED;
2845 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2846 struct srvsvc_NetTransportDel *r)
2848 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2849 return WERR_NOT_SUPPORTED;
2852 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2853 struct srvsvc_NetSetServiceBits *r)
2855 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2856 return WERR_NOT_SUPPORTED;
2859 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2860 struct srvsvc_NetPathType *r)
2862 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2863 return WERR_NOT_SUPPORTED;
2866 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2867 struct srvsvc_NetPathCanonicalize *r)
2869 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2870 return WERR_NOT_SUPPORTED;
2873 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2874 struct srvsvc_NetPathCompare *r)
2876 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2877 return WERR_NOT_SUPPORTED;
2880 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2881 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2883 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2884 return WERR_NOT_SUPPORTED;
2887 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2888 struct srvsvc_NetPRNameCompare *r)
2890 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2891 return WERR_NOT_SUPPORTED;
2894 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2895 struct srvsvc_NetShareDelStart *r)
2897 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2898 return WERR_NOT_SUPPORTED;
2901 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2902 struct srvsvc_NetShareDelCommit *r)
2904 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2905 return WERR_NOT_SUPPORTED;
2908 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2909 struct srvsvc_NetServerTransportAddEx *r)
2911 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2912 return WERR_NOT_SUPPORTED;
2915 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2916 struct srvsvc_NetServerSetServiceBitsEx *r)
2918 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2919 return WERR_NOT_SUPPORTED;
2922 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2923 struct srvsvc_NETRDFSGETVERSION *r)
2925 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2926 return WERR_NOT_SUPPORTED;
2929 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2930 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2932 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2933 return WERR_NOT_SUPPORTED;
2936 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2937 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2939 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2940 return WERR_NOT_SUPPORTED;
2943 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2944 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2946 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2947 return WERR_NOT_SUPPORTED;
2950 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2951 struct srvsvc_NETRDFSSETSERVERINFO *r)
2953 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2954 return WERR_NOT_SUPPORTED;
2957 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2958 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2960 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2961 return WERR_NOT_SUPPORTED;
2964 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2965 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2967 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2968 return WERR_NOT_SUPPORTED;
2971 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2972 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2974 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2975 return WERR_NOT_SUPPORTED;
2978 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2979 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2981 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2982 return WERR_NOT_SUPPORTED;
2985 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2986 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2988 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2989 return WERR_NOT_SUPPORTED;
2992 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2993 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2995 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2996 return WERR_NOT_SUPPORTED;