2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 /* This is the implementation of the srvsvc pipe. */
27 #define DBGC_CLASS DBGC_RPC_SRV
29 extern pstring global_myname;
31 /*******************************************************************
32 Fill in a share info level 1 structure.
33 ********************************************************************/
35 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
42 pstrcpy(net_name, lp_servicename(snum));
43 pstrcpy(remark, lp_comment(snum));
44 standard_sub_conn(p->conn, remark);
45 len_net_name = strlen(net_name);
47 /* work out the share type */
48 type = STYPE_DISKTREE;
50 if (lp_print_ok(snum))
52 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
54 if (net_name[len_net_name] == '$')
57 init_srv_share_info1(&sh1->info_1, net_name, type, remark);
58 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
61 /*******************************************************************
62 Fill in a share info level 2 structure.
63 ********************************************************************/
65 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
74 pstrcpy(net_name, lp_servicename(snum));
75 pstrcpy(remark, lp_comment(snum));
76 standard_sub_conn(p->conn, remark);
78 pstrcat(path, lp_pathname(snum));
81 * Change / to \\ so that win2k will see it as a valid path. This was added to
82 * enable use of browsing in win2k add share dialog.
85 string_replace(path, '/', '\\');
88 len_net_name = strlen(net_name);
90 /* work out the share type */
91 type = STYPE_DISKTREE;
93 if (lp_print_ok(snum))
95 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
97 if (net_name[len_net_name] == '$')
100 init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
101 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
104 /*******************************************************************
105 What to do when smb.conf is updated.
106 ********************************************************************/
108 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
110 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
111 reload_services(False);
114 /*******************************************************************
115 Create the share security tdb.
116 ********************************************************************/
118 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
119 #define SHARE_DATABASE_VERSION_V1 1
120 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
122 BOOL share_info_db_init(void)
124 static pid_t local_pid;
125 char *vstring = "INFO/version";
128 if (share_tdb && local_pid == sys_getpid())
130 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
132 DEBUG(0,("Failed to open share info database %s (%s)\n",
133 lock_path("share_info.tdb"), strerror(errno) ));
137 local_pid = sys_getpid();
139 /* handle a Samba upgrade */
140 tdb_lock_bystring(share_tdb, vstring);
142 /* Cope with byte-reversed older versions of the db. */
143 vers_id = tdb_fetch_int32(share_tdb, vstring);
144 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
145 /* Written on a bigendian machine with old fetch_int code. Save as le. */
146 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
147 vers_id = SHARE_DATABASE_VERSION_V2;
150 if (vers_id != SHARE_DATABASE_VERSION_V2) {
151 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
152 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
154 tdb_unlock_bystring(share_tdb, vstring);
156 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
161 /*******************************************************************
162 Fake up a Everyone, full access as a default.
163 ********************************************************************/
165 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
167 extern DOM_SID global_sid_World;
168 extern struct generic_mapping file_generic_mapping;
172 SEC_DESC *psd = NULL;
173 uint32 def_access = GENERIC_ALL_ACCESS;
175 se_map_generic(&def_access, &file_generic_mapping);
177 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
178 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
180 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
181 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
185 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
192 /*******************************************************************
193 Pull a security descriptor from the share tdb.
194 ********************************************************************/
196 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
200 SEC_DESC *psd = NULL;
204 /* Fetch security descriptor from tdb */
206 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
208 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
209 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
211 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
213 return get_share_security_default(ctx, snum, psize);
217 *psize = sec_desc_size(psd);
223 /*******************************************************************
224 Store a security descriptor in the share db.
225 ********************************************************************/
227 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
230 TALLOC_CTX *mem_ctx = NULL;
234 mem_ctx = talloc_init();
238 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
240 if (!sec_io_desc("share_security", &psd, &ps, 1))
243 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
245 if (tdb_prs_store(share_tdb, key, &ps)==0) {
247 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
249 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
252 /* Free malloc'ed memory */
258 talloc_destroy(mem_ctx);
262 /*******************************************************************
263 Delete a security descriptor.
264 ********************************************************************/
266 static BOOL delete_share_security(int snum)
271 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
273 kbuf.dsize = strlen(key)+1;
275 if (tdb_delete(share_tdb, kbuf) != 0) {
276 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
277 lp_servicename(snum) ));
284 /*******************************************************************
285 Map any generic bits to file specific bits.
286 ********************************************************************/
288 void map_generic_share_sd_bits(SEC_DESC *psd)
290 extern struct generic_mapping file_generic_mapping;
292 SEC_ACL *ps_dacl = NULL;
301 for (i = 0; i < ps_dacl->num_aces; i++) {
302 SEC_ACE *psa = &ps_dacl->ace[i];
303 uint32 orig_mask = psa->info.mask;
305 se_map_generic(&psa->info.mask, &file_generic_mapping);
306 psa->info.mask |= orig_mask;
310 /*******************************************************************
311 Can this user access with share with the required permissions ?
312 ********************************************************************/
314 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
318 TALLOC_CTX *mem_ctx = NULL;
319 SEC_DESC *psd = NULL;
321 NT_USER_TOKEN *token = NULL;
324 mem_ctx = talloc_init();
328 psd = get_share_security(mem_ctx, snum, &sd_size);
334 token = vuser->nt_user_token;
336 token = conn->nt_user_token;
338 ret = se_access_check(psd, token, desired_access, &granted, &status);
342 talloc_destroy(mem_ctx);
347 /*******************************************************************
348 Fill in a share info level 501 structure.
349 ********************************************************************/
351 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
358 pstrcpy(net_name, lp_servicename(snum));
359 pstrcpy(remark, lp_comment(snum));
360 standard_sub_conn(p->conn, remark);
362 len_net_name = strlen(net_name);
364 /* work out the share type */
365 type = STYPE_DISKTREE;
367 if (lp_print_ok(snum))
369 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
371 if (net_name[len_net_name] == '$')
372 type |= STYPE_HIDDEN;
374 init_srv_share_info501(&sh501->info_501, net_name, type, remark, (lp_csc_policy(snum) << 4));
375 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
378 /*******************************************************************
379 Fill in a share info level 502 structure.
380 ********************************************************************/
382 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
392 TALLOC_CTX *ctx = p->mem_ctx;
397 pstrcpy(net_name, lp_servicename(snum));
398 pstrcpy(remark, lp_comment(snum));
399 standard_sub_conn(p->conn, remark);
401 pstrcat(path, lp_pathname(snum));
404 * Change / to \\ so that win2k will see it as a valid path. This was added to
405 * enable use of browsing in win2k add share dialog.
408 string_replace(path, '/', '\\');
411 len_net_name = strlen(net_name);
413 /* work out the share type */
414 type = STYPE_DISKTREE;
416 if (lp_print_ok(snum))
418 if (strequal("IPC$", net_name))
420 if (net_name[len_net_name] == '$')
421 type |= STYPE_HIDDEN;
423 sd = get_share_security(ctx, snum, &sd_size);
425 init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
426 init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
429 /***************************************************************************
430 Fill in a share info level 1005 structure.
431 ***************************************************************************/
433 static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
435 sh1005->dfs_root_flag = 0;
437 if(lp_host_msdfs() && lp_msdfs_root(snum))
438 sh1005->dfs_root_flag = 3;
441 /*******************************************************************
442 True if it ends in '$'.
443 ********************************************************************/
445 static BOOL is_admin_share(int snum)
449 pstrcpy(net_name, lp_servicename(snum));
450 return (net_name[strlen(net_name)] == '$') ? True : False;
453 /*******************************************************************
454 Fill in a share info structure.
455 ********************************************************************/
457 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
458 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
461 int num_services = lp_numservices();
463 TALLOC_CTX *ctx = p->mem_ctx;
465 DEBUG(5,("init_srv_share_info_ctr\n"));
469 ctr->info_level = ctr->switch_value = info_level;
472 /* Count the number of entries. */
473 for (snum = 0; snum < num_services; snum++) {
474 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) )
478 *total_entries = num_entries;
479 ctr->num_entries2 = ctr->num_entries = num_entries;
480 ctr->ptr_share_info = ctr->ptr_entries = 1;
485 switch (info_level) {
488 SRV_SHARE_INFO_1 *info1;
491 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
493 for (snum = *resume_hnd; snum < num_services; snum++) {
494 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
495 init_srv_share_info_1(p, &info1[i++], snum);
499 ctr->share.info1 = info1;
505 SRV_SHARE_INFO_2 *info2;
508 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
510 for (snum = *resume_hnd; snum < num_services; snum++) {
511 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
512 init_srv_share_info_2(p, &info2[i++], snum);
516 ctr->share.info2 = info2;
522 SRV_SHARE_INFO_501 *info501;
525 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
527 for (snum = *resume_hnd; snum < num_services; snum++) {
528 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
529 init_srv_share_info_501(p, &info501[i++], snum);
533 ctr->share.info501 = info501;
539 SRV_SHARE_INFO_502 *info502;
542 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
544 for (snum = *resume_hnd; snum < num_services; snum++) {
545 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
546 init_srv_share_info_502(p, &info502[i++], snum);
550 ctr->share.info502 = info502;
555 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
562 /*******************************************************************
563 Inits a SRV_R_NET_SHARE_ENUM structure.
564 ********************************************************************/
566 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
567 uint32 info_level, uint32 resume_hnd, BOOL all)
569 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
571 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
572 &resume_hnd, &r_n->total_entries, all)) {
573 r_n->status = WERR_OK;
575 r_n->status = WERR_UNKNOWN_LEVEL;
578 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
581 /*******************************************************************
582 Inits a SRV_R_NET_SHARE_GET_INFO structure.
583 ********************************************************************/
585 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
586 char *share_name, uint32 info_level)
588 WERROR status = WERR_OK;
591 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
593 r_n->info.switch_value = info_level;
595 snum = find_service(share_name);
598 switch (info_level) {
600 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
603 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
606 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
609 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
612 init_srv_share_info_1005(&r_n->info.share.info1005, snum);
615 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
616 status = WERR_UNKNOWN_LEVEL;
620 status = WERR_INVALID_NAME;
623 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
624 r_n->status = status;
627 /*******************************************************************
628 fill in a sess info level 1 structure.
629 ********************************************************************/
631 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
633 init_srv_sess_info0(se0, name);
634 init_srv_sess_info0_str(str0, name);
637 /*******************************************************************
638 fill in a sess info level 0 structure.
639 ********************************************************************/
641 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
643 struct sessionid *session_list;
644 uint32 num_entries = 0;
645 (*stot) = list_sessions(&session_list);
649 SAFE_FREE(session_list);
653 DEBUG(5,("init_srv_sess_0_ss0\n"));
656 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
657 init_srv_sess_0_info(&ss0->info_0[num_entries],
658 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
660 /* move on to creating next session */
661 /* move on to creating next sess */
665 ss0->num_entries_read = num_entries;
666 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
667 ss0->num_entries_read2 = num_entries;
669 if ((*snum) >= (*stot)) {
674 ss0->num_entries_read = 0;
675 ss0->ptr_sess_info = 0;
676 ss0->num_entries_read2 = 0;
678 SAFE_FREE(session_list);
681 /*******************************************************************
682 fill in a sess info level 1 structure.
683 ********************************************************************/
685 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
686 char *name, char *user,
688 uint32 open_time, uint32 idle_time,
691 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
692 init_srv_sess_info1_str(str1, name, user);
695 /*******************************************************************
696 fill in a sess info level 1 structure.
697 ********************************************************************/
699 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
701 struct sessionid *session_list;
702 uint32 num_entries = 0;
703 (*stot) = list_sessions(&session_list);
707 SAFE_FREE(session_list);
711 DEBUG(5,("init_srv_sess_1_ss1\n"));
714 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
715 init_srv_sess_1_info(&ss1->info_1[num_entries],
716 &ss1->info_1_str[num_entries],
717 session_list[*snum].remote_machine,
718 session_list[*snum].username,
721 /* move on to creating next session */
722 /* move on to creating next sess */
726 ss1->num_entries_read = num_entries;
727 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
728 ss1->num_entries_read2 = num_entries;
730 if ((*snum) >= (*stot)) {
735 ss1->num_entries_read = 0;
736 ss1->ptr_sess_info = 0;
737 ss1->num_entries_read2 = 0;
743 /*******************************************************************
744 makes a SRV_R_NET_SESS_ENUM structure.
745 ********************************************************************/
747 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
748 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
750 WERROR status = WERR_OK;
751 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
753 ctr->switch_value = switch_value;
755 switch (switch_value) {
757 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
758 ctr->ptr_sess_ctr = 1;
761 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
762 ctr->ptr_sess_ctr = 1;
765 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
767 (*total_entries) = 0;
768 ctr->ptr_sess_ctr = 0;
769 status = WERR_UNKNOWN_LEVEL;
776 /*******************************************************************
777 makes a SRV_R_NET_SESS_ENUM structure.
778 ********************************************************************/
780 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
781 uint32 resume_hnd, int sess_level, int switch_value)
783 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
785 r_n->sess_level = sess_level;
787 if (sess_level == -1)
788 r_n->status = WERR_UNKNOWN_LEVEL;
790 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
792 if (!W_ERROR_IS_OK(r_n->status))
795 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
798 /*******************************************************************
799 fill in a conn info level 0 structure.
800 ********************************************************************/
802 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
804 uint32 num_entries = 0;
812 DEBUG(5,("init_srv_conn_0_ss0\n"));
815 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
817 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
819 /* move on to creating next connection */
820 /* move on to creating next conn */
824 ss0->num_entries_read = num_entries;
825 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
826 ss0->num_entries_read2 = num_entries;
828 if ((*snum) >= (*stot)) {
833 ss0->num_entries_read = 0;
834 ss0->ptr_conn_info = 0;
835 ss0->num_entries_read2 = 0;
841 /*******************************************************************
842 fill in a conn info level 1 structure.
843 ********************************************************************/
845 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
846 uint32 id, uint32 type,
847 uint32 num_opens, uint32 num_users, uint32 open_time,
848 char *usr_name, char *net_name)
850 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
851 init_srv_conn_info1_str(str1, usr_name, net_name);
854 /*******************************************************************
855 fill in a conn info level 1 structure.
856 ********************************************************************/
858 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
860 uint32 num_entries = 0;
868 DEBUG(5,("init_srv_conn_1_ss1\n"));
871 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
872 init_srv_conn_1_info(&ss1->info_1[num_entries],
873 &ss1->info_1_str[num_entries],
874 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
876 /* move on to creating next connection */
877 /* move on to creating next conn */
881 ss1->num_entries_read = num_entries;
882 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
883 ss1->num_entries_read2 = num_entries;
886 if ((*snum) >= (*stot)) {
891 ss1->num_entries_read = 0;
892 ss1->ptr_conn_info = 0;
893 ss1->num_entries_read2 = 0;
899 /*******************************************************************
900 makes a SRV_R_NET_CONN_ENUM structure.
901 ********************************************************************/
903 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
904 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
906 WERROR status = WERR_OK;
907 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
909 ctr->switch_value = switch_value;
911 switch (switch_value) {
913 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
914 ctr->ptr_conn_ctr = 1;
917 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
918 ctr->ptr_conn_ctr = 1;
921 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
923 (*total_entries) = 0;
924 ctr->ptr_conn_ctr = 0;
925 status = WERR_UNKNOWN_LEVEL;
932 /*******************************************************************
933 makes a SRV_R_NET_CONN_ENUM structure.
934 ********************************************************************/
936 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
937 uint32 resume_hnd, int conn_level, int switch_value)
939 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
941 r_n->conn_level = conn_level;
942 if (conn_level == -1)
943 r_n->status = WERR_UNKNOWN_LEVEL;
945 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
947 if (!W_ERROR_IS_OK(r_n->status))
950 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
953 /*******************************************************************
954 makes a SRV_R_NET_FILE_ENUM structure.
955 ********************************************************************/
957 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
958 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
960 WERROR status = WERR_OK;
961 TALLOC_CTX *ctx = p->mem_ctx;
962 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
963 *total_entries = 1; /* dummy entries only, for */
965 ctr->switch_value = switch_value;
966 ctr->num_entries = *total_entries - *resume_hnd;
967 if (ctr->num_entries < 0)
968 ctr->num_entries = 0;
969 ctr->num_entries2 = ctr->num_entries;
971 switch (switch_value) {
974 if (*total_entries > 0) {
975 ctr->ptr_entries = 1;
976 ctr->file.info3 = talloc(ctx, ctr->num_entries *
977 sizeof(SRV_FILE_INFO_3));
979 for (i=0 ;i<ctr->num_entries;i++) {
980 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
981 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
984 ctr->ptr_file_info = 1;
989 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
991 (*total_entries) = 0;
992 ctr->ptr_entries = 0;
993 status = WERR_UNKNOWN_LEVEL;
1000 /*******************************************************************
1001 makes a SRV_R_NET_FILE_ENUM structure.
1002 ********************************************************************/
1004 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1005 uint32 resume_hnd, int file_level, int switch_value)
1007 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1009 r_n->file_level = file_level;
1010 if (file_level == 0)
1011 r_n->status = WERR_UNKNOWN_LEVEL;
1013 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1015 if (!W_ERROR_IS_OK(r_n->status))
1018 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1021 /*******************************************************************
1023 ********************************************************************/
1025 WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
1027 WERROR status = WERR_OK;
1028 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1035 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1037 if (!pipe_access_check(p)) {
1038 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1039 return WERR_ACCESS_DENIED;
1042 switch (q_u->switch_value) {
1044 /* Technically level 102 should only be available to
1045 Administrators but there isn't anything super-secret
1046 here, as most of it is made up. */
1049 init_srv_info_102(&ctr->srv.sv102,
1051 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1052 lp_major_announce_version(), lp_minor_announce_version(),
1053 lp_default_server_announce(),
1054 0xffffffff, /* users */
1058 3000, /* announce delta */
1059 100000, /* licenses */
1060 "c:\\"); /* user path */
1063 init_srv_info_101(&ctr->srv.sv101,
1065 lp_major_announce_version(), lp_minor_announce_version(),
1066 lp_default_server_announce(),
1067 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1070 init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
1073 status = WERR_UNKNOWN_LEVEL;
1077 /* set up the net server get info structure */
1078 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1080 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1085 /*******************************************************************
1087 ********************************************************************/
1089 WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1091 WERROR status = WERR_OK;
1093 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1095 /* Set up the net server set info structure. */
1097 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1099 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1104 /*******************************************************************
1106 ********************************************************************/
1108 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1110 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1113 init_srv_r_net_file_enum(p, r_u,
1114 get_enum_hnd(&q_u->enum_hnd),
1116 q_u->ctr.switch_value);
1118 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1123 /*******************************************************************
1125 ********************************************************************/
1127 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1129 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1131 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1135 ZERO_STRUCTP(r_u->ctr);
1138 init_srv_r_net_conn_enum(r_u,
1139 get_enum_hnd(&q_u->enum_hnd),
1141 q_u->ctr->switch_value);
1143 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1148 /*******************************************************************
1150 ********************************************************************/
1152 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1154 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1156 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1160 ZERO_STRUCTP(r_u->ctr);
1163 init_srv_r_net_sess_enum(r_u,
1164 get_enum_hnd(&q_u->enum_hnd),
1166 q_u->ctr->switch_value);
1168 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1173 /*******************************************************************
1175 ********************************************************************/
1177 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1179 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1181 if (!pipe_access_check(p)) {
1182 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1183 return WERR_ACCESS_DENIED;
1186 /* Create the list of shares for the response. */
1187 init_srv_r_net_share_enum(p, r_u,
1188 q_u->ctr.info_level,
1189 get_enum_hnd(&q_u->enum_hnd), True);
1191 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1196 /*******************************************************************
1198 ********************************************************************/
1200 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1202 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1204 if (!pipe_access_check(p)) {
1205 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1206 return WERR_ACCESS_DENIED;
1209 /* Create the list of shares for the response. */
1210 init_srv_r_net_share_enum(p, r_u,
1211 q_u->ctr.info_level,
1212 get_enum_hnd(&q_u->enum_hnd), False);
1214 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1219 /*******************************************************************
1221 ********************************************************************/
1223 WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1227 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1229 /* Create the list of shares for the response. */
1230 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1231 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1233 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1238 /*******************************************************************
1239 Check a given DOS pathname is valid for a share.
1240 ********************************************************************/
1242 static char *valid_share_pathname(char *dos_pathname)
1244 pstring saved_pathname;
1245 pstring unix_pathname;
1249 /* Convert any '\' paths to '/' */
1250 unix_format(dos_pathname);
1251 unix_clean_name(dos_pathname);
1253 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1255 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1258 /* Only abolute paths allowed. */
1262 /* Can we cd to it ? */
1264 /* First save our current directory. */
1265 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1268 pstrcpy(unix_pathname, ptr);
1270 ret = chdir(unix_pathname);
1272 /* We *MUST* be able to chdir back. Abort if we can't. */
1273 if (chdir(saved_pathname) == -1)
1274 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1276 return (ret != -1) ? ptr : NULL;
1279 /*******************************************************************
1280 Net share set info. Modify share details.
1281 ********************************************************************/
1283 WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1285 struct current_user user;
1294 SEC_DESC *psd = NULL;
1296 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1298 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1300 r_u->switch_value = 0;
1302 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1303 return WERR_ACCESS_DENIED;
1305 snum = find_service(share_name);
1307 /* Does this share exist ? */
1309 return WERR_INVALID_NAME;
1311 /* No change to printer shares. */
1312 if (lp_print_ok(snum))
1313 return WERR_ACCESS_DENIED;
1315 get_current_user(&user,p);
1318 return WERR_ACCESS_DENIED;
1320 switch (q_u->info_level) {
1322 /* Not enough info in a level 1 to do anything. */
1323 return WERR_ACCESS_DENIED;
1325 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1326 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1327 type = q_u->info.share.info2.info_2.type;
1331 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1332 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1333 type = q_u->info.share.info502.info_502.type;
1334 psd = q_u->info.share.info502.info_502_str.sd;
1335 map_generic_share_sd_bits(psd);
1338 return WERR_ACCESS_DENIED;
1340 fstrcpy(pathname, lp_pathname(snum));
1341 fstrcpy(comment, lp_comment(snum));
1342 psd = q_u->info.share.info1501.sdb->sec;
1343 map_generic_share_sd_bits(psd);
1344 type = STYPE_DISKTREE;
1347 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1348 return WERR_UNKNOWN_LEVEL;
1351 /* We can only modify disk shares. */
1352 if (type != STYPE_DISKTREE)
1353 return WERR_ACCESS_DENIED;
1355 /* Check if the pathname is valid. */
1356 if (!(ptr = valid_share_pathname( pathname )))
1357 return WERR_OBJECT_PATH_INVALID;
1359 /* Ensure share name, pathname and comment don't contain '"' characters. */
1360 string_replace(share_name, '"', ' ');
1361 string_replace(ptr, '"', ' ');
1362 string_replace(comment, '"', ' ');
1364 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1365 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1367 /* Only call modify function if something changed. */
1369 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1370 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1371 return WERR_ACCESS_DENIED;
1373 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1374 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1376 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1377 if ((ret = smbrun(command, NULL)) != 0) {
1378 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1379 return WERR_ACCESS_DENIED;
1382 /* Tell everyone we updated smb.conf. */
1383 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1386 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1389 /* Replace SD if changed. */
1394 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1396 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1397 if (!set_share_security(p->mem_ctx, share_name, psd))
1398 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1403 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1408 /*******************************************************************
1409 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1410 ********************************************************************/
1412 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1414 struct current_user user;
1423 SEC_DESC *psd = NULL;
1425 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1427 r_u->switch_value = 0;
1429 get_current_user(&user,p);
1431 if (user.uid != 0) {
1432 DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
1433 return WERR_ACCESS_DENIED;
1436 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1437 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1438 return WERR_ACCESS_DENIED;
1441 switch (q_u->info_level) {
1443 /* Not enough info in a level 1 to do anything. */
1444 return WERR_ACCESS_DENIED;
1446 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1447 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1448 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1449 type = q_u->info.share.info2.info_2.type;
1452 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1453 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1454 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1455 type = q_u->info.share.info502.info_502.type;
1456 psd = q_u->info.share.info502.info_502_str.sd;
1457 map_generic_share_sd_bits(psd);
1460 /* DFS only level. */
1461 return WERR_ACCESS_DENIED;
1463 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1464 return WERR_UNKNOWN_LEVEL;
1467 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1468 return WERR_ACCESS_DENIED;
1470 snum = find_service(share_name);
1472 /* Share already exists. */
1474 return WERR_ALREADY_EXISTS;
1476 /* We can only add disk shares. */
1477 if (type != STYPE_DISKTREE)
1478 return WERR_ACCESS_DENIED;
1480 /* Check if the pathname is valid. */
1481 if (!(ptr = valid_share_pathname( pathname )))
1482 return WERR_OBJECT_PATH_INVALID;
1484 /* Ensure share name, pathname and comment don't contain '"' characters. */
1485 string_replace(share_name, '"', ' ');
1486 string_replace(ptr, '"', ' ');
1487 string_replace(comment, '"', ' ');
1489 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1490 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1492 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1493 if ((ret = smbrun(command, NULL)) != 0) {
1494 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1495 return WERR_ACCESS_DENIED;
1499 if (!set_share_security(p->mem_ctx, share_name, psd))
1500 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1504 /* Tell everyone we updated smb.conf. */
1505 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1508 * We don't call reload_services() here, the message will
1509 * cause this to be done before the next packet is read
1510 * from the client. JRA.
1513 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1518 /*******************************************************************
1519 Net share delete. Call "delete share command" with the share name as
1521 ********************************************************************/
1523 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1525 struct current_user user;
1531 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1533 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1535 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1536 return WERR_ACCESS_DENIED;
1538 snum = find_service(share_name);
1541 return WERR_NO_SUCH_SHARE;
1543 /* No change to printer shares. */
1544 if (lp_print_ok(snum))
1545 return WERR_ACCESS_DENIED;
1547 get_current_user(&user,p);
1550 return WERR_ACCESS_DENIED;
1552 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1553 return WERR_ACCESS_DENIED;
1555 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1556 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1558 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1559 if ((ret = smbrun(command, NULL)) != 0) {
1560 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1561 return WERR_ACCESS_DENIED;
1564 /* Delete the SD in the database. */
1565 delete_share_security(snum);
1567 /* Tell everyone we updated smb.conf. */
1568 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1570 lp_killservice(snum);
1575 /*******************************************************************
1577 ********************************************************************/
1579 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1581 TIME_OF_DAY_INFO *tod;
1583 time_t unixdate = time(NULL);
1585 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1592 r_u->ptr_srv_tod = 0x1;
1593 r_u->status = WERR_OK;
1595 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1597 t = gmtime(&unixdate);
1600 init_time_of_day_info(tod,
1607 TimeDiff(unixdate)/60,
1614 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1619 /***********************************************************************************
1620 Win9x NT tools get security descriptor.
1621 ***********************************************************************************/
1623 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1624 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1626 SEC_DESC *psd = NULL;
1631 files_struct *fsp = NULL;
1637 struct current_user user;
1638 connection_struct *conn = NULL;
1639 BOOL became_user = False;
1643 r_u->status = WERR_OK;
1645 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1647 /* Null password is ok - we are already an authenticated user... */
1648 null_pw = data_blob(NULL, 0);
1650 get_current_user(&user, p);
1653 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1657 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1658 r_u->status = ntstatus_to_werror(nt_status);
1662 if (!become_user(conn, conn->vuid)) {
1663 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1664 r_u->status = WERR_ACCESS_DENIED;
1669 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1670 unix_convert(filename, conn, NULL, &bad_path, &st);
1671 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1672 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1675 /* Perhaps it is a directory */
1676 if (errno == EISDIR)
1677 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1678 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1681 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1682 r_u->status = WERR_ACCESS_DENIED;
1687 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1690 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1691 r_u->status = WERR_ACCESS_DENIED;
1695 r_u->ptr_response = 1;
1696 r_u->size_response = sd_size;
1697 r_u->ptr_secdesc = 1;
1698 r_u->size_secdesc = sd_size;
1699 r_u->sec_desc = psd;
1701 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1703 close_file(fsp, True);
1705 close_cnum(conn, user.vuid);
1711 close_file(fsp, True);
1718 close_cnum(conn, user.vuid);
1723 /***********************************************************************************
1724 Win9x NT tools set security descriptor.
1725 ***********************************************************************************/
1727 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1728 SRV_R_NET_FILE_SET_SECDESC *r_u)
1734 files_struct *fsp = NULL;
1740 struct current_user user;
1741 connection_struct *conn = NULL;
1742 BOOL became_user = False;
1746 r_u->status = WERR_OK;
1748 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1750 /* Null password is ok - we are already an authenticated user... */
1751 null_pw = data_blob(NULL, 0);
1753 get_current_user(&user, p);
1756 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1760 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1761 r_u->status = ntstatus_to_werror(nt_status);
1765 if (!become_user(conn, conn->vuid)) {
1766 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1767 r_u->status = WERR_ACCESS_DENIED;
1772 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1773 unix_convert(filename, conn, NULL, &bad_path, &st);
1775 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1776 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1779 /* Perhaps it is a directory */
1780 if (errno == EISDIR)
1781 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1782 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1785 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1786 r_u->status = WERR_ACCESS_DENIED;
1791 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1794 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1795 r_u->status = WERR_ACCESS_DENIED;
1799 close_file(fsp, True);
1801 close_cnum(conn, user.vuid);
1807 close_file(fsp, True);
1814 close_cnum(conn, user.vuid);
1819 /***********************************************************************************
1820 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
1821 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
1822 These disks would the disks listed by this function.
1823 Users could then create shares relative to these disks. Watch out for moving these disks around.
1824 "Nigel Williams" <nigel@veritas.com>.
1825 ***********************************************************************************/
1827 const char *server_disks[] = {"C:"};
1829 static uint32 get_server_disk_count(void)
1831 return sizeof(server_disks)/sizeof(server_disks[0]);
1834 static uint32 init_server_disk_enum(uint32 *resume)
1836 uint32 server_disk_count = get_server_disk_count();
1838 /*resume can be an offset into the list for now*/
1840 if(*resume & 0x80000000)
1843 if(*resume > server_disk_count)
1844 *resume = server_disk_count;
1846 return server_disk_count - *resume;
1849 static const char *next_server_disk_enum(uint32 *resume)
1853 if(init_server_disk_enum(resume) == 0)
1856 disk = server_disks[*resume];
1860 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
1865 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
1868 const char *disk_name;
1869 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
1871 r_u->status=WERR_OK;
1873 r_u->total_entries = init_server_disk_enum(&resume);
1875 r_u->disk_enum_ctr.unknown = 0;
1877 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
1879 /*allow one DISK_INFO for null terminator*/
1881 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
1883 r_u->disk_enum_ctr.entries_read++;
1885 /*copy disk name into a unicode string*/
1887 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
1890 /*add a terminating null string. Is this there if there is more data to come?*/
1892 r_u->disk_enum_ctr.entries_read++;
1894 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
1896 init_enum_hnd(&r_u->enum_hnd, resume);
1901 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
1906 r_u->status=WERR_OK;
1912 /*check if share name is ok*/
1913 /*also check if we already have a share with this name*/
1915 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
1916 snum = find_service(share_name);
1918 /* Share already exists. */
1920 r_u->status = WERR_ALREADY_EXISTS;
1924 /*unsupported type*/
1925 r_u->status = WERR_UNKNOWN_LEVEL;