2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 * Copyright (C) Jeremy Allison 2001.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* This is the implementation of the srvsvc pipe. */
29 extern pstring global_myname;
31 /*******************************************************************
32 Fill in a share info level 1 structure.
33 ********************************************************************/
35 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
42 pstrcpy(net_name, lp_servicename(snum));
43 pstrcpy(remark, lp_comment(snum));
44 standard_sub_conn(p->conn, remark);
45 len_net_name = strlen(net_name);
47 /* work out the share type */
48 type = STYPE_DISKTREE;
50 if (lp_print_ok(snum))
52 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
54 if (net_name[len_net_name] == '$')
57 init_srv_share_info1(&sh1->info_1, net_name, type, remark);
58 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
61 /*******************************************************************
62 Fill in a share info level 2 structure.
63 ********************************************************************/
65 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
74 pstrcpy(net_name, lp_servicename(snum));
75 pstrcpy(remark, lp_comment(snum));
76 standard_sub_conn(p->conn, remark);
78 pstrcat(path, lp_pathname(snum));
81 * Change / to \\ so that win2k will see it as a valid path. This was added to
82 * enable use of browsing in win2k add share dialog.
85 string_replace(path, '/', '\\');
88 len_net_name = strlen(net_name);
90 /* work out the share type */
91 type = STYPE_DISKTREE;
93 if (lp_print_ok(snum))
95 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
97 if (net_name[len_net_name] == '$')
100 init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
101 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
104 /*******************************************************************
105 What to do when smb.conf is updated.
106 ********************************************************************/
108 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
110 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
111 reload_services(False);
114 /*******************************************************************
115 Create the share security tdb.
116 ********************************************************************/
118 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
119 #define SHARE_DATABASE_VERSION 1
121 BOOL share_info_db_init(void)
123 static pid_t local_pid;
124 char *vstring = "INFO/version";
126 if (share_tdb && local_pid == sys_getpid()) return True;
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);
138 if (tdb_fetch_int(share_tdb, vstring) != SHARE_DATABASE_VERSION) {
139 tdb_traverse(share_tdb, (tdb_traverse_func)tdb_delete, NULL);
140 tdb_store_int(share_tdb, vstring, SHARE_DATABASE_VERSION);
142 tdb_unlock_bystring(share_tdb, vstring);
144 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
149 /*******************************************************************
150 Fake up a Everyone, full access as a default.
151 ********************************************************************/
153 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
155 extern DOM_SID global_sid_World;
156 extern struct generic_mapping file_generic_mapping;
160 SEC_DESC *psd = NULL;
161 uint32 def_access = GENERIC_ALL_ACCESS;
163 se_map_generic(&def_access, &file_generic_mapping);
165 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
166 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
168 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
169 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
173 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
180 /*******************************************************************
181 Pull a security descriptor from the share tdb.
182 ********************************************************************/
184 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
188 SEC_DESC *psd = NULL;
192 /* Fetch security descriptor from tdb */
194 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
196 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
197 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
199 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
201 return get_share_security_default(ctx, snum, psize);
205 *psize = sec_desc_size(psd);
211 /*******************************************************************
212 Store a security descriptor in the share db.
213 ********************************************************************/
215 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
218 TALLOC_CTX *mem_ctx = NULL;
222 mem_ctx = talloc_init();
226 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
228 if (!sec_io_desc("share_security", &psd, &ps, 1)) {
232 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
234 if (tdb_prs_store(share_tdb, key, &ps)==0) {
236 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
238 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
241 /* Free malloc'ed memory */
247 talloc_destroy(mem_ctx);
251 /*******************************************************************
252 Delete a security descriptor.
253 ********************************************************************/
255 static BOOL delete_share_security(int snum)
260 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
262 kbuf.dsize = strlen(key)+1;
264 if (tdb_delete(share_tdb, kbuf) != 0) {
265 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
266 lp_servicename(snum) ));
273 /*******************************************************************
274 Map any generic bits to file specific bits.
275 ********************************************************************/
277 void map_generic_share_sd_bits(SEC_DESC *psd)
279 extern struct generic_mapping file_generic_mapping;
281 SEC_ACL *ps_dacl = NULL;
290 for (i = 0; i < ps_dacl->num_aces; i++) {
291 SEC_ACE *psa = &ps_dacl->ace[i];
292 uint32 orig_mask = psa->info.mask;
294 se_map_generic(&psa->info.mask, &file_generic_mapping);
295 psa->info.mask |= orig_mask;
299 /*******************************************************************
300 Can this user access with share with the required permissions ?
301 ********************************************************************/
303 BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access)
307 TALLOC_CTX *mem_ctx = NULL;
308 SEC_DESC *psd = NULL;
310 NT_USER_TOKEN *token = NULL;
311 user_struct *vuser = get_valid_user_struct(vuid);
314 mem_ctx = talloc_init();
318 psd = get_share_security(mem_ctx, snum, &sd_size);
324 token = vuser->nt_user_token;
326 token = conn->nt_user_token;
328 ret = se_access_check(psd, token, desired_access, &granted, &status);
332 talloc_destroy(mem_ctx);
337 /*******************************************************************
338 Fill in a share info level 502 structure.
339 ********************************************************************/
341 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
351 TALLOC_CTX *ctx = p->mem_ctx;
356 pstrcpy(net_name, lp_servicename(snum));
357 pstrcpy(remark, lp_comment(snum));
358 standard_sub_conn(p->conn, remark);
360 pstrcat(path, lp_pathname(snum));
363 * Change / to \\ so that win2k will see it as a valid path. This was added to
364 * enable use of browsing in win2k add share dialog.
367 string_replace(path, '/', '\\');
370 len_net_name = strlen(net_name);
372 /* work out the share type */
373 type = STYPE_DISKTREE;
375 if (lp_print_ok(snum))
377 if (strequal("IPC$", net_name))
379 if (net_name[len_net_name] == '$')
380 type |= STYPE_HIDDEN;
382 sd = get_share_security(ctx, snum, &sd_size);
384 init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
385 init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
388 /***************************************************************************
389 Fill in a share info level 1005 structure.
390 ***************************************************************************/
392 static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
394 sh1005->dfs_root_flag = 0;
396 if(lp_host_msdfs() && lp_msdfs_root(snum))
397 sh1005->dfs_root_flag = 3;
400 /*******************************************************************
401 True if it ends in '$'.
402 ********************************************************************/
404 static BOOL is_admin_share(int snum)
408 pstrcpy(net_name, lp_servicename(snum));
409 return (net_name[strlen(net_name)] == '$') ? True : False;
412 /*******************************************************************
413 Fill in a share info structure.
414 ********************************************************************/
416 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
417 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
420 int num_services = lp_numservices();
422 TALLOC_CTX *ctx = p->mem_ctx;
424 DEBUG(5,("init_srv_share_info_ctr\n"));
428 ctr->info_level = ctr->switch_value = info_level;
431 /* Count the number of entries. */
432 for (snum = 0; snum < num_services; snum++) {
433 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) )
437 *total_entries = num_entries;
438 ctr->num_entries2 = ctr->num_entries = num_entries;
439 ctr->ptr_share_info = ctr->ptr_entries = 1;
444 switch (info_level) {
447 SRV_SHARE_INFO_1 *info1;
450 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
452 for (snum = *resume_hnd; snum < num_services; snum++) {
453 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
454 init_srv_share_info_1(p, &info1[i++], snum);
458 ctr->share.info1 = info1;
464 SRV_SHARE_INFO_2 *info2;
467 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
469 for (snum = *resume_hnd; snum < num_services; snum++) {
470 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
471 init_srv_share_info_2(p, &info2[i++], snum);
475 ctr->share.info2 = info2;
481 SRV_SHARE_INFO_502 *info502;
484 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
486 for (snum = *resume_hnd; snum < num_services; snum++) {
487 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
488 init_srv_share_info_502(p, &info502[i++], snum);
492 ctr->share.info502 = info502;
497 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
504 /*******************************************************************
505 Inits a SRV_R_NET_SHARE_ENUM structure.
506 ********************************************************************/
508 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
509 uint32 info_level, uint32 resume_hnd, BOOL all)
511 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
513 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
514 &resume_hnd, &r_n->total_entries, all)) {
515 r_n->status = NT_STATUS_OK;
517 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
520 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
523 /*******************************************************************
524 Inits a SRV_R_NET_SHARE_GET_INFO structure.
525 ********************************************************************/
527 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
528 char *share_name, uint32 info_level)
530 NTSTATUS status = NT_STATUS_OK;
533 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
535 r_n->info.switch_value = info_level;
537 snum = find_service(share_name);
540 switch (info_level) {
542 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
545 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
548 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
551 init_srv_share_info_1005(&r_n->info.share.info1005, snum);
554 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
555 status = NT_STATUS_INVALID_INFO_CLASS;
559 status = NT_STATUS_BAD_NETWORK_NAME;
562 r_n->info.ptr_share_ctr = NT_STATUS_IS_OK(status) ? 1 : 0;
563 r_n->status = status;
566 /*******************************************************************
567 fill in a sess info level 1 structure.
568 ********************************************************************/
570 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
572 init_srv_sess_info0(se0, name);
573 init_srv_sess_info0_str(str0, name);
576 /*******************************************************************
577 fill in a sess info level 0 structure.
578 ********************************************************************/
580 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
582 uint32 num_entries = 0;
590 DEBUG(5,("init_srv_sess_0_ss0\n"));
593 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
594 init_srv_sess_0_info(&ss0->info_0[num_entries],
595 &ss0->info_0_str[num_entries], "MACHINE");
597 /* move on to creating next session */
598 /* move on to creating next sess */
602 ss0->num_entries_read = num_entries;
603 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
604 ss0->num_entries_read2 = num_entries;
606 if ((*snum) >= (*stot)) {
611 ss0->num_entries_read = 0;
612 ss0->ptr_sess_info = 0;
613 ss0->num_entries_read2 = 0;
617 /*******************************************************************
618 fill in a sess info level 1 structure.
619 ********************************************************************/
621 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
622 char *name, char *user,
624 uint32 open_time, uint32 idle_time,
627 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
628 init_srv_sess_info1_str(str1, name, user);
631 /*******************************************************************
632 fill in a sess info level 1 structure.
633 ********************************************************************/
635 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
637 uint32 num_entries = 0;
645 DEBUG(5,("init_srv_sess_1_ss1\n"));
648 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
649 init_srv_sess_1_info(&ss1->info_1[num_entries],
650 &ss1->info_1_str[num_entries],
651 "MACHINE", "dummy_user", 1, 10, 5, 0);
653 /* move on to creating next session */
654 /* move on to creating next sess */
658 ss1->num_entries_read = num_entries;
659 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
660 ss1->num_entries_read2 = num_entries;
662 if ((*snum) >= (*stot)) {
667 ss1->num_entries_read = 0;
668 ss1->ptr_sess_info = 0;
669 ss1->num_entries_read2 = 0;
675 /*******************************************************************
676 makes a SRV_R_NET_SESS_ENUM structure.
677 ********************************************************************/
679 static NTSTATUS init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
680 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
682 NTSTATUS status = NT_STATUS_OK;
683 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
685 ctr->switch_value = switch_value;
687 switch (switch_value) {
689 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
690 ctr->ptr_sess_ctr = 1;
693 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
694 ctr->ptr_sess_ctr = 1;
697 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
699 (*total_entries) = 0;
700 ctr->ptr_sess_ctr = 0;
701 status = NT_STATUS_INVALID_INFO_CLASS;
708 /*******************************************************************
709 makes a SRV_R_NET_SESS_ENUM structure.
710 ********************************************************************/
712 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
713 uint32 resume_hnd, int sess_level, int switch_value)
715 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
717 r_n->sess_level = sess_level;
719 if (sess_level == -1)
720 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
722 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
724 if (NT_STATUS_IS_ERR(r_n->status))
727 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
730 /*******************************************************************
731 fill in a conn info level 0 structure.
732 ********************************************************************/
734 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
736 uint32 num_entries = 0;
744 DEBUG(5,("init_srv_conn_0_ss0\n"));
747 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
749 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
751 /* move on to creating next connection */
752 /* move on to creating next conn */
756 ss0->num_entries_read = num_entries;
757 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
758 ss0->num_entries_read2 = num_entries;
760 if ((*snum) >= (*stot)) {
765 ss0->num_entries_read = 0;
766 ss0->ptr_conn_info = 0;
767 ss0->num_entries_read2 = 0;
773 /*******************************************************************
774 fill in a conn info level 1 structure.
775 ********************************************************************/
777 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
778 uint32 id, uint32 type,
779 uint32 num_opens, uint32 num_users, uint32 open_time,
780 char *usr_name, char *net_name)
782 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
783 init_srv_conn_info1_str(str1, usr_name, net_name);
786 /*******************************************************************
787 fill in a conn info level 1 structure.
788 ********************************************************************/
790 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
792 uint32 num_entries = 0;
800 DEBUG(5,("init_srv_conn_1_ss1\n"));
803 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
804 init_srv_conn_1_info(&ss1->info_1[num_entries],
805 &ss1->info_1_str[num_entries],
806 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
808 /* move on to creating next connection */
809 /* move on to creating next conn */
813 ss1->num_entries_read = num_entries;
814 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
815 ss1->num_entries_read2 = num_entries;
818 if ((*snum) >= (*stot)) {
823 ss1->num_entries_read = 0;
824 ss1->ptr_conn_info = 0;
825 ss1->num_entries_read2 = 0;
831 /*******************************************************************
832 makes a SRV_R_NET_CONN_ENUM structure.
833 ********************************************************************/
835 static NTSTATUS init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
836 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
838 NTSTATUS status = NT_STATUS_OK;
839 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
841 ctr->switch_value = switch_value;
843 switch (switch_value) {
845 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
846 ctr->ptr_conn_ctr = 1;
849 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
850 ctr->ptr_conn_ctr = 1;
853 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
855 (*total_entries) = 0;
856 ctr->ptr_conn_ctr = 0;
857 status = NT_STATUS_INVALID_INFO_CLASS;
864 /*******************************************************************
865 makes a SRV_R_NET_CONN_ENUM structure.
866 ********************************************************************/
868 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
869 uint32 resume_hnd, int conn_level, int switch_value)
871 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
873 r_n->conn_level = conn_level;
874 if (conn_level == -1)
875 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
877 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
879 if (NT_STATUS_IS_ERR(r_n->status))
882 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
885 /*******************************************************************
886 fill in a file info level 3 structure.
887 ********************************************************************/
889 static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
890 uint32 fnum, uint32 perms, uint32 num_locks,
891 char *path_name, char *user_name)
893 init_srv_file_info3(fl3 , fnum, perms, num_locks, path_name, user_name);
894 init_srv_file_info3_str(str3, path_name, user_name);
897 /*******************************************************************
898 fill in a file info level 3 structure.
899 ********************************************************************/
901 static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
903 uint32 num_entries = 0;
911 DEBUG(5,("init_srv_file_3_fl3\n"));
913 for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++) {
914 init_srv_file_3_info(&fl3->info_3[num_entries],
915 &fl3->info_3_str[num_entries],
916 (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
918 /* move on to creating next file */
922 fl3->num_entries_read = num_entries;
923 fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
924 fl3->num_entries_read2 = num_entries;
926 if ((*fnum) >= (*ftot)) {
931 /*******************************************************************
932 makes a SRV_R_NET_FILE_ENUM structure.
933 ********************************************************************/
935 static NTSTATUS init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
936 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
938 NTSTATUS status = NT_STATUS_OK;
939 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
941 ctr->switch_value = switch_value;
943 switch (switch_value) {
945 init_srv_file_info_3(&ctr->file.info3, resume_hnd, total_entries);
946 ctr->ptr_file_ctr = 1;
949 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
951 (*total_entries) = 0;
952 ctr->ptr_file_ctr = 0;
953 status = NT_STATUS_INVALID_INFO_CLASS;
960 /*******************************************************************
961 makes a SRV_R_NET_FILE_ENUM structure.
962 ********************************************************************/
964 static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
965 uint32 resume_hnd, int file_level, int switch_value)
967 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
969 r_n->file_level = file_level;
971 r_n->status = NT_STATUS_INVALID_INFO_CLASS;
973 r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
975 if (NT_STATUS_IS_ERR(r_n->status))
978 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
981 /*******************************************************************
983 ********************************************************************/
985 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)
987 NTSTATUS status = NT_STATUS_OK;
988 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
991 return NT_STATUS_NO_MEMORY;
995 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
997 switch (q_u->switch_value) {
999 init_srv_info_102(&ctr->srv.sv102,
1001 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1002 lp_major_announce_version(), lp_minor_announce_version(),
1003 lp_default_server_announce(),
1004 0xffffffff, /* users */
1008 3000, /* announce delta */
1009 100000, /* licenses */
1010 "c:\\"); /* user path */
1013 init_srv_info_101(&ctr->srv.sv101,
1015 lp_major_announce_version(), lp_minor_announce_version(),
1016 lp_default_server_announce(),
1017 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1020 init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
1023 status = NT_STATUS_INVALID_INFO_CLASS;
1027 /* set up the net server get info structure */
1028 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1030 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1035 /*******************************************************************
1037 ********************************************************************/
1039 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)
1041 /* NT gives "Windows NT error 0xc00000022" if we return
1042 NT_STATUS_ACCESS_DENIED here so just pretend everything is OK. */
1044 NTSTATUS status = NT_STATUS_OK;
1046 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1048 /* Set up the net server set info structure. */
1050 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1052 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1057 /*******************************************************************
1059 ********************************************************************/
1061 NTSTATUS _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1063 r_u->ctr = (SRV_FILE_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_FILE_INFO_CTR));
1065 return NT_STATUS_NO_MEMORY;
1067 ZERO_STRUCTP(r_u->ctr);
1069 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1072 init_srv_r_net_file_enum(r_u,
1073 get_enum_hnd(&q_u->enum_hnd),
1075 q_u->ctr->switch_value);
1077 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1082 /*******************************************************************
1084 ********************************************************************/
1086 NTSTATUS _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1088 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1090 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1092 return NT_STATUS_NO_MEMORY;
1094 ZERO_STRUCTP(r_u->ctr);
1097 init_srv_r_net_conn_enum(r_u,
1098 get_enum_hnd(&q_u->enum_hnd),
1100 q_u->ctr->switch_value);
1102 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1107 /*******************************************************************
1109 ********************************************************************/
1111 NTSTATUS _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1113 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1115 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1117 return NT_STATUS_NO_MEMORY;
1119 ZERO_STRUCTP(r_u->ctr);
1122 init_srv_r_net_sess_enum(r_u,
1123 get_enum_hnd(&q_u->enum_hnd),
1125 q_u->ctr->switch_value);
1127 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1132 /*******************************************************************
1134 ********************************************************************/
1136 NTSTATUS _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1138 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1140 /* Create the list of shares for the response. */
1141 init_srv_r_net_share_enum(p, r_u,
1142 q_u->ctr.info_level,
1143 get_enum_hnd(&q_u->enum_hnd), True);
1145 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1150 /*******************************************************************
1152 ********************************************************************/
1154 NTSTATUS _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1156 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1158 /* Create the list of shares for the response. */
1159 init_srv_r_net_share_enum(p, r_u,
1160 q_u->ctr.info_level,
1161 get_enum_hnd(&q_u->enum_hnd), False);
1163 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1168 /*******************************************************************
1170 ********************************************************************/
1172 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)
1176 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1178 /* Create the list of shares for the response. */
1179 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1180 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1182 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1187 /*******************************************************************
1188 Check a given DOS pathname is valid for a share.
1189 ********************************************************************/
1191 static char *valid_share_pathname(char *dos_pathname)
1193 pstring saved_pathname;
1194 pstring unix_pathname;
1198 /* Convert any '\' paths to '/' */
1199 unix_format(dos_pathname);
1200 unix_clean_name(dos_pathname);
1202 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1204 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1207 /* Only abolute paths allowed. */
1211 /* Can we cd to it ? */
1213 /* First save our current directory. */
1214 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1217 pstrcpy(unix_pathname, ptr);
1219 ret = chdir(unix_pathname);
1221 /* We *MUST* be able to chdir back. Abort if we can't. */
1222 if (chdir(saved_pathname) == -1)
1223 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1225 return (ret != -1) ? ptr : NULL;
1228 /*******************************************************************
1229 Net share set info. Modify share details.
1230 ********************************************************************/
1232 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)
1234 struct current_user user;
1243 SEC_DESC *psd = NULL;
1245 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1247 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1249 r_u->switch_value = 0;
1251 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1252 return NT_STATUS_ACCESS_DENIED;
1254 snum = find_service(share_name);
1256 /* Does this share exist ? */
1258 return NT_STATUS_BAD_NETWORK_NAME;
1260 /* No change to printer shares. */
1261 if (lp_print_ok(snum))
1262 return NT_STATUS_ACCESS_DENIED;
1264 get_current_user(&user,p);
1267 return NT_STATUS_ACCESS_DENIED;
1269 switch (q_u->info_level) {
1271 /* Not enough info in a level 1 to do anything. */
1272 return NT_STATUS_ACCESS_DENIED;
1274 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1275 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1276 type = q_u->info.share.info2.info_2.type;
1280 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1281 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1282 type = q_u->info.share.info502.info_502.type;
1283 psd = q_u->info.share.info502.info_502_str.sd;
1284 map_generic_share_sd_bits(psd);
1287 return NT_STATUS_ACCESS_DENIED;
1289 fstrcpy(pathname, lp_pathname(snum));
1290 fstrcpy(comment, lp_comment(snum));
1291 psd = q_u->info.share.info1501.sdb->sec;
1292 map_generic_share_sd_bits(psd);
1293 type = STYPE_DISKTREE;
1296 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1297 return NT_STATUS_INVALID_INFO_CLASS;
1300 /* We can only modify disk shares. */
1301 if (type != STYPE_DISKTREE)
1302 return NT_STATUS_ACCESS_DENIED;
1304 /* Check if the pathname is valid. */
1305 if (!(ptr = valid_share_pathname( pathname )))
1306 return NT_STATUS_OBJECT_PATH_INVALID;
1308 /* Ensure share name, pathname and comment don't contain '"' characters. */
1309 string_replace(share_name, '"', ' ');
1310 string_replace(ptr, '"', ' ');
1311 string_replace(comment, '"', ' ');
1313 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1314 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1316 /* Only call modify function if something changed. */
1318 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1319 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1320 return NT_STATUS_ACCESS_DENIED;
1322 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1323 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1325 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1326 if ((ret = smbrun(command, NULL)) != 0) {
1327 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1328 return NT_STATUS_ACCESS_DENIED;
1331 /* Tell everyone we updated smb.conf. */
1332 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False);
1335 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1338 /* Replace SD if changed. */
1343 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1345 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1346 if (!set_share_security(p->mem_ctx, share_name, psd))
1347 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1352 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1354 return NT_STATUS_OK;
1357 /*******************************************************************
1358 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1359 ********************************************************************/
1361 NTSTATUS _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1363 struct current_user user;
1372 SEC_DESC *psd = NULL;
1374 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1376 r_u->switch_value = 0;
1378 get_current_user(&user,p);
1380 if (user.uid != 0) {
1381 DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
1382 return NT_STATUS_ACCESS_DENIED;
1385 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1386 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1387 return NT_STATUS_ACCESS_DENIED;
1390 switch (q_u->info_level) {
1392 /* Not enough info in a level 1 to do anything. */
1393 return NT_STATUS_ACCESS_DENIED;
1395 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1396 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1397 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1398 type = q_u->info.share.info2.info_2.type;
1401 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1402 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1403 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1404 type = q_u->info.share.info502.info_502.type;
1405 psd = q_u->info.share.info502.info_502_str.sd;
1406 map_generic_share_sd_bits(psd);
1409 /* DFS only level. */
1410 return NT_STATUS_ACCESS_DENIED;
1412 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1413 return NT_STATUS_INVALID_INFO_CLASS;
1416 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1417 return NT_STATUS_ACCESS_DENIED;
1419 snum = find_service(share_name);
1421 /* Share already exists. */
1423 return NT_STATUS_OBJECT_NAME_COLLISION;
1425 /* We can only add disk shares. */
1426 if (type != STYPE_DISKTREE)
1427 return NT_STATUS_ACCESS_DENIED;
1429 /* Check if the pathname is valid. */
1430 if (!(ptr = valid_share_pathname( pathname )))
1431 return NT_STATUS_OBJECT_PATH_INVALID;
1433 /* Ensure share name, pathname and comment don't contain '"' characters. */
1434 string_replace(share_name, '"', ' ');
1435 string_replace(ptr, '"', ' ');
1436 string_replace(comment, '"', ' ');
1438 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1439 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1441 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1442 if ((ret = smbrun(command, NULL)) != 0) {
1443 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1444 return NT_STATUS_ACCESS_DENIED;
1448 if (!set_share_security(p->mem_ctx, share_name, psd))
1449 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1453 /* Tell everyone we updated smb.conf. */
1454 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False);
1457 * We don't call reload_services() here, the message will
1458 * cause this to be done before the next packet is read
1459 * from the client. JRA.
1462 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1464 return NT_STATUS_OK;
1467 /*******************************************************************
1468 Net share delete. Call "delete share command" with the share name as
1470 ********************************************************************/
1472 NTSTATUS _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1474 struct current_user user;
1480 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1482 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1484 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1485 return NT_STATUS_ACCESS_DENIED;
1487 snum = find_service(share_name);
1490 return NT_STATUS_BAD_NETWORK_NAME;
1492 /* No change to printer shares. */
1493 if (lp_print_ok(snum))
1494 return NT_STATUS_ACCESS_DENIED;
1496 get_current_user(&user,p);
1499 return NT_STATUS_ACCESS_DENIED;
1501 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1502 return NT_STATUS_ACCESS_DENIED;
1504 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1505 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1507 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1508 if ((ret = smbrun(command, NULL)) != 0) {
1509 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1510 return NT_STATUS_ACCESS_DENIED;
1513 /* Delete the SD in the database. */
1514 delete_share_security(snum);
1516 /* Tell everyone we updated smb.conf. */
1517 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False);
1519 lp_killservice(snum);
1521 return NT_STATUS_OK;
1524 /*******************************************************************
1526 ********************************************************************/
1528 NTSTATUS _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1530 TIME_OF_DAY_INFO *tod;
1532 time_t unixdate = time(NULL);
1534 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1536 return NT_STATUS_NO_MEMORY;
1541 r_u->ptr_srv_tod = 0x1;
1542 r_u->status = NT_STATUS_OK;
1544 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1546 t = gmtime(&unixdate);
1549 init_time_of_day_info(tod,
1556 TimeDiff(unixdate)/60,
1563 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1568 /***********************************************************************************
1569 Win9x NT tools get security descriptor.
1570 ***********************************************************************************/
1572 NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1573 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1575 SEC_DESC *psd = NULL;
1580 files_struct *fsp = NULL;
1586 struct current_user user;
1587 connection_struct *conn = NULL;
1588 BOOL became_user = False;
1592 r_u->status = NT_STATUS_OK;
1594 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1596 /* Null password is ok - we are already an authenticated user... */
1597 null_pw = data_blob(NULL, 0);
1599 get_current_user(&user, p);
1602 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1606 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1607 r_u->status = nt_status;
1611 if (!become_user(conn, conn->vuid)) {
1612 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1613 r_u->status = NT_STATUS_ACCESS_DENIED;
1618 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1619 unix_convert(filename, conn, NULL, &bad_path, &st);
1621 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1622 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1625 /* Perhaps it is a directory */
1626 if (errno == EISDIR)
1627 fsp = open_directory(conn, filename, &st,
1628 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1631 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1632 r_u->status = NT_STATUS_ACCESS_DENIED;
1637 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1640 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1641 r_u->status = NT_STATUS_ACCESS_DENIED;
1645 r_u->ptr_response = 1;
1646 r_u->size_response = sd_size;
1647 r_u->ptr_secdesc = 1;
1648 r_u->size_secdesc = sd_size;
1649 r_u->sec_desc = psd;
1651 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1653 close_file(fsp, True);
1655 close_cnum(conn, user.vuid);
1661 close_file(fsp, True);
1668 close_cnum(conn, user.vuid);
1673 /***********************************************************************************
1674 Win9x NT tools set security descriptor.
1675 ***********************************************************************************/
1677 NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1678 SRV_R_NET_FILE_SET_SECDESC *r_u)
1684 files_struct *fsp = NULL;
1690 struct current_user user;
1691 connection_struct *conn = NULL;
1692 BOOL became_user = False;
1696 r_u->status = NT_STATUS_OK;
1698 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1700 /* Null password is ok - we are already an authenticated user... */
1701 null_pw = data_blob(NULL, 0);
1703 get_current_user(&user, p);
1706 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1710 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1711 r_u->status = nt_status;
1715 if (!become_user(conn, conn->vuid)) {
1716 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1717 r_u->status = NT_STATUS_ACCESS_DENIED;
1722 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1723 unix_convert(filename, conn, NULL, &bad_path, &st);
1725 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1726 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1729 /* Perhaps it is a directory */
1730 if (errno == EISDIR)
1731 fsp = open_directory(conn, filename, &st,
1732 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1735 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1736 r_u->status = NT_STATUS_ACCESS_DENIED;
1741 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1744 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1745 r_u->status = NT_STATUS_ACCESS_DENIED;
1749 close_file(fsp, True);
1751 close_cnum(conn, user.vuid);
1757 close_file(fsp, True);
1764 close_cnum(conn, user.vuid);
1769 /***********************************************************************************
1770 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
1771 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
1772 These disks would the disks listed by this function.
1773 Users could then create shares relative to these disks. Watch out for moving these disks around.
1774 "Nigel Williams" <nigel@veritas.com>.
1775 ***********************************************************************************/
1777 const char *server_disks[] = {"C:"};
1779 static uint32 get_server_disk_count(void)
1781 return sizeof(server_disks)/sizeof(server_disks[0]);
1784 static uint32 init_server_disk_enum(uint32 *resume)
1786 uint32 server_disk_count = get_server_disk_count();
1788 /*resume can be an offset into the list for now*/
1790 if(*resume & 0x80000000)
1793 if(*resume > server_disk_count)
1794 *resume = server_disk_count;
1796 return server_disk_count - *resume;
1799 static const char *next_server_disk_enum(uint32 *resume)
1803 if(init_server_disk_enum(resume) == 0)
1806 disk = server_disks[*resume];
1810 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
1815 NTSTATUS _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
1818 const char *disk_name;
1819 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
1821 r_u->status=NT_STATUS_OK;
1823 r_u->total_entries = init_server_disk_enum(&resume);
1825 r_u->disk_enum_ctr.unknown = 0;
1827 r_u->disk_enum_ctr.disk_info_ptr = (uint32) r_u->disk_enum_ctr.disk_info;
1829 /*allow one DISK_INFO for null terminator*/
1831 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
1833 r_u->disk_enum_ctr.entries_read++;
1835 /*copy disk name into a unicode string*/
1837 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
1840 /*add a terminating null string. Is this there if there is more data to come?*/
1842 r_u->disk_enum_ctr.entries_read++;
1844 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
1846 init_enum_hnd(&r_u->enum_hnd, resume);
1851 NTSTATUS _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
1856 r_u->status=NT_STATUS_OK;
1862 /*check if share name is ok*/
1863 /*also check if we already have a share with this name*/
1865 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
1866 snum = find_service(share_name);
1868 /* Share already exists. */
1870 r_u->status = NT_STATUS_OBJECT_NAME_INVALID;
1874 /*unsupported type*/
1875 r_u->status = NT_STATUS_INVALID_LEVEL;