2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997.
7 * Copyright (C) Jeremy Allison 2001.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* This is the implementation of the srvsvc pipe. */
28 extern pstring global_myname;
30 /*******************************************************************
31 Fill in a share info level 1 structure.
32 ********************************************************************/
34 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
41 pstrcpy(net_name, lp_servicename(snum));
42 pstrcpy(remark, lp_comment(snum));
43 standard_sub_conn(p->conn, remark);
44 len_net_name = strlen(net_name);
46 /* work out the share type */
47 type = STYPE_DISKTREE;
49 if (lp_print_ok(snum))
51 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
53 if (net_name[len_net_name] == '$')
56 init_srv_share_info1(&sh1->info_1, net_name, type, remark);
57 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
60 /*******************************************************************
61 Fill in a share info level 2 structure.
62 ********************************************************************/
64 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
73 pstrcpy(net_name, lp_servicename(snum));
74 pstrcpy(remark, lp_comment(snum));
75 standard_sub_conn(p->conn, remark);
77 pstrcat(path, lp_pathname(snum));
80 * Change / to \\ so that win2k will see it as a valid path. This was added to
81 * enable use of browsing in win2k add share dialog.
84 string_replace(path, '/', '\\');
87 len_net_name = strlen(net_name);
89 /* work out the share type */
90 type = STYPE_DISKTREE;
92 if (lp_print_ok(snum))
94 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
96 if (net_name[len_net_name] == '$')
99 init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
100 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
103 /*******************************************************************
104 What to do when smb.conf is updated.
105 ********************************************************************/
107 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
109 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
110 reload_services(False);
113 /*******************************************************************
114 Create the share security tdb.
115 ********************************************************************/
117 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
118 #define SHARE_DATABASE_VERSION_V1 1
119 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
121 BOOL share_info_db_init(void)
123 static pid_t local_pid;
124 char *vstring = "INFO/version";
127 if (share_tdb && local_pid == sys_getpid())
129 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
131 DEBUG(0,("Failed to open share info database %s (%s)\n",
132 lock_path("share_info.tdb"), strerror(errno) ));
136 local_pid = sys_getpid();
138 /* handle a Samba upgrade */
139 tdb_lock_bystring(share_tdb, vstring);
141 /* Cope with byte-reversed older versions of the db. */
142 vers_id = tdb_fetch_int32(share_tdb, vstring);
143 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
144 /* Written on a bigendian machine with old fetch_int code. Save as le. */
145 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
146 vers_id = SHARE_DATABASE_VERSION_V2;
149 if (vers_id != SHARE_DATABASE_VERSION_V2) {
150 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
151 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
153 tdb_unlock_bystring(share_tdb, vstring);
155 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
160 /*******************************************************************
161 Fake up a Everyone, full access as a default.
162 ********************************************************************/
164 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
166 extern DOM_SID global_sid_World;
167 extern struct generic_mapping file_generic_mapping;
171 SEC_DESC *psd = NULL;
172 uint32 def_access = GENERIC_ALL_ACCESS;
174 se_map_generic(&def_access, &file_generic_mapping);
176 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
177 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
179 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
180 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
184 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
191 /*******************************************************************
192 Pull a security descriptor from the share tdb.
193 ********************************************************************/
195 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
199 SEC_DESC *psd = NULL;
203 /* Fetch security descriptor from tdb */
205 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
207 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
208 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
210 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
212 return get_share_security_default(ctx, snum, psize);
216 *psize = sec_desc_size(psd);
222 /*******************************************************************
223 Store a security descriptor in the share db.
224 ********************************************************************/
226 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
229 TALLOC_CTX *mem_ctx = NULL;
233 mem_ctx = talloc_init();
237 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
239 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, uint16 vuid, uint32 desired_access)
318 TALLOC_CTX *mem_ctx = NULL;
319 SEC_DESC *psd = NULL;
321 NT_USER_TOKEN *token = NULL;
322 user_struct *vuser = get_valid_user_struct(vuid);
325 mem_ctx = talloc_init();
329 psd = get_share_security(mem_ctx, snum, &sd_size);
335 token = vuser->nt_user_token;
337 token = conn->nt_user_token;
339 ret = se_access_check(psd, token, desired_access, &granted, &status);
343 talloc_destroy(mem_ctx);
348 /*******************************************************************
349 Fill in a share info level 502 structure.
350 ********************************************************************/
352 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
362 TALLOC_CTX *ctx = p->mem_ctx;
367 pstrcpy(net_name, lp_servicename(snum));
368 pstrcpy(remark, lp_comment(snum));
369 standard_sub_conn(p->conn, remark);
371 pstrcat(path, lp_pathname(snum));
374 * Change / to \\ so that win2k will see it as a valid path. This was added to
375 * enable use of browsing in win2k add share dialog.
378 string_replace(path, '/', '\\');
381 len_net_name = strlen(net_name);
383 /* work out the share type */
384 type = STYPE_DISKTREE;
386 if (lp_print_ok(snum))
388 if (strequal("IPC$", net_name))
390 if (net_name[len_net_name] == '$')
391 type |= STYPE_HIDDEN;
393 sd = get_share_security(ctx, snum, &sd_size);
395 init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
396 init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
399 /***************************************************************************
400 Fill in a share info level 1005 structure.
401 ***************************************************************************/
403 static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
405 sh1005->dfs_root_flag = 0;
407 if(lp_host_msdfs() && lp_msdfs_root(snum))
408 sh1005->dfs_root_flag = 3;
411 /*******************************************************************
412 True if it ends in '$'.
413 ********************************************************************/
415 static BOOL is_admin_share(int snum)
419 pstrcpy(net_name, lp_servicename(snum));
420 return (net_name[strlen(net_name)] == '$') ? True : False;
423 /*******************************************************************
424 Fill in a share info structure.
425 ********************************************************************/
427 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
428 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
431 int num_services = lp_numservices();
433 TALLOC_CTX *ctx = p->mem_ctx;
435 DEBUG(5,("init_srv_share_info_ctr\n"));
439 ctr->info_level = ctr->switch_value = info_level;
442 /* Count the number of entries. */
443 for (snum = 0; snum < num_services; snum++) {
444 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) )
448 *total_entries = num_entries;
449 ctr->num_entries2 = ctr->num_entries = num_entries;
450 ctr->ptr_share_info = ctr->ptr_entries = 1;
455 switch (info_level) {
458 SRV_SHARE_INFO_1 *info1;
461 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
463 for (snum = *resume_hnd; snum < num_services; snum++) {
464 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
465 init_srv_share_info_1(p, &info1[i++], snum);
469 ctr->share.info1 = info1;
475 SRV_SHARE_INFO_2 *info2;
478 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
480 for (snum = *resume_hnd; snum < num_services; snum++) {
481 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
482 init_srv_share_info_2(p, &info2[i++], snum);
486 ctr->share.info2 = info2;
492 SRV_SHARE_INFO_502 *info502;
495 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
497 for (snum = *resume_hnd; snum < num_services; snum++) {
498 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
499 init_srv_share_info_502(p, &info502[i++], snum);
503 ctr->share.info502 = info502;
508 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
515 /*******************************************************************
516 Inits a SRV_R_NET_SHARE_ENUM structure.
517 ********************************************************************/
519 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
520 uint32 info_level, uint32 resume_hnd, BOOL all)
522 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
524 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
525 &resume_hnd, &r_n->total_entries, all)) {
526 r_n->status = NT_STATUS_OK;
528 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
531 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
534 /*******************************************************************
535 Inits a SRV_R_NET_SHARE_GET_INFO structure.
536 ********************************************************************/
538 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
539 char *share_name, uint32 info_level)
541 NTSTATUS status = NT_STATUS_OK;
544 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
546 r_n->info.switch_value = info_level;
548 snum = find_service(share_name);
551 switch (info_level) {
553 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
556 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
559 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
562 init_srv_share_info_1005(&r_n->info.share.info1005, snum);
565 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
566 status = NT_STATUS_INVALID_INFO_CLASS;
570 status = NT_STATUS_BAD_NETWORK_NAME;
573 r_n->info.ptr_share_ctr = NT_STATUS_IS_OK(status) ? 1 : 0;
574 r_n->status = status;
577 /*******************************************************************
578 fill in a sess info level 1 structure.
579 ********************************************************************/
581 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
583 init_srv_sess_info0(se0, name);
584 init_srv_sess_info0_str(str0, name);
587 /*******************************************************************
588 fill in a sess info level 0 structure.
589 ********************************************************************/
591 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
593 uint32 num_entries = 0;
601 DEBUG(5,("init_srv_sess_0_ss0\n"));
604 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
605 init_srv_sess_0_info(&ss0->info_0[num_entries],
606 &ss0->info_0_str[num_entries], "MACHINE");
608 /* move on to creating next session */
609 /* move on to creating next sess */
613 ss0->num_entries_read = num_entries;
614 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
615 ss0->num_entries_read2 = num_entries;
617 if ((*snum) >= (*stot)) {
622 ss0->num_entries_read = 0;
623 ss0->ptr_sess_info = 0;
624 ss0->num_entries_read2 = 0;
628 /*******************************************************************
629 fill in a sess info level 1 structure.
630 ********************************************************************/
632 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
633 char *name, char *user,
635 uint32 open_time, uint32 idle_time,
638 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
639 init_srv_sess_info1_str(str1, name, user);
642 /*******************************************************************
643 fill in a sess info level 1 structure.
644 ********************************************************************/
646 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
648 uint32 num_entries = 0;
656 DEBUG(5,("init_srv_sess_1_ss1\n"));
659 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
660 init_srv_sess_1_info(&ss1->info_1[num_entries],
661 &ss1->info_1_str[num_entries],
662 "MACHINE", "dummy_user", 1, 10, 5, 0);
664 /* move on to creating next session */
665 /* move on to creating next sess */
669 ss1->num_entries_read = num_entries;
670 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
671 ss1->num_entries_read2 = num_entries;
673 if ((*snum) >= (*stot)) {
678 ss1->num_entries_read = 0;
679 ss1->ptr_sess_info = 0;
680 ss1->num_entries_read2 = 0;
686 /*******************************************************************
687 makes a SRV_R_NET_SESS_ENUM structure.
688 ********************************************************************/
690 static NTSTATUS init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
691 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
693 NTSTATUS status = NT_STATUS_OK;
694 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
696 ctr->switch_value = switch_value;
698 switch (switch_value) {
700 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
701 ctr->ptr_sess_ctr = 1;
704 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
705 ctr->ptr_sess_ctr = 1;
708 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
710 (*total_entries) = 0;
711 ctr->ptr_sess_ctr = 0;
712 status = NT_STATUS_INVALID_INFO_CLASS;
719 /*******************************************************************
720 makes a SRV_R_NET_SESS_ENUM structure.
721 ********************************************************************/
723 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
724 uint32 resume_hnd, int sess_level, int switch_value)
726 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
728 r_n->sess_level = sess_level;
730 if (sess_level == -1)
731 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
733 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
735 if (NT_STATUS_IS_ERR(r_n->status))
738 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
741 /*******************************************************************
742 fill in a conn info level 0 structure.
743 ********************************************************************/
745 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
747 uint32 num_entries = 0;
755 DEBUG(5,("init_srv_conn_0_ss0\n"));
758 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
760 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
762 /* move on to creating next connection */
763 /* move on to creating next conn */
767 ss0->num_entries_read = num_entries;
768 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
769 ss0->num_entries_read2 = num_entries;
771 if ((*snum) >= (*stot)) {
776 ss0->num_entries_read = 0;
777 ss0->ptr_conn_info = 0;
778 ss0->num_entries_read2 = 0;
784 /*******************************************************************
785 fill in a conn info level 1 structure.
786 ********************************************************************/
788 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
789 uint32 id, uint32 type,
790 uint32 num_opens, uint32 num_users, uint32 open_time,
791 char *usr_name, char *net_name)
793 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
794 init_srv_conn_info1_str(str1, usr_name, net_name);
797 /*******************************************************************
798 fill in a conn info level 1 structure.
799 ********************************************************************/
801 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
803 uint32 num_entries = 0;
811 DEBUG(5,("init_srv_conn_1_ss1\n"));
814 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
815 init_srv_conn_1_info(&ss1->info_1[num_entries],
816 &ss1->info_1_str[num_entries],
817 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
819 /* move on to creating next connection */
820 /* move on to creating next conn */
824 ss1->num_entries_read = num_entries;
825 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
826 ss1->num_entries_read2 = num_entries;
829 if ((*snum) >= (*stot)) {
834 ss1->num_entries_read = 0;
835 ss1->ptr_conn_info = 0;
836 ss1->num_entries_read2 = 0;
842 /*******************************************************************
843 makes a SRV_R_NET_CONN_ENUM structure.
844 ********************************************************************/
846 static NTSTATUS init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
847 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
849 NTSTATUS status = NT_STATUS_OK;
850 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
852 ctr->switch_value = switch_value;
854 switch (switch_value) {
856 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
857 ctr->ptr_conn_ctr = 1;
860 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
861 ctr->ptr_conn_ctr = 1;
864 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
866 (*total_entries) = 0;
867 ctr->ptr_conn_ctr = 0;
868 status = NT_STATUS_INVALID_INFO_CLASS;
875 /*******************************************************************
876 makes a SRV_R_NET_CONN_ENUM structure.
877 ********************************************************************/
879 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
880 uint32 resume_hnd, int conn_level, int switch_value)
882 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
884 r_n->conn_level = conn_level;
885 if (conn_level == -1)
886 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
888 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
890 if (NT_STATUS_IS_ERR(r_n->status))
893 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
896 /*******************************************************************
897 fill in a file info level 3 structure.
898 ********************************************************************/
900 static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
901 uint32 fnum, uint32 perms, uint32 num_locks,
902 char *path_name, char *user_name)
904 init_srv_file_info3(fl3 , fnum, perms, num_locks, path_name, user_name);
905 init_srv_file_info3_str(str3, path_name, user_name);
908 /*******************************************************************
909 fill in a file info level 3 structure.
910 ********************************************************************/
912 static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
914 uint32 num_entries = 0;
922 DEBUG(5,("init_srv_file_3_fl3\n"));
924 for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++) {
925 init_srv_file_3_info(&fl3->info_3[num_entries],
926 &fl3->info_3_str[num_entries],
927 (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
929 /* move on to creating next file */
933 fl3->num_entries_read = num_entries;
934 fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
935 fl3->num_entries_read2 = num_entries;
937 if ((*fnum) >= (*ftot)) {
942 /*******************************************************************
943 makes a SRV_R_NET_FILE_ENUM structure.
944 ********************************************************************/
946 static NTSTATUS init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
947 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
949 NTSTATUS status = NT_STATUS_OK;
950 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
952 ctr->switch_value = switch_value;
954 switch (switch_value) {
956 init_srv_file_info_3(&ctr->file.info3, resume_hnd, total_entries);
957 ctr->ptr_file_ctr = 1;
960 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
962 (*total_entries) = 0;
963 ctr->ptr_file_ctr = 0;
964 status = NT_STATUS_INVALID_INFO_CLASS;
971 /*******************************************************************
972 makes a SRV_R_NET_FILE_ENUM structure.
973 ********************************************************************/
975 static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
976 uint32 resume_hnd, int file_level, int switch_value)
978 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
980 r_n->file_level = file_level;
982 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
984 r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
986 if (NT_STATUS_IS_ERR(r_n->status))
989 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
992 /*******************************************************************
994 ********************************************************************/
996 NTSTATUS _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
998 NTSTATUS status = NT_STATUS_OK;
999 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1002 return NT_STATUS_NO_MEMORY;
1006 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1008 switch (q_u->switch_value) {
1010 init_srv_info_102(&ctr->srv.sv102,
1012 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1013 lp_major_announce_version(), lp_minor_announce_version(),
1014 lp_default_server_announce(),
1015 0xffffffff, /* users */
1019 3000, /* announce delta */
1020 100000, /* licenses */
1021 "c:\\"); /* user path */
1024 init_srv_info_101(&ctr->srv.sv101,
1026 lp_major_announce_version(), lp_minor_announce_version(),
1027 lp_default_server_announce(),
1028 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1031 init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
1034 status = NT_STATUS_INVALID_INFO_CLASS;
1038 /* set up the net server get info structure */
1039 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1041 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1046 /*******************************************************************
1048 ********************************************************************/
1050 NTSTATUS _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1052 /* NT gives "Windows NT error 0xc00000022" if we return
1053 NT_STATUS_ACCESS_DENIED here so just pretend everything is OK. */
1055 NTSTATUS status = NT_STATUS_OK;
1057 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1059 /* Set up the net server set info structure. */
1061 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1063 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1068 /*******************************************************************
1070 ********************************************************************/
1072 NTSTATUS _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1074 r_u->ctr = (SRV_FILE_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_FILE_INFO_CTR));
1076 return NT_STATUS_NO_MEMORY;
1078 ZERO_STRUCTP(r_u->ctr);
1080 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1083 init_srv_r_net_file_enum(r_u,
1084 get_enum_hnd(&q_u->enum_hnd),
1086 q_u->ctr->switch_value);
1088 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1093 /*******************************************************************
1095 ********************************************************************/
1097 NTSTATUS _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1099 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1101 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1103 return NT_STATUS_NO_MEMORY;
1105 ZERO_STRUCTP(r_u->ctr);
1108 init_srv_r_net_conn_enum(r_u,
1109 get_enum_hnd(&q_u->enum_hnd),
1111 q_u->ctr->switch_value);
1113 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1118 /*******************************************************************
1120 ********************************************************************/
1122 NTSTATUS _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1124 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1126 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1128 return NT_STATUS_NO_MEMORY;
1130 ZERO_STRUCTP(r_u->ctr);
1133 init_srv_r_net_sess_enum(r_u,
1134 get_enum_hnd(&q_u->enum_hnd),
1136 q_u->ctr->switch_value);
1138 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1143 /*******************************************************************
1145 ********************************************************************/
1147 NTSTATUS _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1149 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1151 /* Create the list of shares for the response. */
1152 init_srv_r_net_share_enum(p, r_u,
1153 q_u->ctr.info_level,
1154 get_enum_hnd(&q_u->enum_hnd), True);
1156 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1161 /*******************************************************************
1163 ********************************************************************/
1165 NTSTATUS _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1167 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1169 /* Create the list of shares for the response. */
1170 init_srv_r_net_share_enum(p, r_u,
1171 q_u->ctr.info_level,
1172 get_enum_hnd(&q_u->enum_hnd), False);
1174 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1179 /*******************************************************************
1181 ********************************************************************/
1183 NTSTATUS _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1187 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1189 /* Create the list of shares for the response. */
1190 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1191 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1193 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1198 /*******************************************************************
1199 Check a given DOS pathname is valid for a share.
1200 ********************************************************************/
1202 static char *valid_share_pathname(char *dos_pathname)
1204 pstring saved_pathname;
1205 pstring unix_pathname;
1209 /* Convert any '\' paths to '/' */
1210 unix_format(dos_pathname);
1211 unix_clean_name(dos_pathname);
1213 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1215 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1218 /* Only abolute paths allowed. */
1222 /* Can we cd to it ? */
1224 /* First save our current directory. */
1225 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1228 pstrcpy(unix_pathname, ptr);
1230 ret = chdir(unix_pathname);
1232 /* We *MUST* be able to chdir back. Abort if we can't. */
1233 if (chdir(saved_pathname) == -1)
1234 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1236 return (ret != -1) ? ptr : NULL;
1239 /*******************************************************************
1240 Net share set info. Modify share details.
1241 ********************************************************************/
1243 NTSTATUS _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1245 struct current_user user;
1254 SEC_DESC *psd = NULL;
1256 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1258 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1260 r_u->switch_value = 0;
1262 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1263 return NT_STATUS_ACCESS_DENIED;
1265 snum = find_service(share_name);
1267 /* Does this share exist ? */
1269 return NT_STATUS_BAD_NETWORK_NAME;
1271 /* No change to printer shares. */
1272 if (lp_print_ok(snum))
1273 return NT_STATUS_ACCESS_DENIED;
1275 get_current_user(&user,p);
1278 return NT_STATUS_ACCESS_DENIED;
1280 switch (q_u->info_level) {
1282 /* Not enough info in a level 1 to do anything. */
1283 return NT_STATUS_ACCESS_DENIED;
1285 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1286 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1287 type = q_u->info.share.info2.info_2.type;
1291 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1292 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1293 type = q_u->info.share.info502.info_502.type;
1294 psd = q_u->info.share.info502.info_502_str.sd;
1295 map_generic_share_sd_bits(psd);
1298 return NT_STATUS_ACCESS_DENIED;
1300 fstrcpy(pathname, lp_pathname(snum));
1301 fstrcpy(comment, lp_comment(snum));
1302 psd = q_u->info.share.info1501.sdb->sec;
1303 map_generic_share_sd_bits(psd);
1304 type = STYPE_DISKTREE;
1307 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1308 return NT_STATUS_INVALID_INFO_CLASS;
1311 /* We can only modify disk shares. */
1312 if (type != STYPE_DISKTREE)
1313 return NT_STATUS_ACCESS_DENIED;
1315 /* Check if the pathname is valid. */
1316 if (!(ptr = valid_share_pathname( pathname )))
1317 return NT_STATUS_OBJECT_PATH_INVALID;
1319 /* Ensure share name, pathname and comment don't contain '"' characters. */
1320 string_replace(share_name, '"', ' ');
1321 string_replace(ptr, '"', ' ');
1322 string_replace(comment, '"', ' ');
1324 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1325 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1327 /* Only call modify function if something changed. */
1329 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1330 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1331 return NT_STATUS_ACCESS_DENIED;
1333 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1334 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1336 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1337 if ((ret = smbrun(command, NULL)) != 0) {
1338 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1339 return NT_STATUS_ACCESS_DENIED;
1342 /* Tell everyone we updated smb.conf. */
1343 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL,
1347 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1350 /* Replace SD if changed. */
1355 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1357 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1358 if (!set_share_security(p->mem_ctx, share_name, psd))
1359 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1364 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1366 return NT_STATUS_OK;
1369 /*******************************************************************
1370 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1371 ********************************************************************/
1373 NTSTATUS _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1375 struct current_user user;
1384 SEC_DESC *psd = NULL;
1386 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1388 r_u->switch_value = 0;
1390 get_current_user(&user,p);
1392 if (user.uid != 0) {
1393 DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
1394 return NT_STATUS_ACCESS_DENIED;
1397 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1398 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1399 return NT_STATUS_ACCESS_DENIED;
1402 switch (q_u->info_level) {
1404 /* Not enough info in a level 1 to do anything. */
1405 return NT_STATUS_ACCESS_DENIED;
1407 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1408 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1409 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1410 type = q_u->info.share.info2.info_2.type;
1413 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1414 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1415 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1416 type = q_u->info.share.info502.info_502.type;
1417 psd = q_u->info.share.info502.info_502_str.sd;
1418 map_generic_share_sd_bits(psd);
1421 /* DFS only level. */
1422 return NT_STATUS_ACCESS_DENIED;
1424 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1425 return NT_STATUS_INVALID_INFO_CLASS;
1428 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1429 return NT_STATUS_ACCESS_DENIED;
1431 snum = find_service(share_name);
1433 /* Share already exists. */
1435 return NT_STATUS_OBJECT_NAME_COLLISION;
1437 /* We can only add disk shares. */
1438 if (type != STYPE_DISKTREE)
1439 return NT_STATUS_ACCESS_DENIED;
1441 /* Check if the pathname is valid. */
1442 if (!(ptr = valid_share_pathname( pathname )))
1443 return NT_STATUS_OBJECT_PATH_INVALID;
1445 /* Ensure share name, pathname and comment don't contain '"' characters. */
1446 string_replace(share_name, '"', ' ');
1447 string_replace(ptr, '"', ' ');
1448 string_replace(comment, '"', ' ');
1450 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1451 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1453 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1454 if ((ret = smbrun(command, NULL)) != 0) {
1455 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1456 return NT_STATUS_ACCESS_DENIED;
1460 if (!set_share_security(p->mem_ctx, share_name, psd))
1461 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1465 /* Tell everyone we updated smb.conf. */
1466 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False,
1470 * We don't call reload_services() here, the message will
1471 * cause this to be done before the next packet is read
1472 * from the client. JRA.
1475 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1477 return NT_STATUS_OK;
1480 /*******************************************************************
1481 Net share delete. Call "delete share command" with the share name as
1483 ********************************************************************/
1485 NTSTATUS _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1487 struct current_user user;
1493 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1495 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1497 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1498 return NT_STATUS_ACCESS_DENIED;
1500 snum = find_service(share_name);
1503 return NT_STATUS_BAD_NETWORK_NAME;
1505 /* No change to printer shares. */
1506 if (lp_print_ok(snum))
1507 return NT_STATUS_ACCESS_DENIED;
1509 get_current_user(&user,p);
1512 return NT_STATUS_ACCESS_DENIED;
1514 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1515 return NT_STATUS_ACCESS_DENIED;
1517 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1518 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1520 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1521 if ((ret = smbrun(command, NULL)) != 0) {
1522 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1523 return NT_STATUS_ACCESS_DENIED;
1526 /* Delete the SD in the database. */
1527 delete_share_security(snum);
1529 /* Tell everyone we updated smb.conf. */
1530 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False,
1533 lp_killservice(snum);
1535 return NT_STATUS_OK;
1538 /*******************************************************************
1540 ********************************************************************/
1542 NTSTATUS _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1544 TIME_OF_DAY_INFO *tod;
1546 time_t unixdate = time(NULL);
1548 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1550 return NT_STATUS_NO_MEMORY;
1555 r_u->ptr_srv_tod = 0x1;
1556 r_u->status = NT_STATUS_OK;
1558 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1560 t = gmtime(&unixdate);
1563 init_time_of_day_info(tod,
1570 TimeDiff(unixdate)/60,
1577 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1582 /***********************************************************************************
1583 Win9x NT tools get security descriptor.
1584 ***********************************************************************************/
1586 NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1587 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1589 SEC_DESC *psd = NULL;
1594 files_struct *fsp = NULL;
1600 struct current_user user;
1601 connection_struct *conn = NULL;
1602 BOOL became_user = False;
1606 r_u->status = NT_STATUS_OK;
1608 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1610 /* Null password is ok - we are already an authenticated user... */
1611 null_pw = data_blob(NULL, 0);
1613 get_current_user(&user, p);
1616 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1620 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1621 r_u->status = nt_status;
1625 if (!become_user(conn, conn->vuid)) {
1626 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1627 r_u->status = NT_STATUS_ACCESS_DENIED;
1632 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1633 unix_convert(filename, conn, NULL, &bad_path, &st);
1635 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1636 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1639 /* Perhaps it is a directory */
1640 if (errno == EISDIR)
1641 fsp = open_directory(conn, filename, &st,0,
1642 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1645 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1646 r_u->status = NT_STATUS_ACCESS_DENIED;
1651 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1654 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1655 r_u->status = NT_STATUS_ACCESS_DENIED;
1659 r_u->ptr_response = 1;
1660 r_u->size_response = sd_size;
1661 r_u->ptr_secdesc = 1;
1662 r_u->size_secdesc = sd_size;
1663 r_u->sec_desc = psd;
1665 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1667 close_file(fsp, True);
1669 close_cnum(conn, user.vuid);
1675 close_file(fsp, True);
1682 close_cnum(conn, user.vuid);
1687 /***********************************************************************************
1688 Win9x NT tools set security descriptor.
1689 ***********************************************************************************/
1691 NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1692 SRV_R_NET_FILE_SET_SECDESC *r_u)
1698 files_struct *fsp = NULL;
1704 struct current_user user;
1705 connection_struct *conn = NULL;
1706 BOOL became_user = False;
1710 r_u->status = NT_STATUS_OK;
1712 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1714 /* Null password is ok - we are already an authenticated user... */
1715 null_pw = data_blob(NULL, 0);
1717 get_current_user(&user, p);
1720 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1724 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1725 r_u->status = nt_status;
1729 if (!become_user(conn, conn->vuid)) {
1730 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1731 r_u->status = NT_STATUS_ACCESS_DENIED;
1736 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1737 unix_convert(filename, conn, NULL, &bad_path, &st);
1739 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1740 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1743 /* Perhaps it is a directory */
1744 if (errno == EISDIR)
1745 fsp = open_directory(conn, filename, &st,0,
1746 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1749 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1750 r_u->status = NT_STATUS_ACCESS_DENIED;
1755 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1758 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1759 r_u->status = NT_STATUS_ACCESS_DENIED;
1763 close_file(fsp, True);
1765 close_cnum(conn, user.vuid);
1771 close_file(fsp, True);
1778 close_cnum(conn, user.vuid);
1783 /***********************************************************************************
1784 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
1785 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
1786 These disks would the disks listed by this function.
1787 Users could then create shares relative to these disks. Watch out for moving these disks around.
1788 "Nigel Williams" <nigel@veritas.com>.
1789 ***********************************************************************************/
1791 const char *server_disks[] = {"C:"};
1793 static uint32 get_server_disk_count(void)
1795 return sizeof(server_disks)/sizeof(server_disks[0]);
1798 static uint32 init_server_disk_enum(uint32 *resume)
1800 uint32 server_disk_count = get_server_disk_count();
1802 /*resume can be an offset into the list for now*/
1804 if(*resume & 0x80000000)
1807 if(*resume > server_disk_count)
1808 *resume = server_disk_count;
1810 return server_disk_count - *resume;
1813 static const char *next_server_disk_enum(uint32 *resume)
1817 if(init_server_disk_enum(resume) == 0)
1820 disk = server_disks[*resume];
1824 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
1829 NTSTATUS _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
1832 const char *disk_name;
1833 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
1835 r_u->status=NT_STATUS_OK;
1837 r_u->total_entries = init_server_disk_enum(&resume);
1839 r_u->disk_enum_ctr.unknown = 0;
1841 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info? 1 : 0;
1843 /*allow one DISK_INFO for null terminator*/
1845 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
1847 r_u->disk_enum_ctr.entries_read++;
1849 /*copy disk name into a unicode string*/
1851 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
1854 /*add a terminating null string. Is this there if there is more data to come?*/
1856 r_u->disk_enum_ctr.entries_read++;
1858 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
1860 init_enum_hnd(&r_u->enum_hnd, resume);
1865 NTSTATUS _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
1870 r_u->status=NT_STATUS_OK;
1876 /*check if share name is ok*/
1877 /*also check if we already have a share with this name*/
1879 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
1880 snum = find_service(share_name);
1882 /* Share already exists. */
1884 r_u->status = NT_STATUS_OBJECT_NAME_INVALID;
1888 /*unsupported type*/
1889 r_u->status = NT_STATUS_INVALID_LEVEL;