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 load_usershare_shares(NULL, connections_snum_used);
552 load_registry_shares();
553 num_services = lp_numservices();
556 allowed = talloc_zero_array(ctx, bool, num_services);
557 W_ERROR_HAVE_NO_MEMORY(allowed);
559 /* Count the number of entries. */
560 for (snum = 0; snum < num_services; snum++) {
561 if (lp_browseable(snum) && lp_snum_ok(snum) &&
562 is_enumeration_allowed(p, snum) &&
563 (all_shares || !is_hidden_share(snum)) ) {
564 DEBUG(10, ("counting service %s\n",
565 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
566 allowed[snum] = true;
569 DEBUG(10, ("NOT counting service %s\n",
570 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
574 if (!num_entries || (resume_handle >= num_entries)) {
578 /* Calculate alloc entries. */
579 alloc_entries = num_entries - resume_handle;
580 switch (info_ctr->level) {
582 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
583 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
585 ctr.ctr0->count = alloc_entries;
586 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
587 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
589 for (snum = 0; snum < num_services; snum++) {
591 (resume_handle <= (i + valid_share_count++)) ) {
592 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
599 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
600 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
602 ctr.ctr1->count = alloc_entries;
603 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
604 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
606 for (snum = 0; snum < num_services; snum++) {
608 (resume_handle <= (i + valid_share_count++)) ) {
609 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
616 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
617 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
619 ctr.ctr2->count = alloc_entries;
620 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
621 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
623 for (snum = 0; snum < num_services; snum++) {
625 (resume_handle <= (i + valid_share_count++)) ) {
626 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
630 count_connections_for_all_shares(&ctr);
634 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
635 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
637 ctr.ctr501->count = alloc_entries;
638 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
639 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
641 for (snum = 0; snum < num_services; snum++) {
643 (resume_handle <= (i + valid_share_count++)) ) {
644 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
651 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
652 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
654 ctr.ctr502->count = alloc_entries;
655 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
656 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
658 for (snum = 0; snum < num_services; snum++) {
660 (resume_handle <= (i + valid_share_count++)) ) {
661 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
668 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
669 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
671 ctr.ctr1004->count = alloc_entries;
672 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
673 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
675 for (snum = 0; snum < num_services; snum++) {
677 (resume_handle <= (i + valid_share_count++)) ) {
678 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
685 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
686 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
688 ctr.ctr1005->count = alloc_entries;
689 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
690 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
692 for (snum = 0; snum < num_services; snum++) {
694 (resume_handle <= (i + valid_share_count++)) ) {
695 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
702 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
703 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
705 ctr.ctr1006->count = alloc_entries;
706 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
707 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
709 for (snum = 0; snum < num_services; snum++) {
711 (resume_handle <= (i + valid_share_count++)) ) {
712 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
719 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
720 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
722 ctr.ctr1007->count = alloc_entries;
723 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
724 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
726 for (snum = 0; snum < num_services; snum++) {
728 (resume_handle <= (i + valid_share_count++)) ) {
729 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
736 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
737 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
739 ctr.ctr1501->count = alloc_entries;
740 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
741 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
743 for (snum = 0; snum < num_services; snum++) {
745 (resume_handle <= (i + valid_share_count++)) ) {
746 struct sec_desc_buf *sd_buf = NULL;
747 init_srv_share_info_1501(p, &sd_buf, snum);
748 ctr.ctr1501->array[i++] = *sd_buf;
755 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
757 return WERR_UNKNOWN_LEVEL;
760 *total_entries = alloc_entries;
761 if (resume_handle_p) {
763 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
765 *resume_handle_p = num_entries;
774 /*******************************************************************
775 fill in a sess info level 0 structure.
776 ********************************************************************/
778 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
779 struct srvsvc_NetSessCtr0 *ctr0,
780 uint32_t *resume_handle_p,
781 uint32_t *total_entries)
783 struct sessionid *session_list;
784 uint32_t num_entries = 0;
785 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
786 *total_entries = list_sessions(p->mem_ctx, &session_list);
788 DEBUG(5,("init_srv_sess_info_0\n"));
791 if (resume_handle_p) {
792 *resume_handle_p = 0;
797 for (; resume_handle < *total_entries; resume_handle++) {
799 ctr0->array = talloc_realloc(p->mem_ctx,
801 struct srvsvc_NetSessInfo0,
803 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
805 ctr0->array[num_entries].client =
806 session_list[resume_handle].remote_machine;
811 ctr0->count = num_entries;
813 if (resume_handle_p) {
814 if (*resume_handle_p >= *total_entries) {
815 *resume_handle_p = 0;
817 *resume_handle_p = resume_handle;
824 /***********************************************************************
825 * find out the session on which this file is open and bump up its count
826 **********************************************************************/
828 static void count_sess_files_fn(const struct share_mode_entry *e,
829 const char *sharepath, const char *fname,
832 struct sess_file_info *info = data;
833 uint32_t rh = info->resume_handle;
836 for (i=0; i < info->num_entries; i++) {
837 /* rh+info->num_entries is safe, as we've
839 *total_entries > resume_handle &&
840 info->num_entries = *total_entries - resume_handle;
841 inside init_srv_sess_info_1() below.
843 struct sessionid *sess = &info->session_list[rh + i];
844 if ((e->uid == sess->uid) &&
845 serverid_equal(&e->pid, &sess->pid)) {
847 info->ctr->array[i].num_open++;
853 /*******************************************************************
854 * count the num of open files on all sessions
855 *******************************************************************/
857 static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
858 struct sessionid *session_list,
859 uint32_t resume_handle,
860 uint32_t num_entries)
862 struct sess_file_info s_file_info;
864 s_file_info.ctr = ctr1;
865 s_file_info.session_list = session_list;
866 s_file_info.resume_handle = resume_handle;
867 s_file_info.num_entries = num_entries;
869 share_mode_forall(count_sess_files_fn, &s_file_info);
872 /*******************************************************************
873 fill in a sess info level 1 structure.
874 ********************************************************************/
876 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
877 struct srvsvc_NetSessCtr1 *ctr1,
878 uint32_t *resume_handle_p,
879 uint32_t *total_entries)
881 struct sessionid *session_list;
882 uint32_t num_entries = 0;
883 time_t now = time(NULL);
884 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
889 if (resume_handle_p) {
890 *resume_handle_p = 0;
895 *total_entries = list_sessions(p->mem_ctx, &session_list);
897 if (resume_handle >= *total_entries) {
898 if (resume_handle_p) {
899 *resume_handle_p = 0;
904 /* We know num_entries must be positive, due to
905 the check resume_handle >= *total_entries above. */
907 num_entries = *total_entries - resume_handle;
909 ctr1->array = talloc_zero_array(p->mem_ctx,
910 struct srvsvc_NetSessInfo1,
913 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
915 for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
919 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
920 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
922 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
923 ctr1->array[num_entries].user = session_list[resume_handle].username;
924 ctr1->array[num_entries].num_open = 0;/* computed later */
925 ctr1->array[num_entries].time = connect_time;
926 ctr1->array[num_entries].idle_time = 0;
927 ctr1->array[num_entries].user_flags = guest;
930 ctr1->count = num_entries;
932 /* count open files on all sessions in single tdb traversal */
933 net_count_files_for_all_sess(ctr1, session_list,
934 resume_handle_p ? *resume_handle_p : 0,
937 if (resume_handle_p) {
938 if (*resume_handle_p >= *total_entries) {
939 *resume_handle_p = 0;
941 *resume_handle_p = resume_handle;
948 /*******************************************************************
949 find the share connection on which this open exists.
950 ********************************************************************/
952 static void share_file_fn(const struct share_mode_entry *e,
953 const char *sharepath, const char *fname,
956 struct share_file_stat *sfs = data;
958 uint32_t offset = sfs->total_entries - sfs->resp_entries;
960 if (strequal(sharepath, sfs->in_sharepath)) {
961 for (i=0; i < sfs->resp_entries; i++) {
962 if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) {
963 sfs->netconn_arr[i].num_open ++;
970 /*******************************************************************
971 count number of open files on given share connections.
972 ********************************************************************/
974 static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
975 struct server_id *svrid_arr, char *sharepath,
976 uint32_t resp_entries, uint32_t total_entries)
978 struct share_file_stat sfs;
980 sfs.netconn_arr = arr;
981 sfs.svrid_arr = svrid_arr;
982 sfs.in_sharepath = sharepath;
983 sfs.resp_entries = resp_entries;
984 sfs.total_entries = total_entries;
986 share_mode_forall(share_file_fn, &sfs);
989 /****************************************************************************
990 process an entry from the connection db.
991 ****************************************************************************/
993 static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
996 struct share_conn_stat *scs = data;
998 if (!process_exists(tcon->server_id)) {
1002 if (strequal(tcon->share_name, scs->sharename)) {
1003 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
1006 if (!scs->svrid_arr) {
1010 scs->svrid_arr[scs->count] = tcon->server_id;
1017 /****************************************************************************
1018 Count the connections to a share. Build an array of serverid's owning these
1020 ****************************************************************************/
1022 static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
1023 struct server_id **arr)
1025 struct share_conn_stat scs;
1029 scs.sharename = sharename;
1030 scs.svrid_arr = NULL;
1033 status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 DEBUG(0,("count_share_conns: traverse of "
1037 "smbXsrv_tcon_global.tdb failed - %s\n",
1038 nt_errstr(status)));
1042 *arr = scs.svrid_arr;
1046 /*******************************************************************
1047 fill in a conn info level 0 structure.
1048 ********************************************************************/
1050 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
1051 uint32_t *resume_handle_p,
1052 uint32_t *total_entries)
1054 uint32_t num_entries = 0;
1055 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1057 DEBUG(5,("init_srv_conn_info_0\n"));
1060 if (resume_handle_p) {
1061 *resume_handle_p = 0;
1070 for (; resume_handle < *total_entries; resume_handle++) {
1072 ctr0->array = talloc_realloc(talloc_tos(),
1074 struct srvsvc_NetConnInfo0,
1080 ctr0->array[num_entries].conn_id = *total_entries;
1082 /* move on to creating next connection */
1086 ctr0->count = num_entries;
1087 *total_entries = num_entries;
1089 if (resume_handle_p) {
1090 if (*resume_handle_p >= *total_entries) {
1091 *resume_handle_p = 0;
1093 *resume_handle_p = resume_handle;
1100 /*******************************************************************
1101 fill in a conn info level 1 structure.
1102 ********************************************************************/
1104 static WERROR init_srv_conn_info_1(const char *name,
1105 struct srvsvc_NetConnCtr1 *ctr1,
1106 uint32_t *resume_handle_p,
1107 uint32_t *total_entries)
1109 uint32_t num_entries = 0, snum = 0;
1110 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1111 char *share_name = NULL;
1112 struct server_id *svrid_arr = NULL;
1114 DEBUG(5,("init_srv_conn_info_1\n"));
1117 if (resume_handle_p) {
1118 *resume_handle_p = 0;
1123 /* check if this is a server name or a share name */
1124 if (name && (strlen(name) > 2) && (name[0] == '\\') &&
1125 (name[1] == '\\')) {
1127 /* 'name' is a server name - this part is unimplemented */
1130 /* 'name' is a share name */
1131 snum = find_service(talloc_tos(), name, &share_name);
1138 return WERR_INVALID_NAME;
1142 * count the num of connections to this share. Also,
1143 * build a list of serverid's that own these
1144 * connections. The serverid list is used later to
1145 * identify the share connection on which an open exists.
1148 *total_entries = count_share_conns(talloc_tos(),
1153 if (resume_handle >= *total_entries) {
1154 if (resume_handle_p) {
1155 *resume_handle_p = 0;
1161 * We know num_entries must be positive, due to
1162 * the check resume_handle >= *total_entries above.
1165 num_entries = *total_entries - resume_handle;
1169 ctr1->array = talloc_zero_array(talloc_tos(),
1170 struct srvsvc_NetConnInfo1,
1173 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1175 for (num_entries = 0; resume_handle < *total_entries;
1176 num_entries++, resume_handle++) {
1178 ctr1->array[num_entries].conn_id = *total_entries;
1179 ctr1->array[num_entries].conn_type = 0x3;
1182 * if these are connections to a share, we are going to
1183 * compute the opens on them later. If it's for the server,
1184 * it's unimplemented.
1188 ctr1->array[num_entries].num_open = 1;
1191 ctr1->array[num_entries].num_users = 1;
1192 ctr1->array[num_entries].conn_time = 3;
1193 ctr1->array[num_entries].user = "dummy_user";
1194 ctr1->array[num_entries].share = "IPC$";
1197 /* now compute open files on the share connections */
1202 * the locking tdb, which has the open files information,
1203 * does not store share name or share (service) number, but
1204 * just the share path. So, we can compute open files only
1205 * on the share path. If more than one shares are defined
1206 * on a share path, open files on all of them are included
1209 * To have the correct behavior in case multiple shares
1210 * are defined on the same path, changes to tdb records
1211 * would be required. That would be lot more effort, so
1212 * this seems a good stopgap fix.
1215 count_share_opens(ctr1->array, svrid_arr,
1216 lp_path(talloc_tos(), snum),
1217 num_entries, *total_entries);
1221 ctr1->count = num_entries;
1222 *total_entries = num_entries;
1224 if (resume_handle_p) {
1225 *resume_handle_p = resume_handle;
1231 /*******************************************************************
1233 *******************************************************************/
1235 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1236 struct srvsvc_NetFileEnum *r)
1238 TALLOC_CTX *ctx = NULL;
1239 struct srvsvc_NetFileCtr3 *ctr3;
1240 uint32_t resume_hnd = 0;
1243 switch (r->in.info_ctr->level) {
1247 return WERR_UNKNOWN_LEVEL;
1250 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1251 p->session_info->security_token)) {
1252 DEBUG(1, ("Enumerating files only allowed for "
1253 "administrators\n"));
1254 return WERR_ACCESS_DENIED;
1258 ctr3 = r->in.info_ctr->ctr.ctr3;
1260 werr = WERR_INVALID_PARAM;
1264 /* TODO -- Windows enumerates
1266 (c) open directories and files */
1268 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1269 if (!W_ERROR_IS_OK(werr)) {
1273 *r->out.totalentries = ctr3->count;
1274 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1275 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1283 /*******************************************************************
1284 _srvsvc_NetSrvGetInfo
1285 ********************************************************************/
1287 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1288 struct srvsvc_NetSrvGetInfo *r)
1290 WERROR status = WERR_OK;
1292 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1294 if (!pipe_access_check(p)) {
1295 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1296 return WERR_ACCESS_DENIED;
1299 switch (r->in.level) {
1301 /* Technically level 102 should only be available to
1302 Administrators but there isn't anything super-secret
1303 here, as most of it is made up. */
1306 struct srvsvc_NetSrvInfo102 *info102;
1308 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1313 info102->platform_id = PLATFORM_ID_NT;
1314 info102->server_name = lp_netbios_name();
1315 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1316 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1317 info102->server_type = lp_default_server_announce();
1318 info102->comment = string_truncate(lp_server_string(talloc_tos()),
1319 MAX_SERVER_STRING_LENGTH);
1320 info102->users = 0xffffffff;
1321 info102->disc = 0xf;
1322 info102->hidden = 0;
1323 info102->announce = 240;
1324 info102->anndelta = 3000;
1325 info102->licenses = 100000;
1326 info102->userpath = "C:\\";
1328 r->out.info->info102 = info102;
1332 struct srvsvc_NetSrvInfo101 *info101;
1334 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1339 info101->platform_id = PLATFORM_ID_NT;
1340 info101->server_name = lp_netbios_name();
1341 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1342 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1343 info101->server_type = lp_default_server_announce();
1344 info101->comment = string_truncate(lp_server_string(talloc_tos()),
1345 MAX_SERVER_STRING_LENGTH);
1347 r->out.info->info101 = info101;
1351 struct srvsvc_NetSrvInfo100 *info100;
1353 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1358 info100->platform_id = PLATFORM_ID_NT;
1359 info100->server_name = lp_netbios_name();
1361 r->out.info->info100 = info100;
1366 status = WERR_UNKNOWN_LEVEL;
1370 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1375 /*******************************************************************
1376 _srvsvc_NetSrvSetInfo
1377 ********************************************************************/
1379 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1380 struct srvsvc_NetSrvSetInfo *r)
1382 WERROR status = WERR_OK;
1384 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1386 /* Set up the net server set info structure. */
1388 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1393 /*******************************************************************
1395 ********************************************************************/
1397 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1398 struct srvsvc_NetConnEnum *r)
1402 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1404 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1405 p->session_info->security_token)) {
1406 DEBUG(1, ("Enumerating connections only allowed for "
1407 "administrators\n"));
1408 return WERR_ACCESS_DENIED;
1411 switch (r->in.info_ctr->level) {
1413 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1414 r->in.resume_handle,
1415 r->out.totalentries);
1418 werr = init_srv_conn_info_1(r->in.path,
1419 r->in.info_ctr->ctr.ctr1,
1420 r->in.resume_handle,
1421 r->out.totalentries);
1424 return WERR_UNKNOWN_LEVEL;
1427 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1432 /*******************************************************************
1434 ********************************************************************/
1436 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1437 struct srvsvc_NetSessEnum *r)
1441 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1443 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1444 p->session_info->security_token)) {
1445 DEBUG(1, ("Enumerating sessions only allowed for "
1446 "administrators\n"));
1447 return WERR_ACCESS_DENIED;
1450 switch (r->in.info_ctr->level) {
1452 werr = init_srv_sess_info_0(p,
1453 r->in.info_ctr->ctr.ctr0,
1454 r->in.resume_handle,
1455 r->out.totalentries);
1458 werr = init_srv_sess_info_1(p,
1459 r->in.info_ctr->ctr.ctr1,
1460 r->in.resume_handle,
1461 r->out.totalentries);
1464 return WERR_UNKNOWN_LEVEL;
1467 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1472 /*******************************************************************
1474 ********************************************************************/
1476 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1477 struct srvsvc_NetSessDel *r)
1479 struct sessionid *session_list;
1480 int num_sessions, snum;
1481 const char *username;
1482 const char *machine;
1483 bool not_root = False;
1486 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1488 werr = WERR_ACCESS_DENIED;
1490 /* fail out now if you are not root or not a domain admin */
1492 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1493 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1494 DOMAIN_RID_ADMINS))) {
1499 username = r->in.user;
1500 machine = r->in.client;
1502 /* strip leading backslashes if any */
1503 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1507 num_sessions = find_sessions(p->mem_ctx, username, machine,
1510 for (snum = 0; snum < num_sessions; snum++) {
1514 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1519 ntstat = messaging_send(p->msg_ctx,
1520 session_list[snum].pid,
1521 MSG_SHUTDOWN, &data_blob_null);
1523 if (NT_STATUS_IS_OK(ntstat))
1530 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1537 /*******************************************************************
1538 _srvsvc_NetShareEnumAll
1539 ********************************************************************/
1541 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1542 struct srvsvc_NetShareEnumAll *r)
1546 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1548 if (!pipe_access_check(p)) {
1549 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1550 return WERR_ACCESS_DENIED;
1553 /* Create the list of shares for the response. */
1554 werr = init_srv_share_info_ctr(p,
1556 r->in.resume_handle,
1557 r->out.totalentries,
1560 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1565 /*******************************************************************
1566 _srvsvc_NetShareEnum
1567 ********************************************************************/
1569 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1570 struct srvsvc_NetShareEnum *r)
1574 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1576 if (!pipe_access_check(p)) {
1577 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1578 return WERR_ACCESS_DENIED;
1581 /* Create the list of shares for the response. */
1582 werr = init_srv_share_info_ctr(p,
1584 r->in.resume_handle,
1585 r->out.totalentries,
1588 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1593 /*******************************************************************
1594 _srvsvc_NetShareGetInfo
1595 ********************************************************************/
1597 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1598 struct srvsvc_NetShareGetInfo *r)
1600 WERROR status = WERR_OK;
1601 char *share_name = NULL;
1603 union srvsvc_NetShareInfo *info = r->out.info;
1605 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1607 if (!r->in.share_name) {
1608 return WERR_INVALID_NAME;
1611 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1616 return WERR_INVALID_NAME;
1619 switch (r->in.level) {
1621 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1622 W_ERROR_HAVE_NO_MEMORY(info->info0);
1623 init_srv_share_info_0(p, info->info0, snum);
1626 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1627 W_ERROR_HAVE_NO_MEMORY(info->info1);
1628 init_srv_share_info_1(p, info->info1, snum);
1631 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1632 W_ERROR_HAVE_NO_MEMORY(info->info2);
1633 init_srv_share_info_2(p, info->info2, snum);
1634 info->info2->current_users =
1635 count_current_connections(info->info2->name, false);
1638 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1639 W_ERROR_HAVE_NO_MEMORY(info->info501);
1640 init_srv_share_info_501(p, info->info501, snum);
1643 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1644 W_ERROR_HAVE_NO_MEMORY(info->info502);
1645 init_srv_share_info_502(p, info->info502, snum);
1648 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1649 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1650 init_srv_share_info_1004(p, info->info1004, snum);
1653 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1654 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1655 init_srv_share_info_1005(p, info->info1005, snum);
1658 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1659 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1660 init_srv_share_info_1006(p, info->info1006, snum);
1663 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1664 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1665 init_srv_share_info_1007(p, info->info1007, snum);
1668 init_srv_share_info_1501(p, &info->info1501, snum);
1671 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1673 status = WERR_UNKNOWN_LEVEL;
1677 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1682 /*******************************************************************
1683 _srvsvc_NetShareSetInfo. Modify share details.
1684 ********************************************************************/
1686 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1687 struct srvsvc_NetShareSetInfo *r)
1689 char *command = NULL;
1690 char *share_name = NULL;
1691 char *comment = NULL;
1692 const char *pathname = NULL;
1697 struct security_descriptor *psd = NULL;
1698 bool is_disk_op = False;
1699 const char *csc_policy = NULL;
1700 bool csc_policy_changed = false;
1701 const char *csc_policies[] = {"manual", "documents", "programs",
1703 uint32_t client_csc_policy;
1704 int max_connections = 0;
1705 TALLOC_CTX *ctx = p->mem_ctx;
1706 union srvsvc_NetShareInfo *info = r->in.info;
1708 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1710 if (!r->in.share_name) {
1711 return WERR_INVALID_NAME;
1714 if (r->out.parm_error) {
1715 *r->out.parm_error = 0;
1718 if ( strequal(r->in.share_name,"IPC$")
1719 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1720 || strequal(r->in.share_name,"global") )
1722 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1723 "modified by a remote user.\n",
1724 r->in.share_name ));
1725 return WERR_ACCESS_DENIED;
1728 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1733 /* Does this share exist ? */
1735 return WERR_NET_NAME_NOT_FOUND;
1737 /* No change to printer shares. */
1738 if (lp_printable(snum))
1739 return WERR_ACCESS_DENIED;
1741 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1743 /* fail out now if you are not root and not a disk op */
1745 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1746 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1747 "SeDiskOperatorPrivilege privilege needed to modify "
1749 (unsigned int)p->session_info->unix_token->uid,
1751 return WERR_ACCESS_DENIED;
1754 max_connections = lp_max_connections(snum);
1755 csc_policy = csc_policies[lp_csc_policy(snum)];
1757 switch (r->in.level) {
1759 pathname = lp_path(ctx, snum);
1760 comment = talloc_strdup(ctx, info->info1->comment);
1761 type = info->info1->type;
1765 comment = talloc_strdup(ctx, info->info2->comment);
1766 pathname = info->info2->path;
1767 type = info->info2->type;
1768 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1769 0 : info->info2->max_users;
1773 /* not supported on set but here for completeness */
1775 comment = talloc_strdup(ctx, info->info501->comment);
1776 type = info->info501->type;
1781 comment = talloc_strdup(ctx, info->info502->comment);
1782 pathname = info->info502->path;
1783 type = info->info502->type;
1784 psd = info->info502->sd_buf.sd;
1785 map_generic_share_sd_bits(psd);
1788 pathname = lp_path(ctx, snum);
1789 comment = talloc_strdup(ctx, info->info1004->comment);
1790 type = STYPE_DISKTREE;
1793 /* XP re-sets the csc policy even if it wasn't changed by the
1794 user, so we must compare it to see if it's what is set in
1795 smb.conf, so that we can contine other ops like setting
1797 client_csc_policy = (info->info1005->dfs_flags &
1798 SHARE_1005_CSC_POLICY_MASK) >>
1799 SHARE_1005_CSC_POLICY_SHIFT;
1801 if (client_csc_policy == lp_csc_policy(snum))
1804 csc_policy = csc_policies[client_csc_policy];
1805 csc_policy_changed = true;
1808 pathname = lp_path(ctx, snum);
1809 comment = lp_comment(ctx, snum);
1810 type = STYPE_DISKTREE;
1814 return WERR_ACCESS_DENIED;
1816 pathname = lp_path(ctx, snum);
1817 comment = lp_comment(ctx, snum);
1818 psd = info->info1501->sd;
1819 map_generic_share_sd_bits(psd);
1820 type = STYPE_DISKTREE;
1823 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1825 return WERR_UNKNOWN_LEVEL;
1828 /* We can only modify disk shares. */
1829 if (type != STYPE_DISKTREE) {
1830 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1833 return WERR_ACCESS_DENIED;
1836 if (comment == NULL) {
1840 /* Check if the pathname is valid. */
1841 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1842 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1844 return WERR_OBJECT_PATH_INVALID;
1847 /* Ensure share name, pathname and comment don't contain '"' characters. */
1848 string_replace(share_name, '"', ' ');
1849 string_replace(path, '"', ' ');
1850 string_replace(comment, '"', ' ');
1852 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1853 lp_change_share_command(talloc_tos()) ? lp_change_share_command(talloc_tos()) : "NULL" ));
1855 /* Only call modify function if something changed. */
1857 if (strcmp(path, lp_path(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1858 || (lp_max_connections(snum) != max_connections)
1859 || csc_policy_changed) {
1861 if (!lp_change_share_command(talloc_tos()) || !*lp_change_share_command(talloc_tos())) {
1862 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1863 return WERR_ACCESS_DENIED;
1866 command = talloc_asprintf(p->mem_ctx,
1867 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
1868 lp_change_share_command(talloc_tos()),
1869 get_dyn_CONFIGFILE(),
1872 comment ? comment : "",
1879 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1881 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1886 if ( (ret = smbrun(command, NULL)) == 0 ) {
1887 /* Tell everyone we updated smb.conf. */
1888 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1895 /********* END SeDiskOperatorPrivilege BLOCK *********/
1897 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1900 TALLOC_FREE(command);
1903 return WERR_ACCESS_DENIED;
1905 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1909 /* Replace SD if changed. */
1911 struct security_descriptor *old_sd;
1914 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1916 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1917 if (!set_share_security(share_name, psd))
1918 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1923 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1928 /*******************************************************************
1929 _srvsvc_NetShareAdd.
1930 Call 'add_share_command "sharename" "pathname"
1931 "comment" "max connections = "
1932 ********************************************************************/
1934 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1935 struct srvsvc_NetShareAdd *r)
1937 char *command = NULL;
1938 char *share_name_in = NULL;
1939 char *share_name = NULL;
1940 char *comment = NULL;
1941 char *pathname = NULL;
1946 struct security_descriptor *psd = NULL;
1948 int max_connections = 0;
1949 TALLOC_CTX *ctx = p->mem_ctx;
1951 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1953 if (r->out.parm_error) {
1954 *r->out.parm_error = 0;
1957 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1959 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1960 return WERR_ACCESS_DENIED;
1962 if (!lp_add_share_command(talloc_tos()) || !*lp_add_share_command(talloc_tos())) {
1963 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1964 return WERR_ACCESS_DENIED;
1967 switch (r->in.level) {
1969 /* No path. Not enough info in a level 0 to do anything. */
1970 return WERR_ACCESS_DENIED;
1972 /* Not enough info in a level 1 to do anything. */
1973 return WERR_ACCESS_DENIED;
1975 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1976 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1977 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1978 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1979 0 : r->in.info->info2->max_users;
1980 type = r->in.info->info2->type;
1983 /* No path. Not enough info in a level 501 to do anything. */
1984 return WERR_ACCESS_DENIED;
1986 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1987 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1988 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1989 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1990 0 : r->in.info->info502->max_users;
1991 type = r->in.info->info502->type;
1992 psd = r->in.info->info502->sd_buf.sd;
1993 map_generic_share_sd_bits(psd);
1996 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
2002 return WERR_ACCESS_DENIED;
2004 /* DFS only level. */
2005 return WERR_ACCESS_DENIED;
2007 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
2009 return WERR_UNKNOWN_LEVEL;
2012 /* check for invalid share names */
2014 if (!share_name_in || !validate_net_name(share_name_in,
2015 INVALID_SHARENAME_CHARS,
2016 strlen(share_name_in))) {
2017 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
2018 share_name_in ? share_name_in : ""));
2019 return WERR_INVALID_NAME;
2022 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
2023 || (lp_enable_asu_support() &&
2024 strequal(share_name_in,"ADMIN$"))) {
2025 return WERR_ACCESS_DENIED;
2028 snum = find_service(ctx, share_name_in, &share_name);
2033 /* Share already exists. */
2035 return WERR_FILE_EXISTS;
2038 /* We can only add disk shares. */
2039 if (type != STYPE_DISKTREE) {
2040 return WERR_ACCESS_DENIED;
2043 /* Check if the pathname is valid. */
2044 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
2045 return WERR_OBJECT_PATH_INVALID;
2048 /* Ensure share name, pathname and comment don't contain '"' characters. */
2049 string_replace(share_name_in, '"', ' ');
2050 string_replace(share_name, '"', ' ');
2051 string_replace(path, '"', ' ');
2053 string_replace(comment, '"', ' ');
2056 command = talloc_asprintf(ctx,
2057 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
2058 lp_add_share_command(talloc_tos()),
2059 get_dyn_CONFIGFILE(),
2062 comment ? comment : "",
2068 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
2070 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2075 /* FIXME: use libnetconf here - gd */
2077 if ( (ret = smbrun(command, NULL)) == 0 ) {
2078 /* Tell everyone we updated smb.conf. */
2079 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2086 /********* END SeDiskOperatorPrivilege BLOCK *********/
2088 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
2091 TALLOC_FREE(command);
2094 return WERR_ACCESS_DENIED;
2097 /* Note we use share_name here, not share_name_in as
2098 we need a canonicalized name for setting security. */
2099 if (!set_share_security(share_name, psd)) {
2100 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
2106 * We don't call reload_services() here, the message will
2107 * cause this to be done before the next packet is read
2108 * from the client. JRA.
2111 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
2116 /*******************************************************************
2118 Call "delete share command" with the share name as
2120 ********************************************************************/
2122 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
2123 struct srvsvc_NetShareDel *r)
2125 char *command = NULL;
2126 char *share_name = NULL;
2130 struct share_params *params;
2131 TALLOC_CTX *ctx = p->mem_ctx;
2133 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
2135 if (!r->in.share_name) {
2136 return WERR_NET_NAME_NOT_FOUND;
2139 if ( strequal(r->in.share_name,"IPC$")
2140 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
2141 || strequal(r->in.share_name,"global") )
2143 return WERR_ACCESS_DENIED;
2146 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
2152 return WERR_NO_SUCH_SHARE;
2155 if (!(params = get_share_params(p->mem_ctx, share_name))) {
2156 return WERR_NO_SUCH_SHARE;
2159 /* No change to printer shares. */
2160 if (lp_printable(snum))
2161 return WERR_ACCESS_DENIED;
2163 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2165 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
2166 return WERR_ACCESS_DENIED;
2168 if (!lp_delete_share_command(talloc_tos()) || !*lp_delete_share_command(talloc_tos())) {
2169 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
2170 return WERR_ACCESS_DENIED;
2173 command = talloc_asprintf(ctx,
2175 lp_delete_share_command(talloc_tos()),
2176 get_dyn_CONFIGFILE(),
2177 lp_servicename(talloc_tos(), snum));
2182 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2184 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2189 if ( (ret = smbrun(command, NULL)) == 0 ) {
2190 /* Tell everyone we updated smb.conf. */
2191 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2198 /********* END SeDiskOperatorPrivilege BLOCK *********/
2200 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2203 return WERR_ACCESS_DENIED;
2205 /* Delete the SD in the database. */
2206 delete_share_security(lp_servicename(talloc_tos(), params->service));
2208 lp_killservice(params->service);
2213 /*******************************************************************
2214 _srvsvc_NetShareDelSticky
2215 ********************************************************************/
2217 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2218 struct srvsvc_NetShareDelSticky *r)
2220 struct srvsvc_NetShareDel q;
2222 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2224 q.in.server_unc = r->in.server_unc;
2225 q.in.share_name = r->in.share_name;
2226 q.in.reserved = r->in.reserved;
2228 return _srvsvc_NetShareDel(p, &q);
2231 /*******************************************************************
2232 _srvsvc_NetRemoteTOD
2233 ********************************************************************/
2235 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2236 struct srvsvc_NetRemoteTOD *r)
2238 struct srvsvc_NetRemoteTODInfo *tod;
2240 time_t unixdate = time(NULL);
2242 /* We do this call first as if we do it *after* the gmtime call
2243 it overwrites the pointed-to values. JRA */
2245 uint32 zone = get_time_zone(unixdate)/60;
2247 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2249 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2254 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2256 t = gmtime(&unixdate);
2259 tod->elapsed = unixdate;
2261 tod->hours = t->tm_hour;
2262 tod->mins = t->tm_min;
2263 tod->secs = t->tm_sec;
2265 tod->timezone = zone;
2266 tod->tinterval = 10000;
2267 tod->day = t->tm_mday;
2268 tod->month = t->tm_mon + 1;
2269 tod->year = 1900+t->tm_year;
2270 tod->weekday = t->tm_wday;
2272 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2277 /***********************************************************************************
2278 _srvsvc_NetGetFileSecurity
2279 Win9x NT tools get security descriptor.
2280 ***********************************************************************************/
2282 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2283 struct srvsvc_NetGetFileSecurity *r)
2285 struct smb_filename *smb_fname = NULL;
2287 char *servicename = NULL;
2291 connection_struct *conn = NULL;
2292 struct sec_desc_buf *sd_buf = NULL;
2293 files_struct *fsp = NULL;
2295 char *oldcwd = NULL;
2300 werr = WERR_NET_NAME_NOT_FOUND;
2303 snum = find_service(talloc_tos(), r->in.share, &servicename);
2309 DEBUG(10, ("Could not find service %s\n", servicename));
2310 werr = WERR_NET_NAME_NOT_FOUND;
2314 nt_status = create_conn_struct_cwd(talloc_tos(),
2315 server_event_context(),
2316 server_messaging_context(),
2318 snum, lp_path(talloc_tos(), snum),
2319 p->session_info, &oldcwd);
2320 if (!NT_STATUS_IS_OK(nt_status)) {
2321 DEBUG(10, ("create_conn_struct failed: %s\n",
2322 nt_errstr(nt_status)));
2323 werr = ntstatus_to_werror(nt_status);
2327 nt_status = filename_convert(talloc_tos(),
2334 if (!NT_STATUS_IS_OK(nt_status)) {
2335 werr = ntstatus_to_werror(nt_status);
2339 nt_status = SMB_VFS_CREATE_FILE(
2342 0, /* root_dir_fid */
2343 smb_fname, /* fname */
2344 FILE_READ_ATTRIBUTES, /* access_mask */
2345 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2346 FILE_OPEN, /* create_disposition*/
2347 0, /* create_options */
2348 0, /* file_attributes */
2349 INTERNAL_OPEN_ONLY, /* oplock_request */
2350 0, /* allocation_size */
2351 0, /* private_flags */
2357 if (!NT_STATUS_IS_OK(nt_status)) {
2358 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2359 smb_fname_str_dbg(smb_fname)));
2360 werr = ntstatus_to_werror(nt_status);
2364 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2370 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2373 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2375 if (!NT_STATUS_IS_OK(nt_status)) {
2376 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2377 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2378 werr = ntstatus_to_werror(nt_status);
2379 TALLOC_FREE(sd_buf);
2383 if (sd_buf->sd->dacl) {
2384 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2387 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2389 sd_buf->sd_size = sd_size;
2391 *r->out.sd_buf = sd_buf;
2393 close_file(NULL, fsp, NORMAL_CLOSE);
2394 vfs_ChDir(conn, oldcwd);
2395 SMB_VFS_DISCONNECT(conn);
2403 close_file(NULL, fsp, NORMAL_CLOSE);
2407 vfs_ChDir(conn, oldcwd);
2411 SMB_VFS_DISCONNECT(conn);
2417 TALLOC_FREE(smb_fname);
2422 /***********************************************************************************
2423 _srvsvc_NetSetFileSecurity
2424 Win9x NT tools set security descriptor.
2425 ***********************************************************************************/
2427 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2428 struct srvsvc_NetSetFileSecurity *r)
2430 struct smb_filename *smb_fname = NULL;
2431 char *servicename = NULL;
2432 files_struct *fsp = NULL;
2436 connection_struct *conn = NULL;
2438 char *oldcwd = NULL;
2439 struct security_descriptor *psd = NULL;
2440 uint32_t security_info_sent = 0;
2445 werr = WERR_NET_NAME_NOT_FOUND;
2449 snum = find_service(talloc_tos(), r->in.share, &servicename);
2456 DEBUG(10, ("Could not find service %s\n", servicename));
2457 werr = WERR_NET_NAME_NOT_FOUND;
2461 nt_status = create_conn_struct_cwd(talloc_tos(),
2462 server_event_context(),
2463 server_messaging_context(),
2465 snum, lp_path(talloc_tos(), snum),
2466 p->session_info, &oldcwd);
2467 if (!NT_STATUS_IS_OK(nt_status)) {
2468 DEBUG(10, ("create_conn_struct failed: %s\n",
2469 nt_errstr(nt_status)));
2470 werr = ntstatus_to_werror(nt_status);
2474 nt_status = filename_convert(talloc_tos(),
2481 if (!NT_STATUS_IS_OK(nt_status)) {
2482 werr = ntstatus_to_werror(nt_status);
2486 nt_status = SMB_VFS_CREATE_FILE(
2489 0, /* root_dir_fid */
2490 smb_fname, /* fname */
2491 FILE_WRITE_ATTRIBUTES, /* access_mask */
2492 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2493 FILE_OPEN, /* create_disposition*/
2494 0, /* create_options */
2495 0, /* file_attributes */
2496 INTERNAL_OPEN_ONLY, /* oplock_request */
2497 0, /* allocation_size */
2498 0, /* private_flags */
2504 if (!NT_STATUS_IS_OK(nt_status)) {
2505 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2506 smb_fname_str_dbg(smb_fname)));
2507 werr = ntstatus_to_werror(nt_status);
2511 psd = r->in.sd_buf->sd;
2512 security_info_sent = r->in.securityinformation;
2514 nt_status = set_sd(fsp, psd, security_info_sent);
2516 if (!NT_STATUS_IS_OK(nt_status) ) {
2517 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2518 "on file %s\n", r->in.share));
2519 werr = WERR_ACCESS_DENIED;
2523 close_file(NULL, fsp, NORMAL_CLOSE);
2524 vfs_ChDir(conn, oldcwd);
2525 SMB_VFS_DISCONNECT(conn);
2533 close_file(NULL, fsp, NORMAL_CLOSE);
2537 vfs_ChDir(conn, oldcwd);
2541 SMB_VFS_DISCONNECT(conn);
2546 TALLOC_FREE(smb_fname);
2551 /***********************************************************************************
2552 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2553 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2554 These disks would the disks listed by this function.
2555 Users could then create shares relative to these disks. Watch out for moving these disks around.
2556 "Nigel Williams" <nigel@veritas.com>.
2557 ***********************************************************************************/
2559 static const char *server_disks[] = {"C:"};
2561 static uint32 get_server_disk_count(void)
2563 return sizeof(server_disks)/sizeof(server_disks[0]);
2566 static uint32 init_server_disk_enum(uint32 *resume)
2568 uint32 server_disk_count = get_server_disk_count();
2570 /*resume can be an offset into the list for now*/
2572 if(*resume & 0x80000000)
2575 if(*resume > server_disk_count)
2576 *resume = server_disk_count;
2578 return server_disk_count - *resume;
2581 static const char *next_server_disk_enum(uint32 *resume)
2585 if(init_server_disk_enum(resume) == 0)
2588 disk = server_disks[*resume];
2592 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2597 /********************************************************************
2599 ********************************************************************/
2601 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2602 struct srvsvc_NetDiskEnum *r)
2605 const char *disk_name;
2606 TALLOC_CTX *ctx = p->mem_ctx;
2608 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2612 *r->out.totalentries = init_server_disk_enum(&resume);
2614 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2615 MAX_SERVER_DISK_ENTRIES);
2616 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2618 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2620 r->out.info->count = 0;
2622 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2624 r->out.info->count++;
2626 /*copy disk name into a unicode string*/
2628 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2629 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2632 /* add a terminating null string. Is this there if there is more data to come? */
2634 r->out.info->count++;
2636 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2637 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2639 if (r->out.resume_handle) {
2640 *r->out.resume_handle = resume;
2646 /********************************************************************
2647 _srvsvc_NetNameValidate
2648 ********************************************************************/
2650 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2651 struct srvsvc_NetNameValidate *r)
2653 switch (r->in.name_type) {
2655 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2656 strlen_m(r->in.name)))
2658 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2660 return WERR_INVALID_NAME;
2665 return WERR_UNKNOWN_LEVEL;
2671 /*******************************************************************
2672 ********************************************************************/
2674 struct enum_file_close_state {
2675 struct srvsvc_NetFileClose *r;
2676 struct messaging_context *msg_ctx;
2679 static void enum_file_close_fn( const struct share_mode_entry *e,
2680 const char *sharepath, const char *fname,
2681 void *private_data )
2683 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2684 struct enum_file_close_state *state =
2685 (struct enum_file_close_state *)private_data;
2686 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2688 if (fid != state->r->in.fid) {
2689 return; /* Not this file. */
2692 if (!process_exists(e->pid) ) {
2696 /* Ok - send the close message. */
2697 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2699 share_mode_str(talloc_tos(), 0, e) ));
2701 share_mode_entry_to_message(msg, e);
2703 state->r->out.result = ntstatus_to_werror(
2704 messaging_send_buf(state->msg_ctx,
2705 e->pid, MSG_SMB_CLOSE_FILE,
2706 (uint8 *)msg, sizeof(msg)));
2709 /********************************************************************
2710 Close a file given a 32-bit file id.
2711 ********************************************************************/
2713 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2714 struct srvsvc_NetFileClose *r)
2716 struct enum_file_close_state state;
2719 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2721 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2723 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2724 return WERR_ACCESS_DENIED;
2727 /* enum_file_close_fn sends the close message to
2728 * the relevant smbd process. */
2730 r->out.result = WERR_BADFILE;
2732 state.msg_ctx = p->msg_ctx;
2733 share_mode_forall(enum_file_close_fn, &state);
2734 return r->out.result;
2737 /********************************************************************
2738 ********************************************************************/
2740 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2741 struct srvsvc_NetCharDevEnum *r)
2743 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2744 return WERR_NOT_SUPPORTED;
2747 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2748 struct srvsvc_NetCharDevGetInfo *r)
2750 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2751 return WERR_NOT_SUPPORTED;
2754 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2755 struct srvsvc_NetCharDevControl *r)
2757 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2758 return WERR_NOT_SUPPORTED;
2761 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2762 struct srvsvc_NetCharDevQEnum *r)
2764 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2765 return WERR_NOT_SUPPORTED;
2768 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2769 struct srvsvc_NetCharDevQGetInfo *r)
2771 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2772 return WERR_NOT_SUPPORTED;
2775 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2776 struct srvsvc_NetCharDevQSetInfo *r)
2778 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2779 return WERR_NOT_SUPPORTED;
2782 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2783 struct srvsvc_NetCharDevQPurge *r)
2785 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2786 return WERR_NOT_SUPPORTED;
2789 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2790 struct srvsvc_NetCharDevQPurgeSelf *r)
2792 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2793 return WERR_NOT_SUPPORTED;
2796 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2797 struct srvsvc_NetFileGetInfo *r)
2799 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2800 return WERR_NOT_SUPPORTED;
2803 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2804 struct srvsvc_NetShareCheck *r)
2806 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2807 return WERR_NOT_SUPPORTED;
2810 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2811 struct srvsvc_NetServerStatisticsGet *r)
2813 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2814 return WERR_NOT_SUPPORTED;
2817 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2818 struct srvsvc_NetTransportAdd *r)
2820 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2821 return WERR_NOT_SUPPORTED;
2824 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2825 struct srvsvc_NetTransportEnum *r)
2827 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2828 return WERR_NOT_SUPPORTED;
2831 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2832 struct srvsvc_NetTransportDel *r)
2834 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2835 return WERR_NOT_SUPPORTED;
2838 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2839 struct srvsvc_NetSetServiceBits *r)
2841 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2842 return WERR_NOT_SUPPORTED;
2845 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2846 struct srvsvc_NetPathType *r)
2848 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2849 return WERR_NOT_SUPPORTED;
2852 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2853 struct srvsvc_NetPathCanonicalize *r)
2855 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2856 return WERR_NOT_SUPPORTED;
2859 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2860 struct srvsvc_NetPathCompare *r)
2862 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2863 return WERR_NOT_SUPPORTED;
2866 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2867 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2869 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2870 return WERR_NOT_SUPPORTED;
2873 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2874 struct srvsvc_NetPRNameCompare *r)
2876 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2877 return WERR_NOT_SUPPORTED;
2880 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2881 struct srvsvc_NetShareDelStart *r)
2883 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2884 return WERR_NOT_SUPPORTED;
2887 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2888 struct srvsvc_NetShareDelCommit *r)
2890 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2891 return WERR_NOT_SUPPORTED;
2894 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2895 struct srvsvc_NetServerTransportAddEx *r)
2897 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2898 return WERR_NOT_SUPPORTED;
2901 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2902 struct srvsvc_NetServerSetServiceBitsEx *r)
2904 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2905 return WERR_NOT_SUPPORTED;
2908 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2909 struct srvsvc_NETRDFSGETVERSION *r)
2911 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2912 return WERR_NOT_SUPPORTED;
2915 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2916 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2918 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2919 return WERR_NOT_SUPPORTED;
2922 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2923 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2925 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2926 return WERR_NOT_SUPPORTED;
2929 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2930 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2932 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2933 return WERR_NOT_SUPPORTED;
2936 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2937 struct srvsvc_NETRDFSSETSERVERINFO *r)
2939 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2940 return WERR_NOT_SUPPORTED;
2943 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2944 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2946 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2947 return WERR_NOT_SUPPORTED;
2950 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2951 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2953 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2954 return WERR_NOT_SUPPORTED;
2957 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2958 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2960 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2961 return WERR_NOT_SUPPORTED;
2964 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2965 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2967 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2968 return WERR_NOT_SUPPORTED;
2971 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2972 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2974 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2975 return WERR_NOT_SUPPORTED;
2978 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2979 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2981 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2982 return WERR_NOT_SUPPORTED;