* fix to display correct form information in REG_BINARY information
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob202e869d35cfc189d0ceb819f466b9896414c9ff
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 /* This is the implementation of the srvsvc pipe. */
24 #include "includes.h"
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_SRV
29 extern pstring global_myname;
31 /*******************************************************************
32 Fill in a share info level 1 structure.
33 ********************************************************************/
35 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
37 int len_net_name;
38 pstring net_name;
39 pstring remark;
40 uint32 type;
42 pstrcpy(net_name, lp_servicename(snum));
43 pstrcpy(remark, lp_comment(snum));
44 standard_sub_conn(p->conn, remark,sizeof(remark));
45 len_net_name = strlen(net_name);
47 /* work out the share type */
48 type = STYPE_DISKTREE;
50 if (lp_print_ok(snum))
51 type = STYPE_PRINTQ;
52 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
53 type = STYPE_IPC;
54 if (net_name[len_net_name] == '$')
55 type |= STYPE_HIDDEN;
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)
67 int len_net_name;
68 pstring net_name;
69 pstring remark;
70 pstring path;
71 pstring passwd;
72 uint32 type;
74 pstrcpy(net_name, lp_servicename(snum));
75 pstrcpy(remark, lp_comment(snum));
76 standard_sub_conn(p->conn, remark,sizeof(remark));
77 pstrcpy(path, "C:");
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.
83 */
85 string_replace(path, '/', '\\');
87 pstrcpy(passwd, "");
88 len_net_name = strlen(net_name);
90 /* work out the share type */
91 type = STYPE_DISKTREE;
93 if (lp_print_ok(snum))
94 type = STYPE_PRINTQ;
95 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
96 type = STYPE_IPC;
97 if (net_name[len_net_name] == '$')
98 type |= STYPE_HIDDEN;
100 init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
101 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
104 /*******************************************************************
105 What to do when smb.conf is updated.
106 ********************************************************************/
108 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
110 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
111 reload_services(False);
114 /*******************************************************************
115 Create the share security tdb.
116 ********************************************************************/
118 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
119 #define SHARE_DATABASE_VERSION_V1 1
120 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
122 BOOL share_info_db_init(void)
124 static pid_t local_pid;
125 char *vstring = "INFO/version";
126 int32 vers_id;
128 if (share_tdb && local_pid == sys_getpid())
129 return True;
130 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
131 if (!share_tdb) {
132 DEBUG(0,("Failed to open share info database %s (%s)\n",
133 lock_path("share_info.tdb"), strerror(errno) ));
134 return False;
137 local_pid = sys_getpid();
139 /* handle a Samba upgrade */
140 tdb_lock_bystring(share_tdb, vstring);
142 /* Cope with byte-reversed older versions of the db. */
143 vers_id = tdb_fetch_int32(share_tdb, vstring);
144 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
145 /* Written on a bigendian machine with old fetch_int code. Save as le. */
146 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
147 vers_id = SHARE_DATABASE_VERSION_V2;
150 if (vers_id != SHARE_DATABASE_VERSION_V2) {
151 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
152 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
154 tdb_unlock_bystring(share_tdb, vstring);
156 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
158 return True;
161 /*******************************************************************
162 Fake up a Everyone, full access as a default.
163 ********************************************************************/
165 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
167 extern DOM_SID global_sid_World;
168 extern struct generic_mapping file_generic_mapping;
169 SEC_ACCESS sa;
170 SEC_ACE ace;
171 SEC_ACL *psa = NULL;
172 SEC_DESC *psd = NULL;
173 uint32 def_access = GENERIC_ALL_ACCESS;
175 se_map_generic(&def_access, &file_generic_mapping);
177 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
178 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
180 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
181 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
184 if (!psd) {
185 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
186 return NULL;
189 return psd;
192 /*******************************************************************
193 Pull a security descriptor from the share tdb.
194 ********************************************************************/
196 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
198 prs_struct ps;
199 fstring key;
200 SEC_DESC *psd = NULL;
202 *psize = 0;
204 /* Fetch security descriptor from tdb */
206 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
208 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
209 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
211 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
213 return get_share_security_default(ctx, snum, psize);
216 if (psd)
217 *psize = sec_desc_size(psd);
219 prs_mem_free(&ps);
220 return psd;
223 /*******************************************************************
224 Store a security descriptor in the share db.
225 ********************************************************************/
227 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
229 prs_struct ps;
230 TALLOC_CTX *mem_ctx = NULL;
231 fstring key;
232 BOOL ret = False;
234 mem_ctx = talloc_init();
235 if (mem_ctx == NULL)
236 return False;
238 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
240 if (!sec_io_desc("share_security", &psd, &ps, 1))
241 goto out;
243 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
245 if (tdb_prs_store(share_tdb, key, &ps)==0) {
246 ret = True;
247 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
248 } else {
249 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
252 /* Free malloc'ed memory */
254 out:
256 prs_mem_free(&ps);
257 if (mem_ctx)
258 talloc_destroy(mem_ctx);
259 return ret;
262 /*******************************************************************
263 Delete a security descriptor.
264 ********************************************************************/
266 static BOOL delete_share_security(int snum)
268 TDB_DATA kbuf;
269 fstring key;
271 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
272 kbuf.dptr = key;
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) ));
278 return False;
281 return True;
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;
291 int i;
292 SEC_ACL *ps_dacl = NULL;
294 if (!psd)
295 return;
297 ps_dacl = psd->dacl;
298 if (!ps_dacl)
299 return;
301 for (i = 0; i < ps_dacl->num_aces; i++) {
302 SEC_ACE *psa = &ps_dacl->ace[i];
303 uint32 orig_mask = psa->info.mask;
305 se_map_generic(&psa->info.mask, &file_generic_mapping);
306 psa->info.mask |= orig_mask;
310 /*******************************************************************
311 Can this user access with share with the required permissions ?
312 ********************************************************************/
314 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
316 uint32 granted;
317 NTSTATUS status;
318 TALLOC_CTX *mem_ctx = NULL;
319 SEC_DESC *psd = NULL;
320 size_t sd_size;
321 NT_USER_TOKEN *token = NULL;
322 BOOL ret = True;
324 mem_ctx = talloc_init();
325 if (mem_ctx == NULL)
326 return False;
328 psd = get_share_security(mem_ctx, snum, &sd_size);
330 if (!psd)
331 goto out;
333 if (vuser)
334 token = vuser->nt_user_token;
335 else
336 token = conn->nt_user_token;
338 ret = se_access_check(psd, token, desired_access, &granted, &status);
340 out:
342 talloc_destroy(mem_ctx);
344 return ret;
347 /*******************************************************************
348 Fill in a share info level 501 structure.
349 ********************************************************************/
351 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
353 int len_net_name;
354 pstring net_name;
355 pstring remark;
356 uint32 type;
358 pstrcpy(net_name, lp_servicename(snum));
359 pstrcpy(remark, lp_comment(snum));
360 standard_sub_conn(p->conn, remark, sizeof(remark));
362 len_net_name = strlen(net_name);
364 /* work out the share type */
365 type = STYPE_DISKTREE;
367 if (lp_print_ok(snum))
368 type = STYPE_PRINTQ;
369 if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name))
370 type = STYPE_IPC;
371 if (net_name[len_net_name] == '$')
372 type |= STYPE_HIDDEN;
374 init_srv_share_info501(&sh501->info_501, net_name, type, remark, (lp_csc_policy(snum) << 4));
375 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
378 /*******************************************************************
379 Fill in a share info level 502 structure.
380 ********************************************************************/
382 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
384 int len_net_name;
385 pstring net_name;
386 pstring remark;
387 pstring path;
388 pstring passwd;
389 uint32 type;
390 SEC_DESC *sd;
391 size_t sd_size;
392 TALLOC_CTX *ctx = p->mem_ctx;
395 ZERO_STRUCTP(sh502);
397 pstrcpy(net_name, lp_servicename(snum));
398 pstrcpy(remark, lp_comment(snum));
399 standard_sub_conn(p->conn, remark,sizeof(remark));
400 pstrcpy(path, "C:");
401 pstrcat(path, lp_pathname(snum));
404 * Change / to \\ so that win2k will see it as a valid path. This was added to
405 * enable use of browsing in win2k add share dialog.
408 string_replace(path, '/', '\\');
410 pstrcpy(passwd, "");
411 len_net_name = strlen(net_name);
413 /* work out the share type */
414 type = STYPE_DISKTREE;
416 if (lp_print_ok(snum))
417 type = STYPE_PRINTQ;
418 if (strequal("IPC$", net_name))
419 type = STYPE_IPC;
420 if (net_name[len_net_name] == '$')
421 type |= STYPE_HIDDEN;
423 sd = get_share_security(ctx, snum, &sd_size);
425 init_srv_share_info502(&sh502->info_502, net_name, type, remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
426 init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
429 /***************************************************************************
430 Fill in a share info level 1005 structure.
431 ***************************************************************************/
433 static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
435 sh1005->dfs_root_flag = 0;
437 if(lp_host_msdfs() && lp_msdfs_root(snum))
438 sh1005->dfs_root_flag = 3;
441 /*******************************************************************
442 True if it ends in '$'.
443 ********************************************************************/
445 static BOOL is_admin_share(int snum)
447 pstring net_name;
449 pstrcpy(net_name, lp_servicename(snum));
450 return (net_name[strlen(net_name)] == '$') ? True : False;
453 /*******************************************************************
454 Fill in a share info structure.
455 ********************************************************************/
457 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
458 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
460 int num_entries = 0;
461 int num_services = lp_numservices();
462 int snum;
463 TALLOC_CTX *ctx = p->mem_ctx;
465 DEBUG(5,("init_srv_share_info_ctr\n"));
467 ZERO_STRUCTPN(ctr);
469 ctr->info_level = ctr->switch_value = info_level;
470 *resume_hnd = 0;
472 /* Count the number of entries. */
473 for (snum = 0; snum < num_services; snum++) {
474 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) )
475 num_entries++;
478 *total_entries = num_entries;
479 ctr->num_entries2 = ctr->num_entries = num_entries;
480 ctr->ptr_share_info = ctr->ptr_entries = 1;
482 if (!num_entries)
483 return True;
485 switch (info_level) {
486 case 1:
488 SRV_SHARE_INFO_1 *info1;
489 int i = 0;
491 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
493 for (snum = *resume_hnd; snum < num_services; snum++) {
494 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
495 init_srv_share_info_1(p, &info1[i++], snum);
499 ctr->share.info1 = info1;
500 break;
503 case 2:
505 SRV_SHARE_INFO_2 *info2;
506 int i = 0;
508 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
510 for (snum = *resume_hnd; snum < num_services; snum++) {
511 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
512 init_srv_share_info_2(p, &info2[i++], snum);
516 ctr->share.info2 = info2;
517 break;
520 case 501:
522 SRV_SHARE_INFO_501 *info501;
523 int i = 0;
525 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
527 for (snum = *resume_hnd; snum < num_services; snum++) {
528 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
529 init_srv_share_info_501(p, &info501[i++], snum);
533 ctr->share.info501 = info501;
534 break;
537 case 502:
539 SRV_SHARE_INFO_502 *info502;
540 int i = 0;
542 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
544 for (snum = *resume_hnd; snum < num_services; snum++) {
545 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
546 init_srv_share_info_502(p, &info502[i++], snum);
550 ctr->share.info502 = info502;
551 break;
554 default:
555 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
556 return False;
559 return True;
562 /*******************************************************************
563 Inits a SRV_R_NET_SHARE_ENUM structure.
564 ********************************************************************/
566 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
567 uint32 info_level, uint32 resume_hnd, BOOL all)
569 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
571 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
572 &resume_hnd, &r_n->total_entries, all)) {
573 r_n->status = WERR_OK;
574 } else {
575 r_n->status = WERR_UNKNOWN_LEVEL;
578 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
581 /*******************************************************************
582 Inits a SRV_R_NET_SHARE_GET_INFO structure.
583 ********************************************************************/
585 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
586 char *share_name, uint32 info_level)
588 WERROR status = WERR_OK;
589 int snum;
591 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
593 r_n->info.switch_value = info_level;
595 snum = find_service(share_name);
597 if (snum >= 0) {
598 switch (info_level) {
599 case 1:
600 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
601 break;
602 case 2:
603 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
604 break;
605 case 501:
606 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
607 break;
608 case 502:
609 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
610 break;
611 case 1005:
612 init_srv_share_info_1005(&r_n->info.share.info1005, snum);
613 break;
614 default:
615 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
616 status = WERR_UNKNOWN_LEVEL;
617 break;
619 } else {
620 status = WERR_INVALID_NAME;
623 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
624 r_n->status = status;
627 /*******************************************************************
628 fill in a sess info level 1 structure.
629 ********************************************************************/
631 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
633 init_srv_sess_info0(se0, name);
634 init_srv_sess_info0_str(str0, name);
637 /*******************************************************************
638 fill in a sess info level 0 structure.
639 ********************************************************************/
641 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
643 struct sessionid *session_list;
644 uint32 num_entries = 0;
645 (*stot) = list_sessions(&session_list);
647 if (ss0 == NULL) {
648 (*snum) = 0;
649 SAFE_FREE(session_list);
650 return;
653 DEBUG(5,("init_srv_sess_0_ss0\n"));
655 if (snum) {
656 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
657 init_srv_sess_0_info(&ss0->info_0[num_entries],
658 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
660 /* move on to creating next session */
661 /* move on to creating next sess */
662 num_entries++;
665 ss0->num_entries_read = num_entries;
666 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
667 ss0->num_entries_read2 = num_entries;
669 if ((*snum) >= (*stot)) {
670 (*snum) = 0;
673 } else {
674 ss0->num_entries_read = 0;
675 ss0->ptr_sess_info = 0;
676 ss0->num_entries_read2 = 0;
678 SAFE_FREE(session_list);
681 /*******************************************************************
682 fill in a sess info level 1 structure.
683 ********************************************************************/
685 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
686 char *name, char *user,
687 uint32 num_opens,
688 uint32 open_time, uint32 idle_time,
689 uint32 usr_flgs)
691 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
692 init_srv_sess_info1_str(str1, name, user);
695 /*******************************************************************
696 fill in a sess info level 1 structure.
697 ********************************************************************/
699 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
701 struct sessionid *session_list;
702 uint32 num_entries = 0;
703 (*stot) = list_sessions(&session_list);
705 if (ss1 == NULL) {
706 (*snum) = 0;
707 SAFE_FREE(session_list);
708 return;
711 DEBUG(5,("init_srv_sess_1_ss1\n"));
713 if (snum) {
714 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
715 init_srv_sess_1_info(&ss1->info_1[num_entries],
716 &ss1->info_1_str[num_entries],
717 session_list[*snum].remote_machine,
718 session_list[*snum].username,
719 1, 10, 5, 0);
721 /* move on to creating next session */
722 /* move on to creating next sess */
723 num_entries++;
726 ss1->num_entries_read = num_entries;
727 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
728 ss1->num_entries_read2 = num_entries;
730 if ((*snum) >= (*stot)) {
731 (*snum) = 0;
734 } else {
735 ss1->num_entries_read = 0;
736 ss1->ptr_sess_info = 0;
737 ss1->num_entries_read2 = 0;
739 (*stot) = 0;
743 /*******************************************************************
744 makes a SRV_R_NET_SESS_ENUM structure.
745 ********************************************************************/
747 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
748 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
750 WERROR status = WERR_OK;
751 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
753 ctr->switch_value = switch_value;
755 switch (switch_value) {
756 case 0:
757 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
758 ctr->ptr_sess_ctr = 1;
759 break;
760 case 1:
761 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
762 ctr->ptr_sess_ctr = 1;
763 break;
764 default:
765 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
766 (*resume_hnd) = 0;
767 (*total_entries) = 0;
768 ctr->ptr_sess_ctr = 0;
769 status = WERR_UNKNOWN_LEVEL;
770 break;
773 return status;
776 /*******************************************************************
777 makes a SRV_R_NET_SESS_ENUM structure.
778 ********************************************************************/
780 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
781 uint32 resume_hnd, int sess_level, int switch_value)
783 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
785 r_n->sess_level = sess_level;
787 if (sess_level == -1)
788 r_n->status = WERR_UNKNOWN_LEVEL;
789 else
790 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
792 if (!W_ERROR_IS_OK(r_n->status))
793 resume_hnd = 0;
795 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
798 /*******************************************************************
799 fill in a conn info level 0 structure.
800 ********************************************************************/
802 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
804 uint32 num_entries = 0;
805 (*stot) = 1;
807 if (ss0 == NULL) {
808 (*snum) = 0;
809 return;
812 DEBUG(5,("init_srv_conn_0_ss0\n"));
814 if (snum) {
815 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
817 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
819 /* move on to creating next connection */
820 /* move on to creating next conn */
821 num_entries++;
824 ss0->num_entries_read = num_entries;
825 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
826 ss0->num_entries_read2 = num_entries;
828 if ((*snum) >= (*stot)) {
829 (*snum) = 0;
832 } else {
833 ss0->num_entries_read = 0;
834 ss0->ptr_conn_info = 0;
835 ss0->num_entries_read2 = 0;
837 (*stot) = 0;
841 /*******************************************************************
842 fill in a conn info level 1 structure.
843 ********************************************************************/
845 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
846 uint32 id, uint32 type,
847 uint32 num_opens, uint32 num_users, uint32 open_time,
848 char *usr_name, char *net_name)
850 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
851 init_srv_conn_info1_str(str1, usr_name, net_name);
854 /*******************************************************************
855 fill in a conn info level 1 structure.
856 ********************************************************************/
858 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
860 uint32 num_entries = 0;
861 (*stot) = 1;
863 if (ss1 == NULL) {
864 (*snum) = 0;
865 return;
868 DEBUG(5,("init_srv_conn_1_ss1\n"));
870 if (snum) {
871 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
872 init_srv_conn_1_info(&ss1->info_1[num_entries],
873 &ss1->info_1_str[num_entries],
874 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
876 /* move on to creating next connection */
877 /* move on to creating next conn */
878 num_entries++;
881 ss1->num_entries_read = num_entries;
882 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
883 ss1->num_entries_read2 = num_entries;
886 if ((*snum) >= (*stot)) {
887 (*snum) = 0;
890 } else {
891 ss1->num_entries_read = 0;
892 ss1->ptr_conn_info = 0;
893 ss1->num_entries_read2 = 0;
895 (*stot) = 0;
899 /*******************************************************************
900 makes a SRV_R_NET_CONN_ENUM structure.
901 ********************************************************************/
903 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
904 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
906 WERROR status = WERR_OK;
907 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
909 ctr->switch_value = switch_value;
911 switch (switch_value) {
912 case 0:
913 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
914 ctr->ptr_conn_ctr = 1;
915 break;
916 case 1:
917 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
918 ctr->ptr_conn_ctr = 1;
919 break;
920 default:
921 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
922 (*resume_hnd = 0);
923 (*total_entries) = 0;
924 ctr->ptr_conn_ctr = 0;
925 status = WERR_UNKNOWN_LEVEL;
926 break;
929 return status;
932 /*******************************************************************
933 makes a SRV_R_NET_CONN_ENUM structure.
934 ********************************************************************/
936 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
937 uint32 resume_hnd, int conn_level, int switch_value)
939 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
941 r_n->conn_level = conn_level;
942 if (conn_level == -1)
943 r_n->status = WERR_UNKNOWN_LEVEL;
944 else
945 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
947 if (!W_ERROR_IS_OK(r_n->status))
948 resume_hnd = 0;
950 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
953 /*******************************************************************
954 makes a SRV_R_NET_FILE_ENUM structure.
955 ********************************************************************/
957 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
958 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
960 WERROR status = WERR_OK;
961 TALLOC_CTX *ctx = p->mem_ctx;
962 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
963 *total_entries = 1; /* dummy entries only, for */
965 ctr->switch_value = switch_value;
966 ctr->num_entries = *total_entries - *resume_hnd;
967 ctr->num_entries2 = ctr->num_entries;
969 switch (switch_value) {
970 case 3: {
971 int i;
972 if (*total_entries > 0) {
973 ctr->ptr_entries = 1;
974 ctr->file.info3 = talloc(ctx, ctr->num_entries *
975 sizeof(SRV_FILE_INFO_3));
977 for (i=0 ;i<ctr->num_entries;i++) {
978 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
979 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
982 ctr->ptr_file_info = 1;
983 *resume_hnd = 0;
984 break;
986 default:
987 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
988 (*resume_hnd = 0);
989 (*total_entries) = 0;
990 ctr->ptr_entries = 0;
991 status = WERR_UNKNOWN_LEVEL;
992 break;
995 return status;
998 /*******************************************************************
999 makes a SRV_R_NET_FILE_ENUM structure.
1000 ********************************************************************/
1002 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1003 uint32 resume_hnd, int file_level, int switch_value)
1005 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1007 r_n->file_level = file_level;
1008 if (file_level == 0)
1009 r_n->status = WERR_UNKNOWN_LEVEL;
1010 else
1011 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1013 if (!W_ERROR_IS_OK(r_n->status))
1014 resume_hnd = 0;
1016 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1019 /*******************************************************************
1020 net server get info
1021 ********************************************************************/
1023 WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
1025 WERROR status = WERR_OK;
1026 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1028 if (!ctr)
1029 return WERR_NOMEM;
1031 ZERO_STRUCTP(ctr);
1033 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1035 if (!pipe_access_check(p)) {
1036 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1037 return WERR_ACCESS_DENIED;
1040 switch (q_u->switch_value) {
1042 /* Technically level 102 should only be available to
1043 Administrators but there isn't anything super-secret
1044 here, as most of it is made up. */
1046 case 102:
1047 init_srv_info_102(&ctr->srv.sv102,
1048 500, global_myname,
1049 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1050 lp_major_announce_version(), lp_minor_announce_version(),
1051 lp_default_server_announce(),
1052 0xffffffff, /* users */
1053 0xf, /* disc */
1054 0, /* hidden */
1055 240, /* announce */
1056 3000, /* announce delta */
1057 100000, /* licenses */
1058 "c:\\"); /* user path */
1059 break;
1060 case 101:
1061 init_srv_info_101(&ctr->srv.sv101,
1062 500, global_myname,
1063 lp_major_announce_version(), lp_minor_announce_version(),
1064 lp_default_server_announce(),
1065 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1066 break;
1067 case 100:
1068 init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
1069 break;
1070 default:
1071 status = WERR_UNKNOWN_LEVEL;
1072 break;
1075 /* set up the net server get info structure */
1076 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1078 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1080 return r_u->status;
1083 /*******************************************************************
1084 net server set info
1085 ********************************************************************/
1087 WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1089 WERROR status = WERR_OK;
1091 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1093 /* Set up the net server set info structure. */
1095 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1097 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1099 return r_u->status;
1102 /*******************************************************************
1103 net file enum
1104 ********************************************************************/
1106 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1108 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1110 /* set up the */
1111 init_srv_r_net_file_enum(p, r_u,
1112 get_enum_hnd(&q_u->enum_hnd),
1113 q_u->file_level,
1114 q_u->ctr.switch_value);
1116 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1118 return r_u->status;
1121 /*******************************************************************
1122 net conn enum
1123 ********************************************************************/
1125 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1127 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1129 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1130 if (!r_u->ctr)
1131 return WERR_NOMEM;
1133 ZERO_STRUCTP(r_u->ctr);
1135 /* set up the */
1136 init_srv_r_net_conn_enum(r_u,
1137 get_enum_hnd(&q_u->enum_hnd),
1138 q_u->conn_level,
1139 q_u->ctr->switch_value);
1141 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1143 return r_u->status;
1146 /*******************************************************************
1147 net sess enum
1148 ********************************************************************/
1150 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1152 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1154 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1155 if (!r_u->ctr)
1156 return WERR_NOMEM;
1158 ZERO_STRUCTP(r_u->ctr);
1160 /* set up the */
1161 init_srv_r_net_sess_enum(r_u,
1162 get_enum_hnd(&q_u->enum_hnd),
1163 q_u->sess_level,
1164 q_u->ctr->switch_value);
1166 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1168 return r_u->status;
1171 /*******************************************************************
1172 Net share enum all.
1173 ********************************************************************/
1175 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1177 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1179 if (!pipe_access_check(p)) {
1180 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1181 return WERR_ACCESS_DENIED;
1184 /* Create the list of shares for the response. */
1185 init_srv_r_net_share_enum(p, r_u,
1186 q_u->ctr.info_level,
1187 get_enum_hnd(&q_u->enum_hnd), True);
1189 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1191 return r_u->status;
1194 /*******************************************************************
1195 Net share enum.
1196 ********************************************************************/
1198 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1200 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1202 if (!pipe_access_check(p)) {
1203 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1204 return WERR_ACCESS_DENIED;
1207 /* Create the list of shares for the response. */
1208 init_srv_r_net_share_enum(p, r_u,
1209 q_u->ctr.info_level,
1210 get_enum_hnd(&q_u->enum_hnd), False);
1212 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1214 return r_u->status;
1217 /*******************************************************************
1218 Net share get info.
1219 ********************************************************************/
1221 WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1223 fstring share_name;
1225 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1227 /* Create the list of shares for the response. */
1228 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1229 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1231 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1233 return r_u->status;
1236 /*******************************************************************
1237 Check a given DOS pathname is valid for a share.
1238 ********************************************************************/
1240 static char *valid_share_pathname(char *dos_pathname)
1242 pstring saved_pathname;
1243 pstring unix_pathname;
1244 char *ptr;
1245 int ret;
1247 /* Convert any '\' paths to '/' */
1248 unix_format(dos_pathname);
1249 unix_clean_name(dos_pathname);
1251 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1252 ptr = dos_pathname;
1253 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1254 ptr += 2;
1256 /* Only abolute paths allowed. */
1257 if (*ptr != '/')
1258 return NULL;
1260 /* Can we cd to it ? */
1262 /* First save our current directory. */
1263 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1264 return False;
1266 pstrcpy(unix_pathname, ptr);
1268 ret = chdir(unix_pathname);
1270 /* We *MUST* be able to chdir back. Abort if we can't. */
1271 if (chdir(saved_pathname) == -1)
1272 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1274 return (ret != -1) ? ptr : NULL;
1277 /*******************************************************************
1278 Net share set info. Modify share details.
1279 ********************************************************************/
1281 WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1283 struct current_user user;
1284 pstring command;
1285 fstring share_name;
1286 fstring comment;
1287 pstring pathname;
1288 int type;
1289 int snum;
1290 int ret;
1291 char *ptr;
1292 SEC_DESC *psd = NULL;
1294 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1296 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1298 r_u->switch_value = 0;
1300 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1301 return WERR_ACCESS_DENIED;
1303 snum = find_service(share_name);
1305 /* Does this share exist ? */
1306 if (snum < 0)
1307 return WERR_INVALID_NAME;
1309 /* No change to printer shares. */
1310 if (lp_print_ok(snum))
1311 return WERR_ACCESS_DENIED;
1313 get_current_user(&user,p);
1315 if (user.uid != 0)
1316 return WERR_ACCESS_DENIED;
1318 switch (q_u->info_level) {
1319 case 1:
1320 /* Not enough info in a level 1 to do anything. */
1321 return WERR_ACCESS_DENIED;
1322 case 2:
1323 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1324 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1325 type = q_u->info.share.info2.info_2.type;
1326 psd = NULL;
1327 break;
1328 case 502:
1329 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1330 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1331 type = q_u->info.share.info502.info_502.type;
1332 psd = q_u->info.share.info502.info_502_str.sd;
1333 map_generic_share_sd_bits(psd);
1334 break;
1335 case 1005:
1336 return WERR_ACCESS_DENIED;
1337 case 1501:
1338 fstrcpy(pathname, lp_pathname(snum));
1339 fstrcpy(comment, lp_comment(snum));
1340 psd = q_u->info.share.info1501.sdb->sec;
1341 map_generic_share_sd_bits(psd);
1342 type = STYPE_DISKTREE;
1343 break;
1344 default:
1345 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1346 return WERR_UNKNOWN_LEVEL;
1349 /* We can only modify disk shares. */
1350 if (type != STYPE_DISKTREE)
1351 return WERR_ACCESS_DENIED;
1353 /* Check if the pathname is valid. */
1354 if (!(ptr = valid_share_pathname( pathname )))
1355 return WERR_OBJECT_PATH_INVALID;
1357 /* Ensure share name, pathname and comment don't contain '"' characters. */
1358 string_replace(share_name, '"', ' ');
1359 string_replace(ptr, '"', ' ');
1360 string_replace(comment, '"', ' ');
1362 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1363 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1365 /* Only call modify function if something changed. */
1367 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1368 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1369 return WERR_ACCESS_DENIED;
1371 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1372 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1374 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1375 if ((ret = smbrun(command, NULL)) != 0) {
1376 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1377 return WERR_ACCESS_DENIED;
1380 /* Tell everyone we updated smb.conf. */
1381 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1383 } else {
1384 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1387 /* Replace SD if changed. */
1388 if (psd) {
1389 SEC_DESC *old_sd;
1390 size_t sd_size;
1392 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1394 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1395 if (!set_share_security(p->mem_ctx, share_name, psd))
1396 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1397 share_name ));
1401 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1403 return WERR_OK;
1406 /*******************************************************************
1407 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1408 ********************************************************************/
1410 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1412 struct current_user user;
1413 pstring command;
1414 fstring share_name;
1415 fstring comment;
1416 pstring pathname;
1417 int type;
1418 int snum;
1419 int ret;
1420 char *ptr;
1421 SEC_DESC *psd = NULL;
1423 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1425 r_u->switch_value = 0;
1427 get_current_user(&user,p);
1429 if (user.uid != 0) {
1430 DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
1431 return WERR_ACCESS_DENIED;
1434 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1435 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1436 return WERR_ACCESS_DENIED;
1439 switch (q_u->info_level) {
1440 case 1:
1441 /* Not enough info in a level 1 to do anything. */
1442 return WERR_ACCESS_DENIED;
1443 case 2:
1444 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1445 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1446 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1447 type = q_u->info.share.info2.info_2.type;
1448 break;
1449 case 502:
1450 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1451 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1452 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1453 type = q_u->info.share.info502.info_502.type;
1454 psd = q_u->info.share.info502.info_502_str.sd;
1455 map_generic_share_sd_bits(psd);
1456 break;
1457 case 1005:
1458 /* DFS only level. */
1459 return WERR_ACCESS_DENIED;
1460 default:
1461 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1462 return WERR_UNKNOWN_LEVEL;
1465 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1466 return WERR_ACCESS_DENIED;
1468 snum = find_service(share_name);
1470 /* Share already exists. */
1471 if (snum >= 0)
1472 return WERR_ALREADY_EXISTS;
1474 /* We can only add disk shares. */
1475 if (type != STYPE_DISKTREE)
1476 return WERR_ACCESS_DENIED;
1478 /* Check if the pathname is valid. */
1479 if (!(ptr = valid_share_pathname( pathname )))
1480 return WERR_OBJECT_PATH_INVALID;
1482 /* Ensure share name, pathname and comment don't contain '"' characters. */
1483 string_replace(share_name, '"', ' ');
1484 string_replace(ptr, '"', ' ');
1485 string_replace(comment, '"', ' ');
1487 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1488 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1490 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1491 if ((ret = smbrun(command, NULL)) != 0) {
1492 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1493 return WERR_ACCESS_DENIED;
1496 if (psd) {
1497 if (!set_share_security(p->mem_ctx, share_name, psd))
1498 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1499 share_name ));
1502 /* Tell everyone we updated smb.conf. */
1503 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1506 * We don't call reload_services() here, the message will
1507 * cause this to be done before the next packet is read
1508 * from the client. JRA.
1511 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1513 return WERR_OK;
1516 /*******************************************************************
1517 Net share delete. Call "delete share command" with the share name as
1518 a parameter.
1519 ********************************************************************/
1521 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1523 struct current_user user;
1524 pstring command;
1525 fstring share_name;
1526 int ret;
1527 int snum;
1529 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1531 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1533 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1534 return WERR_ACCESS_DENIED;
1536 snum = find_service(share_name);
1538 if (snum < 0)
1539 return WERR_NO_SUCH_SHARE;
1541 /* No change to printer shares. */
1542 if (lp_print_ok(snum))
1543 return WERR_ACCESS_DENIED;
1545 get_current_user(&user,p);
1547 if (user.uid != 0)
1548 return WERR_ACCESS_DENIED;
1550 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1551 return WERR_ACCESS_DENIED;
1553 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1554 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1556 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1557 if ((ret = smbrun(command, NULL)) != 0) {
1558 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1559 return WERR_ACCESS_DENIED;
1562 /* Delete the SD in the database. */
1563 delete_share_security(snum);
1565 /* Tell everyone we updated smb.conf. */
1566 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1568 lp_killservice(snum);
1570 return WERR_OK;
1573 /*******************************************************************
1574 time of day
1575 ********************************************************************/
1577 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1579 TIME_OF_DAY_INFO *tod;
1580 struct tm *t;
1581 time_t unixdate = time(NULL);
1583 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1584 if (!tod)
1585 return WERR_NOMEM;
1587 ZERO_STRUCTP(tod);
1589 r_u->tod = tod;
1590 r_u->ptr_srv_tod = 0x1;
1591 r_u->status = WERR_OK;
1593 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1595 t = gmtime(&unixdate);
1597 /* set up the */
1598 init_time_of_day_info(tod,
1599 unixdate,
1601 t->tm_hour,
1602 t->tm_min,
1603 t->tm_sec,
1605 TimeDiff(unixdate)/60,
1606 10000,
1607 t->tm_mday,
1608 t->tm_mon + 1,
1609 1900+t->tm_year,
1610 t->tm_wday);
1612 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1614 return r_u->status;
1617 /***********************************************************************************
1618 Win9x NT tools get security descriptor.
1619 ***********************************************************************************/
1621 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1622 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1624 SEC_DESC *psd = NULL;
1625 size_t sd_size;
1626 DATA_BLOB null_pw;
1627 pstring filename;
1628 pstring qualname;
1629 files_struct *fsp = NULL;
1630 SMB_STRUCT_STAT st;
1631 BOOL bad_path;
1632 int access_mode;
1633 int action;
1634 NTSTATUS nt_status;
1635 struct current_user user;
1636 connection_struct *conn = NULL;
1637 BOOL became_user = False;
1639 ZERO_STRUCT(st);
1641 r_u->status = WERR_OK;
1643 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1645 /* Null password is ok - we are already an authenticated user... */
1646 null_pw = data_blob(NULL, 0);
1648 get_current_user(&user, p);
1650 become_root();
1651 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1652 unbecome_root();
1654 if (conn == NULL) {
1655 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1656 r_u->status = ntstatus_to_werror(nt_status);
1657 goto error_exit;
1660 if (!become_user(conn, conn->vuid)) {
1661 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1662 r_u->status = WERR_ACCESS_DENIED;
1663 goto error_exit;
1665 became_user = True;
1667 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1668 unix_convert(filename, conn, NULL, &bad_path, &st);
1669 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1670 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1672 if (!fsp) {
1673 /* Perhaps it is a directory */
1674 if (errno == EISDIR)
1675 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1676 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1678 if (!fsp) {
1679 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1680 r_u->status = WERR_ACCESS_DENIED;
1681 goto error_exit;
1685 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1687 if (sd_size == 0) {
1688 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1689 r_u->status = WERR_ACCESS_DENIED;
1690 goto error_exit;
1693 r_u->ptr_response = 1;
1694 r_u->size_response = sd_size;
1695 r_u->ptr_secdesc = 1;
1696 r_u->size_secdesc = sd_size;
1697 r_u->sec_desc = psd;
1699 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1701 close_file(fsp, True);
1702 unbecome_user();
1703 close_cnum(conn, user.vuid);
1704 return r_u->status;
1706 error_exit:
1708 if(fsp) {
1709 close_file(fsp, True);
1712 if (became_user)
1713 unbecome_user();
1715 if (conn)
1716 close_cnum(conn, user.vuid);
1718 return r_u->status;
1721 /***********************************************************************************
1722 Win9x NT tools set security descriptor.
1723 ***********************************************************************************/
1725 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1726 SRV_R_NET_FILE_SET_SECDESC *r_u)
1728 BOOL ret;
1729 pstring filename;
1730 pstring qualname;
1731 DATA_BLOB null_pw;
1732 files_struct *fsp = NULL;
1733 SMB_STRUCT_STAT st;
1734 BOOL bad_path;
1735 int access_mode;
1736 int action;
1737 NTSTATUS nt_status;
1738 struct current_user user;
1739 connection_struct *conn = NULL;
1740 BOOL became_user = False;
1742 ZERO_STRUCT(st);
1744 r_u->status = WERR_OK;
1746 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1748 /* Null password is ok - we are already an authenticated user... */
1749 null_pw = data_blob(NULL, 0);
1751 get_current_user(&user, p);
1753 become_root();
1754 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1755 unbecome_root();
1757 if (conn == NULL) {
1758 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1759 r_u->status = ntstatus_to_werror(nt_status);
1760 goto error_exit;
1763 if (!become_user(conn, conn->vuid)) {
1764 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1765 r_u->status = WERR_ACCESS_DENIED;
1766 goto error_exit;
1768 became_user = True;
1770 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1771 unix_convert(filename, conn, NULL, &bad_path, &st);
1773 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1774 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1776 if (!fsp) {
1777 /* Perhaps it is a directory */
1778 if (errno == EISDIR)
1779 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1780 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1782 if (!fsp) {
1783 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1784 r_u->status = WERR_ACCESS_DENIED;
1785 goto error_exit;
1789 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1791 if (ret == False) {
1792 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1793 r_u->status = WERR_ACCESS_DENIED;
1794 goto error_exit;
1797 close_file(fsp, True);
1798 unbecome_user();
1799 close_cnum(conn, user.vuid);
1800 return r_u->status;
1802 error_exit:
1804 if(fsp) {
1805 close_file(fsp, True);
1808 if (became_user)
1809 unbecome_user();
1811 if (conn)
1812 close_cnum(conn, user.vuid);
1814 return r_u->status;
1817 /***********************************************************************************
1818 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
1819 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
1820 These disks would the disks listed by this function.
1821 Users could then create shares relative to these disks. Watch out for moving these disks around.
1822 "Nigel Williams" <nigel@veritas.com>.
1823 ***********************************************************************************/
1825 static const char *server_disks[] = {"C:"};
1827 static uint32 get_server_disk_count(void)
1829 return sizeof(server_disks)/sizeof(server_disks[0]);
1832 static uint32 init_server_disk_enum(uint32 *resume)
1834 uint32 server_disk_count = get_server_disk_count();
1836 /*resume can be an offset into the list for now*/
1838 if(*resume & 0x80000000)
1839 *resume = 0;
1841 if(*resume > server_disk_count)
1842 *resume = server_disk_count;
1844 return server_disk_count - *resume;
1847 static const char *next_server_disk_enum(uint32 *resume)
1849 const char *disk;
1851 if(init_server_disk_enum(resume) == 0)
1852 return NULL;
1854 disk = server_disks[*resume];
1856 (*resume)++;
1858 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
1860 return disk;
1863 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
1865 uint32 i;
1866 const char *disk_name;
1867 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
1869 r_u->status=WERR_OK;
1871 r_u->total_entries = init_server_disk_enum(&resume);
1873 r_u->disk_enum_ctr.unknown = 0;
1875 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
1877 /*allow one DISK_INFO for null terminator*/
1879 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
1881 r_u->disk_enum_ctr.entries_read++;
1883 /*copy disk name into a unicode string*/
1885 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
1888 /*add a terminating null string. Is this there if there is more data to come?*/
1890 r_u->disk_enum_ctr.entries_read++;
1892 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
1894 init_enum_hnd(&r_u->enum_hnd, resume);
1896 return r_u->status;
1899 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
1901 int snum;
1902 fstring share_name;
1904 r_u->status=WERR_OK;
1906 switch(q_u->type) {
1908 case 0x9:
1910 /*check if share name is ok*/
1911 /*also check if we already have a share with this name*/
1913 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
1914 snum = find_service(share_name);
1916 /* Share already exists. */
1917 if (snum >= 0)
1918 r_u->status = WERR_ALREADY_EXISTS;
1919 break;
1921 default:
1922 /*unsupported type*/
1923 r_u->status = WERR_UNKNOWN_LEVEL;
1924 break;
1927 return r_u->status;