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. */
26 extern pstring global_myname;
28 /*******************************************************************
29 Fill in a share info level 1 structure.
30 ********************************************************************/
32 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
39 pstrcpy(net_name, lp_servicename(snum));
40 pstrcpy(remark, lp_comment(snum));
41 standard_sub_conn(p->conn, remark);
42 len_net_name = strlen(net_name);
44 /* work out the share type */
45 type = STYPE_DISKTREE;
47 if (lp_print_ok(snum))
49 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
51 if (net_name[len_net_name] == '$')
54 init_srv_share_info1(&sh1->info_1, net_name, type, remark);
55 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
58 /*******************************************************************
59 Fill in a share info level 2 structure.
60 ********************************************************************/
62 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
71 pstrcpy(net_name, lp_servicename(snum));
72 pstrcpy(remark, lp_comment(snum));
73 standard_sub_conn(p->conn, remark);
75 pstrcat(path, lp_pathname(snum));
78 * Change / to \\ so that win2k will see it as a valid path. This was added to
79 * enable use of browsing in win2k add share dialog.
82 string_replace(path, '/', '\\');
85 len_net_name = strlen(net_name);
87 /* work out the share type */
88 type = STYPE_DISKTREE;
90 if (lp_print_ok(snum))
92 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
94 if (net_name[len_net_name] == '$')
97 init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
98 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
101 /*******************************************************************
102 What to do when smb.conf is updated.
103 ********************************************************************/
105 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
107 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
108 reload_services(False);
111 /*******************************************************************
112 Create the share security tdb.
113 ********************************************************************/
115 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
116 #define SHARE_DATABASE_VERSION_V1 1
117 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
119 BOOL share_info_db_init(void)
121 static pid_t local_pid;
122 char *vstring = "INFO/version";
125 if (share_tdb && local_pid == sys_getpid())
127 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
129 DEBUG(0,("Failed to open share info database %s (%s)\n",
130 lock_path("share_info.tdb"), strerror(errno) ));
134 local_pid = sys_getpid();
136 /* handle a Samba upgrade */
137 tdb_lock_bystring(share_tdb, vstring);
139 /* Cope with byte-reversed older versions of the db. */
140 vers_id = tdb_fetch_int32(share_tdb, vstring);
141 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
142 /* Written on a bigendian machine with old fetch_int code. Save as le. */
143 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
144 vers_id = SHARE_DATABASE_VERSION_V2;
147 if (vers_id != SHARE_DATABASE_VERSION_V2) {
148 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
149 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
151 tdb_unlock_bystring(share_tdb, vstring);
153 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
158 /*******************************************************************
159 Fake up a Everyone, full access as a default.
160 ********************************************************************/
162 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
164 extern DOM_SID global_sid_World;
165 extern struct generic_mapping file_generic_mapping;
169 SEC_DESC *psd = NULL;
170 uint32 def_access = GENERIC_ALL_ACCESS;
172 se_map_generic(&def_access, &file_generic_mapping);
174 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
175 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
177 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
178 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
182 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
189 /*******************************************************************
190 Pull a security descriptor from the share tdb.
191 ********************************************************************/
193 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
197 SEC_DESC *psd = NULL;
201 /* Fetch security descriptor from tdb */
203 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
205 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
206 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
208 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
210 return get_share_security_default(ctx, snum, psize);
214 *psize = sec_desc_size(psd);
220 /*******************************************************************
221 Store a security descriptor in the share db.
222 ********************************************************************/
224 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
227 TALLOC_CTX *mem_ctx = NULL;
231 mem_ctx = talloc_init();
235 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
237 if (!sec_io_desc("share_security", &psd, &ps, 1))
240 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
242 if (tdb_prs_store(share_tdb, key, &ps)==0) {
244 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
246 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
249 /* Free malloc'ed memory */
255 talloc_destroy(mem_ctx);
259 /*******************************************************************
260 Delete a security descriptor.
261 ********************************************************************/
263 static BOOL delete_share_security(int snum)
268 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
270 kbuf.dsize = strlen(key)+1;
272 if (tdb_delete(share_tdb, kbuf) != 0) {
273 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
274 lp_servicename(snum) ));
281 /*******************************************************************
282 Map any generic bits to file specific bits.
283 ********************************************************************/
285 void map_generic_share_sd_bits(SEC_DESC *psd)
287 extern struct generic_mapping file_generic_mapping;
289 SEC_ACL *ps_dacl = NULL;
298 for (i = 0; i < ps_dacl->num_aces; i++) {
299 SEC_ACE *psa = &ps_dacl->ace[i];
300 uint32 orig_mask = psa->info.mask;
302 se_map_generic(&psa->info.mask, &file_generic_mapping);
303 psa->info.mask |= orig_mask;
307 /*******************************************************************
308 Can this user access with share with the required permissions ?
309 ********************************************************************/
311 BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access)
315 TALLOC_CTX *mem_ctx = NULL;
316 SEC_DESC *psd = NULL;
318 NT_USER_TOKEN *token = NULL;
319 user_struct *vuser = get_valid_user_struct(vuid);
322 mem_ctx = talloc_init();
326 psd = get_share_security(mem_ctx, snum, &sd_size);
332 token = vuser->nt_user_token;
334 token = conn->nt_user_token;
336 ret = se_access_check(psd, token, desired_access, &granted, &status);
340 talloc_destroy(mem_ctx);
345 /*******************************************************************
346 Fill in a share info level 501 structure.
347 ********************************************************************/
349 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
356 pstrcpy(net_name, lp_servicename(snum));
357 pstrcpy(remark, lp_comment(snum));
358 standard_sub_conn(p->conn, remark);
360 len_net_name = strlen(net_name);
362 /* work out the share type */
363 type = STYPE_DISKTREE;
365 if (lp_print_ok(snum))
367 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
369 if (net_name[len_net_name] == '$')
370 type |= STYPE_HIDDEN;
372 init_srv_share_info501(&sh501->info_501, net_name, type, remark, (lp_csc_policy(snum) << 4));
373 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
376 /*******************************************************************
377 Fill in a share info level 502 structure.
378 ********************************************************************/
380 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
390 TALLOC_CTX *ctx = p->mem_ctx;
395 pstrcpy(net_name, lp_servicename(snum));
396 pstrcpy(remark, lp_comment(snum));
397 standard_sub_conn(p->conn, remark);
399 pstrcat(path, lp_pathname(snum));
402 * Change / to \\ so that win2k will see it as a valid path. This was added to
403 * enable use of browsing in win2k add share dialog.
406 string_replace(path, '/', '\\');
409 len_net_name = strlen(net_name);
411 /* work out the share type */
412 type = STYPE_DISKTREE;
414 if (lp_print_ok(snum))
416 if (strequal("IPC$", net_name))
418 if (net_name[len_net_name] == '$')
419 type |= STYPE_HIDDEN;
421 sd = get_share_security(ctx, snum, &sd_size);
423 init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
424 init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
427 /***************************************************************************
428 Fill in a share info level 1005 structure.
429 ***************************************************************************/
431 static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
433 sh1005->dfs_root_flag = 0;
435 if(lp_host_msdfs() && lp_msdfs_root(snum))
436 sh1005->dfs_root_flag = 3;
439 /*******************************************************************
440 True if it ends in '$'.
441 ********************************************************************/
443 static BOOL is_admin_share(int snum)
447 pstrcpy(net_name, lp_servicename(snum));
448 return (net_name[strlen(net_name)] == '$') ? True : False;
451 /*******************************************************************
452 Fill in a share info structure.
453 ********************************************************************/
455 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
456 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
459 int num_services = lp_numservices();
461 TALLOC_CTX *ctx = p->mem_ctx;
463 DEBUG(5,("init_srv_share_info_ctr\n"));
467 ctr->info_level = ctr->switch_value = info_level;
470 /* Count the number of entries. */
471 for (snum = 0; snum < num_services; snum++) {
472 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) )
476 *total_entries = num_entries;
477 ctr->num_entries2 = ctr->num_entries = num_entries;
478 ctr->ptr_share_info = ctr->ptr_entries = 1;
483 switch (info_level) {
486 SRV_SHARE_INFO_1 *info1;
489 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
491 for (snum = *resume_hnd; snum < num_services; snum++) {
492 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
493 init_srv_share_info_1(p, &info1[i++], snum);
497 ctr->share.info1 = info1;
503 SRV_SHARE_INFO_2 *info2;
506 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
508 for (snum = *resume_hnd; snum < num_services; snum++) {
509 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
510 init_srv_share_info_2(p, &info2[i++], snum);
514 ctr->share.info2 = info2;
520 SRV_SHARE_INFO_501 *info501;
523 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
525 for (snum = *resume_hnd; snum < num_services; snum++) {
526 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
527 init_srv_share_info_501(p, &info501[i++], snum);
531 ctr->share.info501 = info501;
537 SRV_SHARE_INFO_502 *info502;
540 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
542 for (snum = *resume_hnd; snum < num_services; snum++) {
543 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
544 init_srv_share_info_502(p, &info502[i++], snum);
548 ctr->share.info502 = info502;
553 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
560 /*******************************************************************
561 Inits a SRV_R_NET_SHARE_ENUM structure.
562 ********************************************************************/
564 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
565 uint32 info_level, uint32 resume_hnd, BOOL all)
567 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
569 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
570 &resume_hnd, &r_n->total_entries, all)) {
571 r_n->status = WERR_OK;
573 r_n->status = WERR_UNKNOWN_LEVEL;
576 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
579 /*******************************************************************
580 Inits a SRV_R_NET_SHARE_GET_INFO structure.
581 ********************************************************************/
583 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
584 char *share_name, uint32 info_level)
586 WERROR status = WERR_OK;
589 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
591 r_n->info.switch_value = info_level;
593 snum = find_service(share_name);
596 switch (info_level) {
598 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
601 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
604 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
607 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
610 init_srv_share_info_1005(&r_n->info.share.info1005, snum);
613 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
614 status = WERR_UNKNOWN_LEVEL;
618 status = WERR_INVALID_NAME;
621 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
622 r_n->status = status;
625 /*******************************************************************
626 fill in a sess info level 1 structure.
627 ********************************************************************/
629 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
631 init_srv_sess_info0(se0, name);
632 init_srv_sess_info0_str(str0, name);
635 /*******************************************************************
636 fill in a sess info level 0 structure.
637 ********************************************************************/
639 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
641 uint32 num_entries = 0;
649 DEBUG(5,("init_srv_sess_0_ss0\n"));
652 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
653 init_srv_sess_0_info(&ss0->info_0[num_entries],
654 &ss0->info_0_str[num_entries], "MACHINE");
656 /* move on to creating next session */
657 /* move on to creating next sess */
661 ss0->num_entries_read = num_entries;
662 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
663 ss0->num_entries_read2 = num_entries;
665 if ((*snum) >= (*stot)) {
670 ss0->num_entries_read = 0;
671 ss0->ptr_sess_info = 0;
672 ss0->num_entries_read2 = 0;
676 /*******************************************************************
677 fill in a sess info level 1 structure.
678 ********************************************************************/
680 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
681 char *name, char *user,
683 uint32 open_time, uint32 idle_time,
686 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
687 init_srv_sess_info1_str(str1, name, user);
690 /*******************************************************************
691 fill in a sess info level 1 structure.
692 ********************************************************************/
694 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
696 uint32 num_entries = 0;
704 DEBUG(5,("init_srv_sess_1_ss1\n"));
707 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
708 init_srv_sess_1_info(&ss1->info_1[num_entries],
709 &ss1->info_1_str[num_entries],
710 "MACHINE", "dummy_user", 1, 10, 5, 0);
712 /* move on to creating next session */
713 /* move on to creating next sess */
717 ss1->num_entries_read = num_entries;
718 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
719 ss1->num_entries_read2 = num_entries;
721 if ((*snum) >= (*stot)) {
726 ss1->num_entries_read = 0;
727 ss1->ptr_sess_info = 0;
728 ss1->num_entries_read2 = 0;
734 /*******************************************************************
735 makes a SRV_R_NET_SESS_ENUM structure.
736 ********************************************************************/
738 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
739 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
741 WERROR status = WERR_OK;
742 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
744 ctr->switch_value = switch_value;
746 switch (switch_value) {
748 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
749 ctr->ptr_sess_ctr = 1;
752 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
753 ctr->ptr_sess_ctr = 1;
756 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
758 (*total_entries) = 0;
759 ctr->ptr_sess_ctr = 0;
760 status = WERR_UNKNOWN_LEVEL;
767 /*******************************************************************
768 makes a SRV_R_NET_SESS_ENUM structure.
769 ********************************************************************/
771 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
772 uint32 resume_hnd, int sess_level, int switch_value)
774 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
776 r_n->sess_level = sess_level;
778 if (sess_level == -1)
779 r_n->status = WERR_UNKNOWN_LEVEL;
781 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
783 if (!W_ERROR_IS_OK(r_n->status))
786 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
789 /*******************************************************************
790 fill in a conn info level 0 structure.
791 ********************************************************************/
793 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
795 uint32 num_entries = 0;
803 DEBUG(5,("init_srv_conn_0_ss0\n"));
806 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
808 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
810 /* move on to creating next connection */
811 /* move on to creating next conn */
815 ss0->num_entries_read = num_entries;
816 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
817 ss0->num_entries_read2 = num_entries;
819 if ((*snum) >= (*stot)) {
824 ss0->num_entries_read = 0;
825 ss0->ptr_conn_info = 0;
826 ss0->num_entries_read2 = 0;
832 /*******************************************************************
833 fill in a conn info level 1 structure.
834 ********************************************************************/
836 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
837 uint32 id, uint32 type,
838 uint32 num_opens, uint32 num_users, uint32 open_time,
839 char *usr_name, char *net_name)
841 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
842 init_srv_conn_info1_str(str1, usr_name, net_name);
845 /*******************************************************************
846 fill in a conn info level 1 structure.
847 ********************************************************************/
849 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
851 uint32 num_entries = 0;
859 DEBUG(5,("init_srv_conn_1_ss1\n"));
862 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
863 init_srv_conn_1_info(&ss1->info_1[num_entries],
864 &ss1->info_1_str[num_entries],
865 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
867 /* move on to creating next connection */
868 /* move on to creating next conn */
872 ss1->num_entries_read = num_entries;
873 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
874 ss1->num_entries_read2 = num_entries;
877 if ((*snum) >= (*stot)) {
882 ss1->num_entries_read = 0;
883 ss1->ptr_conn_info = 0;
884 ss1->num_entries_read2 = 0;
890 /*******************************************************************
891 makes a SRV_R_NET_CONN_ENUM structure.
892 ********************************************************************/
894 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
895 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
897 WERROR status = WERR_OK;
898 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
900 ctr->switch_value = switch_value;
902 switch (switch_value) {
904 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
905 ctr->ptr_conn_ctr = 1;
908 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
909 ctr->ptr_conn_ctr = 1;
912 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
914 (*total_entries) = 0;
915 ctr->ptr_conn_ctr = 0;
916 status = WERR_UNKNOWN_LEVEL;
923 /*******************************************************************
924 makes a SRV_R_NET_CONN_ENUM structure.
925 ********************************************************************/
927 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
928 uint32 resume_hnd, int conn_level, int switch_value)
930 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
932 r_n->conn_level = conn_level;
933 if (conn_level == -1)
934 r_n->status = WERR_UNKNOWN_LEVEL;
936 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
938 if (!W_ERROR_IS_OK(r_n->status))
941 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
944 /*******************************************************************
945 fill in a file info level 3 structure.
946 ********************************************************************/
948 static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
949 uint32 fnum, uint32 perms, uint32 num_locks,
950 char *path_name, char *user_name)
952 init_srv_file_info3(fl3 , fnum, perms, num_locks, path_name, user_name);
953 init_srv_file_info3_str(str3, path_name, user_name);
956 /*******************************************************************
957 fill in a file info level 3 structure.
958 ********************************************************************/
960 static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
962 uint32 num_entries = 0;
970 DEBUG(5,("init_srv_file_3_fl3\n"));
972 for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++) {
973 init_srv_file_3_info(&fl3->info_3[num_entries],
974 &fl3->info_3_str[num_entries],
975 (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
977 /* move on to creating next file */
981 fl3->num_entries_read = num_entries;
982 fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
983 fl3->num_entries_read2 = num_entries;
985 if ((*fnum) >= (*ftot)) {
990 /*******************************************************************
991 makes a SRV_R_NET_FILE_ENUM structure.
992 ********************************************************************/
994 static WERROR init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
995 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
997 WERROR status = WERR_OK;
998 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1000 ctr->switch_value = switch_value;
1002 switch (switch_value) {
1004 init_srv_file_info_3(&ctr->file.info3, resume_hnd, total_entries);
1005 ctr->ptr_file_ctr = 1;
1008 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1010 (*total_entries) = 0;
1011 ctr->ptr_file_ctr = 0;
1012 status = WERR_UNKNOWN_LEVEL;
1019 /*******************************************************************
1020 makes a SRV_R_NET_FILE_ENUM structure.
1021 ********************************************************************/
1023 static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
1024 uint32 resume_hnd, int file_level, int switch_value)
1026 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1028 r_n->file_level = file_level;
1029 if (file_level == 0)
1030 r_n->status = WERR_UNKNOWN_LEVEL;
1032 r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1034 if (!W_ERROR_IS_OK(r_n->status))
1037 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1040 /*******************************************************************
1042 ********************************************************************/
1044 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)
1046 WERROR status = WERR_OK;
1047 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1054 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1056 switch (q_u->switch_value) {
1058 init_srv_info_102(&ctr->srv.sv102,
1060 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1061 lp_major_announce_version(), lp_minor_announce_version(),
1062 lp_default_server_announce(),
1063 0xffffffff, /* users */
1067 3000, /* announce delta */
1068 100000, /* licenses */
1069 "c:\\"); /* user path */
1072 init_srv_info_101(&ctr->srv.sv101,
1074 lp_major_announce_version(), lp_minor_announce_version(),
1075 lp_default_server_announce(),
1076 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1079 init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
1082 status = WERR_UNKNOWN_LEVEL;
1086 /* set up the net server get info structure */
1087 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1089 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1094 /*******************************************************************
1096 ********************************************************************/
1098 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)
1100 WERROR status = WERR_OK;
1102 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1104 /* Set up the net server set info structure. */
1106 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1108 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1113 /*******************************************************************
1115 ********************************************************************/
1117 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1119 r_u->ctr = (SRV_FILE_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_FILE_INFO_CTR));
1123 ZERO_STRUCTP(r_u->ctr);
1125 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1128 init_srv_r_net_file_enum(r_u,
1129 get_enum_hnd(&q_u->enum_hnd),
1131 q_u->ctr->switch_value);
1133 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1138 /*******************************************************************
1140 ********************************************************************/
1142 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1144 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1146 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1150 ZERO_STRUCTP(r_u->ctr);
1153 init_srv_r_net_conn_enum(r_u,
1154 get_enum_hnd(&q_u->enum_hnd),
1156 q_u->ctr->switch_value);
1158 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1163 /*******************************************************************
1165 ********************************************************************/
1167 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1169 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1171 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1175 ZERO_STRUCTP(r_u->ctr);
1178 init_srv_r_net_sess_enum(r_u,
1179 get_enum_hnd(&q_u->enum_hnd),
1181 q_u->ctr->switch_value);
1183 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1188 /*******************************************************************
1190 ********************************************************************/
1192 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1194 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1196 /* Create the list of shares for the response. */
1197 init_srv_r_net_share_enum(p, r_u,
1198 q_u->ctr.info_level,
1199 get_enum_hnd(&q_u->enum_hnd), True);
1201 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1206 /*******************************************************************
1208 ********************************************************************/
1210 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1212 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1214 /* Create the list of shares for the response. */
1215 init_srv_r_net_share_enum(p, r_u,
1216 q_u->ctr.info_level,
1217 get_enum_hnd(&q_u->enum_hnd), False);
1219 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1224 /*******************************************************************
1226 ********************************************************************/
1228 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)
1232 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1234 /* Create the list of shares for the response. */
1235 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1236 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1238 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1243 /*******************************************************************
1244 Check a given DOS pathname is valid for a share.
1245 ********************************************************************/
1247 static char *valid_share_pathname(char *dos_pathname)
1249 pstring saved_pathname;
1250 pstring unix_pathname;
1254 /* Convert any '\' paths to '/' */
1255 unix_format(dos_pathname);
1256 unix_clean_name(dos_pathname);
1258 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1260 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1263 /* Only abolute paths allowed. */
1267 /* Can we cd to it ? */
1269 /* First save our current directory. */
1270 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1273 pstrcpy(unix_pathname, ptr);
1275 ret = chdir(unix_pathname);
1277 /* We *MUST* be able to chdir back. Abort if we can't. */
1278 if (chdir(saved_pathname) == -1)
1279 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1281 return (ret != -1) ? ptr : NULL;
1284 /*******************************************************************
1285 Net share set info. Modify share details.
1286 ********************************************************************/
1288 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)
1290 struct current_user user;
1299 SEC_DESC *psd = NULL;
1301 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1303 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1305 r_u->switch_value = 0;
1307 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1308 return WERR_ACCESS_DENIED;
1310 snum = find_service(share_name);
1312 /* Does this share exist ? */
1314 return WERR_INVALID_NAME;
1316 /* No change to printer shares. */
1317 if (lp_print_ok(snum))
1318 return WERR_ACCESS_DENIED;
1320 get_current_user(&user,p);
1323 return WERR_ACCESS_DENIED;
1325 switch (q_u->info_level) {
1327 /* Not enough info in a level 1 to do anything. */
1328 return WERR_ACCESS_DENIED;
1330 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1331 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1332 type = q_u->info.share.info2.info_2.type;
1336 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1337 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1338 type = q_u->info.share.info502.info_502.type;
1339 psd = q_u->info.share.info502.info_502_str.sd;
1340 map_generic_share_sd_bits(psd);
1343 return WERR_ACCESS_DENIED;
1345 fstrcpy(pathname, lp_pathname(snum));
1346 fstrcpy(comment, lp_comment(snum));
1347 psd = q_u->info.share.info1501.sdb->sec;
1348 map_generic_share_sd_bits(psd);
1349 type = STYPE_DISKTREE;
1352 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1353 return WERR_UNKNOWN_LEVEL;
1356 /* We can only modify disk shares. */
1357 if (type != STYPE_DISKTREE)
1358 return WERR_ACCESS_DENIED;
1360 /* Check if the pathname is valid. */
1361 if (!(ptr = valid_share_pathname( pathname )))
1362 return WERR_OBJECT_PATH_INVALID;
1364 /* Ensure share name, pathname and comment don't contain '"' characters. */
1365 string_replace(share_name, '"', ' ');
1366 string_replace(ptr, '"', ' ');
1367 string_replace(comment, '"', ' ');
1369 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1370 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1372 /* Only call modify function if something changed. */
1374 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1375 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1376 return WERR_ACCESS_DENIED;
1378 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1379 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1381 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1382 if ((ret = smbrun(command, NULL)) != 0) {
1383 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1384 return WERR_ACCESS_DENIED;
1387 /* Tell everyone we updated smb.conf. */
1388 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1391 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1394 /* Replace SD if changed. */
1399 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1401 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1402 if (!set_share_security(p->mem_ctx, share_name, psd))
1403 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1408 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1413 /*******************************************************************
1414 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1415 ********************************************************************/
1417 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1419 struct current_user user;
1428 SEC_DESC *psd = NULL;
1430 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1432 r_u->switch_value = 0;
1434 get_current_user(&user,p);
1436 if (user.uid != 0) {
1437 DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
1438 return WERR_ACCESS_DENIED;
1441 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1442 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1443 return WERR_ACCESS_DENIED;
1446 switch (q_u->info_level) {
1448 /* Not enough info in a level 1 to do anything. */
1449 return WERR_ACCESS_DENIED;
1451 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1452 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1453 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1454 type = q_u->info.share.info2.info_2.type;
1457 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1458 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1459 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1460 type = q_u->info.share.info502.info_502.type;
1461 psd = q_u->info.share.info502.info_502_str.sd;
1462 map_generic_share_sd_bits(psd);
1465 /* DFS only level. */
1466 return WERR_ACCESS_DENIED;
1468 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1469 return WERR_UNKNOWN_LEVEL;
1472 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1473 return WERR_ACCESS_DENIED;
1475 snum = find_service(share_name);
1477 /* Share already exists. */
1479 return WERR_ALREADY_EXISTS;
1481 /* We can only add disk shares. */
1482 if (type != STYPE_DISKTREE)
1483 return WERR_ACCESS_DENIED;
1485 /* Check if the pathname is valid. */
1486 if (!(ptr = valid_share_pathname( pathname )))
1487 return WERR_OBJECT_PATH_INVALID;
1489 /* Ensure share name, pathname and comment don't contain '"' characters. */
1490 string_replace(share_name, '"', ' ');
1491 string_replace(ptr, '"', ' ');
1492 string_replace(comment, '"', ' ');
1494 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1495 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1497 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1498 if ((ret = smbrun(command, NULL)) != 0) {
1499 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1500 return WERR_ACCESS_DENIED;
1504 if (!set_share_security(p->mem_ctx, share_name, psd))
1505 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1509 /* Tell everyone we updated smb.conf. */
1510 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1513 * We don't call reload_services() here, the message will
1514 * cause this to be done before the next packet is read
1515 * from the client. JRA.
1518 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1523 /*******************************************************************
1524 Net share delete. Call "delete share command" with the share name as
1526 ********************************************************************/
1528 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1530 struct current_user user;
1536 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1538 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1540 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1541 return WERR_ACCESS_DENIED;
1543 snum = find_service(share_name);
1546 return WERR_NO_SUCH_SHARE;
1548 /* No change to printer shares. */
1549 if (lp_print_ok(snum))
1550 return WERR_ACCESS_DENIED;
1552 get_current_user(&user,p);
1555 return WERR_ACCESS_DENIED;
1557 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1558 return WERR_ACCESS_DENIED;
1560 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1561 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1563 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1564 if ((ret = smbrun(command, NULL)) != 0) {
1565 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1566 return WERR_ACCESS_DENIED;
1569 /* Delete the SD in the database. */
1570 delete_share_security(snum);
1572 /* Tell everyone we updated smb.conf. */
1573 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1575 lp_killservice(snum);
1580 /*******************************************************************
1582 ********************************************************************/
1584 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1586 TIME_OF_DAY_INFO *tod;
1588 time_t unixdate = time(NULL);
1590 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1597 r_u->ptr_srv_tod = 0x1;
1598 r_u->status = WERR_OK;
1600 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1602 t = gmtime(&unixdate);
1605 init_time_of_day_info(tod,
1612 TimeDiff(unixdate)/60,
1619 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1624 /***********************************************************************************
1625 Win9x NT tools get security descriptor.
1626 ***********************************************************************************/
1628 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1629 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1631 SEC_DESC *psd = NULL;
1636 files_struct *fsp = NULL;
1642 struct current_user user;
1643 connection_struct *conn = NULL;
1644 BOOL became_user = False;
1648 r_u->status = WERR_OK;
1650 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1652 /* Null password is ok - we are already an authenticated user... */
1653 null_pw = data_blob(NULL, 0);
1655 get_current_user(&user, p);
1658 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1662 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1663 r_u->status = ntstatus_to_werror(nt_status);
1667 if (!become_user(conn, conn->vuid)) {
1668 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1669 r_u->status = WERR_ACCESS_DENIED;
1674 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1675 unix_convert(filename, conn, NULL, &bad_path, &st);
1676 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1677 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1680 /* Perhaps it is a directory */
1681 if (errno == EISDIR)
1682 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1683 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1686 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1687 r_u->status = WERR_ACCESS_DENIED;
1692 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1695 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1696 r_u->status = WERR_ACCESS_DENIED;
1700 r_u->ptr_response = 1;
1701 r_u->size_response = sd_size;
1702 r_u->ptr_secdesc = 1;
1703 r_u->size_secdesc = sd_size;
1704 r_u->sec_desc = psd;
1706 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1708 close_file(fsp, True);
1710 close_cnum(conn, user.vuid);
1716 close_file(fsp, True);
1723 close_cnum(conn, user.vuid);
1728 /***********************************************************************************
1729 Win9x NT tools set security descriptor.
1730 ***********************************************************************************/
1732 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1733 SRV_R_NET_FILE_SET_SECDESC *r_u)
1739 files_struct *fsp = NULL;
1745 struct current_user user;
1746 connection_struct *conn = NULL;
1747 BOOL became_user = False;
1751 r_u->status = WERR_OK;
1753 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1755 /* Null password is ok - we are already an authenticated user... */
1756 null_pw = data_blob(NULL, 0);
1758 get_current_user(&user, p);
1761 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1765 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1766 r_u->status = ntstatus_to_werror(nt_status);
1770 if (!become_user(conn, conn->vuid)) {
1771 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1772 r_u->status = WERR_ACCESS_DENIED;
1777 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1778 unix_convert(filename, conn, NULL, &bad_path, &st);
1780 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1781 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1784 /* Perhaps it is a directory */
1785 if (errno == EISDIR)
1786 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1787 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1790 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1791 r_u->status = WERR_ACCESS_DENIED;
1796 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1799 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1800 r_u->status = WERR_ACCESS_DENIED;
1804 close_file(fsp, True);
1806 close_cnum(conn, user.vuid);
1812 close_file(fsp, True);
1819 close_cnum(conn, user.vuid);
1824 /***********************************************************************************
1825 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
1826 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
1827 These disks would the disks listed by this function.
1828 Users could then create shares relative to these disks. Watch out for moving these disks around.
1829 "Nigel Williams" <nigel@veritas.com>.
1830 ***********************************************************************************/
1832 const char *server_disks[] = {"C:"};
1834 static uint32 get_server_disk_count(void)
1836 return sizeof(server_disks)/sizeof(server_disks[0]);
1839 static uint32 init_server_disk_enum(uint32 *resume)
1841 uint32 server_disk_count = get_server_disk_count();
1843 /*resume can be an offset into the list for now*/
1845 if(*resume & 0x80000000)
1848 if(*resume > server_disk_count)
1849 *resume = server_disk_count;
1851 return server_disk_count - *resume;
1854 static const char *next_server_disk_enum(uint32 *resume)
1858 if(init_server_disk_enum(resume) == 0)
1861 disk = server_disks[*resume];
1865 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
1870 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
1873 const char *disk_name;
1874 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
1876 r_u->status=WERR_OK;
1878 r_u->total_entries = init_server_disk_enum(&resume);
1880 r_u->disk_enum_ctr.unknown = 0;
1882 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
1884 /*allow one DISK_INFO for null terminator*/
1886 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
1888 r_u->disk_enum_ctr.entries_read++;
1890 /*copy disk name into a unicode string*/
1892 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
1895 /*add a terminating null string. Is this there if there is more data to come?*/
1897 r_u->disk_enum_ctr.entries_read++;
1899 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
1901 init_enum_hnd(&r_u->enum_hnd, resume);
1906 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
1911 r_u->status=WERR_OK;
1917 /*check if share name is ok*/
1918 /*also check if we already have a share with this name*/
1920 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
1921 snum = find_service(share_name);
1923 /* Share already exists. */
1925 r_u->status = WERR_ALREADY_EXISTS;
1929 /*unsupported type*/
1930 r_u->status = WERR_UNKNOWN_LEVEL;