Prefix VFS API macros with SMB_ for consistency and to avoid problems with VFS_ macro...
[Samba/gebeck_regimport.git] / source / rpc_server / srv_srvsvc_nt.c
blob154376dd3366e1daf405110b4d474e063df78e42
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 * Copyright (C) Nigel Williams 2001.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* This is the implementation of the srvsvc pipe. */
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_SRV
30 /*******************************************************************
31 Utility function to get the 'type' of a share from an snum.
32 ********************************************************************/
33 static uint32 get_share_type(int snum)
35 char *net_name = lp_servicename(snum);
36 int len_net_name = strlen(net_name);
38 /* work out the share type */
39 uint32 type = STYPE_DISKTREE;
41 if (lp_print_ok(snum))
42 type = STYPE_PRINTQ;
43 if (strequal(lp_fstype(snum), "IPC"))
44 type = STYPE_IPC;
45 if (net_name[len_net_name] == '$')
46 type |= STYPE_HIDDEN;
48 return type;
51 /*******************************************************************
52 Fill in a share info level 0 structure.
53 ********************************************************************/
55 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
57 pstring net_name;
59 pstrcpy(net_name, lp_servicename(snum));
61 init_srv_share_info0(&sh0->info_0, net_name);
62 init_srv_share_info0_str(&sh0->info_0_str, net_name);
65 /*******************************************************************
66 Fill in a share info level 1 structure.
67 ********************************************************************/
69 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
71 pstring remark;
73 char *net_name = lp_servicename(snum);
74 pstrcpy(remark, lp_comment(snum));
75 standard_sub_conn(p->conn, remark,sizeof(remark));
77 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
78 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
81 /*******************************************************************
82 Fill in a share info level 2 structure.
83 ********************************************************************/
85 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
87 pstring remark;
88 pstring path;
89 pstring passwd;
91 char *net_name = lp_servicename(snum);
92 pstrcpy(remark, lp_comment(snum));
93 standard_sub_conn(p->conn, remark,sizeof(remark));
94 pstrcpy(path, "C:");
95 pstrcat(path, lp_pathname(snum));
98 * Change / to \\ so that win2k will see it as a valid path. This was added to
99 * enable use of browsing in win2k add share dialog.
102 string_replace(path, '/', '\\');
104 pstrcpy(passwd, "");
106 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
107 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
110 /*******************************************************************
111 What to do when smb.conf is updated.
112 ********************************************************************/
114 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
116 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
117 reload_services(False);
120 /*******************************************************************
121 Create the share security tdb.
122 ********************************************************************/
124 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
125 #define SHARE_DATABASE_VERSION_V1 1
126 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
128 BOOL share_info_db_init(void)
130 static pid_t local_pid;
131 const char *vstring = "INFO/version";
132 int32 vers_id;
134 if (share_tdb && local_pid == sys_getpid())
135 return True;
136 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
137 if (!share_tdb) {
138 DEBUG(0,("Failed to open share info database %s (%s)\n",
139 lock_path("share_info.tdb"), strerror(errno) ));
140 return False;
143 local_pid = sys_getpid();
145 /* handle a Samba upgrade */
146 tdb_lock_bystring(share_tdb, vstring, 0);
148 /* Cope with byte-reversed older versions of the db. */
149 vers_id = tdb_fetch_int32(share_tdb, vstring);
150 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
151 /* Written on a bigendian machine with old fetch_int code. Save as le. */
152 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
153 vers_id = SHARE_DATABASE_VERSION_V2;
156 if (vers_id != SHARE_DATABASE_VERSION_V2) {
157 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
158 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
160 tdb_unlock_bystring(share_tdb, vstring);
162 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
164 return True;
167 /*******************************************************************
168 Fake up a Everyone, full access as a default.
169 ********************************************************************/
171 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
173 extern DOM_SID global_sid_World;
174 extern struct generic_mapping file_generic_mapping;
175 SEC_ACCESS sa;
176 SEC_ACE ace;
177 SEC_ACL *psa = NULL;
178 SEC_DESC *psd = NULL;
179 uint32 def_access = GENERIC_ALL_ACCESS;
181 se_map_generic(&def_access, &file_generic_mapping);
183 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
184 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
186 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
187 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
190 if (!psd) {
191 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
192 return NULL;
195 return psd;
198 /*******************************************************************
199 Pull a security descriptor from the share tdb.
200 ********************************************************************/
202 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
204 prs_struct ps;
205 fstring key;
206 SEC_DESC *psd = NULL;
208 *psize = 0;
210 /* Fetch security descriptor from tdb */
212 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
214 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
215 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
217 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
219 return get_share_security_default(ctx, snum, psize);
222 if (psd)
223 *psize = sec_desc_size(psd);
225 prs_mem_free(&ps);
226 return psd;
229 /*******************************************************************
230 Store a security descriptor in the share db.
231 ********************************************************************/
233 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
235 prs_struct ps;
236 TALLOC_CTX *mem_ctx = NULL;
237 fstring key;
238 BOOL ret = False;
240 mem_ctx = talloc_init("set_share_security");
241 if (mem_ctx == NULL)
242 return False;
244 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
246 if (!sec_io_desc("share_security", &psd, &ps, 1))
247 goto out;
249 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
251 if (tdb_prs_store(share_tdb, key, &ps)==0) {
252 ret = True;
253 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
254 } else {
255 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
258 /* Free malloc'ed memory */
260 out:
262 prs_mem_free(&ps);
263 if (mem_ctx)
264 talloc_destroy(mem_ctx);
265 return ret;
268 /*******************************************************************
269 Delete a security descriptor.
270 ********************************************************************/
272 static BOOL delete_share_security(int snum)
274 TDB_DATA kbuf;
275 fstring key;
277 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
278 kbuf.dptr = key;
279 kbuf.dsize = strlen(key)+1;
281 if (tdb_delete(share_tdb, kbuf) != 0) {
282 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
283 lp_servicename(snum) ));
284 return False;
287 return True;
290 /*******************************************************************
291 Map any generic bits to file specific bits.
292 ********************************************************************/
294 void map_generic_share_sd_bits(SEC_DESC *psd)
296 extern struct generic_mapping file_generic_mapping;
297 int i;
298 SEC_ACL *ps_dacl = NULL;
300 if (!psd)
301 return;
303 ps_dacl = psd->dacl;
304 if (!ps_dacl)
305 return;
307 for (i = 0; i < ps_dacl->num_aces; i++) {
308 SEC_ACE *psa = &ps_dacl->ace[i];
309 uint32 orig_mask = psa->info.mask;
311 se_map_generic(&psa->info.mask, &file_generic_mapping);
312 psa->info.mask |= orig_mask;
316 /*******************************************************************
317 Can this user access with share with the required permissions ?
318 ********************************************************************/
320 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
322 uint32 granted;
323 NTSTATUS status;
324 TALLOC_CTX *mem_ctx = NULL;
325 SEC_DESC *psd = NULL;
326 size_t sd_size;
327 NT_USER_TOKEN *token = NULL;
328 BOOL ret = True;
330 mem_ctx = talloc_init("share_access_check");
331 if (mem_ctx == NULL)
332 return False;
334 psd = get_share_security(mem_ctx, snum, &sd_size);
336 if (!psd)
337 goto out;
339 if (conn->nt_user_token)
340 token = conn->nt_user_token;
341 else
342 token = vuser->nt_user_token;
344 ret = se_access_check(psd, token, desired_access, &granted, &status);
346 out:
348 talloc_destroy(mem_ctx);
350 return ret;
353 /*******************************************************************
354 Fill in a share info level 501 structure.
355 ********************************************************************/
357 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
359 int len_net_name;
360 pstring remark;
362 char *net_name = lp_servicename(snum);
363 pstrcpy(remark, lp_comment(snum));
364 standard_sub_conn(p->conn, remark, sizeof(remark));
366 len_net_name = strlen(net_name);
368 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
369 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
372 /*******************************************************************
373 Fill in a share info level 502 structure.
374 ********************************************************************/
376 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
378 int len_net_name;
379 pstring net_name;
380 pstring remark;
381 pstring path;
382 pstring passwd;
383 SEC_DESC *sd;
384 size_t sd_size;
385 TALLOC_CTX *ctx = p->mem_ctx;
388 ZERO_STRUCTP(sh502);
390 pstrcpy(net_name, lp_servicename(snum));
391 pstrcpy(remark, lp_comment(snum));
392 standard_sub_conn(p->conn, remark,sizeof(remark));
393 pstrcpy(path, "C:");
394 pstrcat(path, lp_pathname(snum));
397 * Change / to \\ so that win2k will see it as a valid path. This was added to
398 * enable use of browsing in win2k add share dialog.
401 string_replace(path, '/', '\\');
403 pstrcpy(passwd, "");
404 len_net_name = strlen(net_name);
406 sd = get_share_security(ctx, snum, &sd_size);
408 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
409 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
412 /***************************************************************************
413 Fill in a share info level 1004 structure.
414 ***************************************************************************/
416 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
418 pstring remark;
420 pstrcpy(remark, lp_comment(snum));
421 standard_sub_conn(p->conn, remark, sizeof(remark));
423 ZERO_STRUCTP(sh1004);
425 init_srv_share_info1004(&sh1004->info_1004, remark);
426 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
429 /***************************************************************************
430 Fill in a share info level 1005 structure.
431 ***************************************************************************/
433 static void init_srv_share_info_1005(pipes_struct *p, 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;
440 /***************************************************************************
441 Fill in a share info level 1006 structure.
442 ***************************************************************************/
444 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
446 sh1006->max_uses = -1;
449 /***************************************************************************
450 Fill in a share info level 1007 structure.
451 ***************************************************************************/
453 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
455 pstring alternate_directory_name = "";
456 uint32 flags = 0;
458 ZERO_STRUCTP(sh1007);
460 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
461 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
464 /*******************************************************************
465 Fill in a share info level 1501 structure.
466 ********************************************************************/
468 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
470 SEC_DESC *sd;
471 size_t sd_size;
472 TALLOC_CTX *ctx = p->mem_ctx;
474 ZERO_STRUCTP(sh1501);
476 sd = get_share_security(ctx, snum, &sd_size);
478 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
481 /*******************************************************************
482 True if it ends in '$'.
483 ********************************************************************/
485 static BOOL is_hidden_share(int snum)
487 pstring net_name;
489 pstrcpy(net_name, lp_servicename(snum));
490 return (net_name[strlen(net_name)] == '$') ? True : False;
493 /*******************************************************************
494 Fill in a share info structure.
495 ********************************************************************/
497 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
498 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
500 int num_entries = 0;
501 int num_services = lp_numservices();
502 int snum;
503 TALLOC_CTX *ctx = p->mem_ctx;
505 DEBUG(5,("init_srv_share_info_ctr\n"));
507 ZERO_STRUCTPN(ctr);
509 ctr->info_level = ctr->switch_value = info_level;
510 *resume_hnd = 0;
512 /* Count the number of entries. */
513 for (snum = 0; snum < num_services; snum++) {
514 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
515 num_entries++;
518 *total_entries = num_entries;
519 ctr->num_entries2 = ctr->num_entries = num_entries;
520 ctr->ptr_share_info = ctr->ptr_entries = 1;
522 if (!num_entries)
523 return True;
525 switch (info_level) {
526 case 0:
528 SRV_SHARE_INFO_0 *info0;
529 int i = 0;
531 info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
533 for (snum = *resume_hnd; snum < num_services; snum++) {
534 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
535 init_srv_share_info_0(p, &info0[i++], snum);
539 ctr->share.info0 = info0;
540 break;
544 case 1:
546 SRV_SHARE_INFO_1 *info1;
547 int i = 0;
549 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
551 for (snum = *resume_hnd; snum < num_services; snum++) {
552 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
553 init_srv_share_info_1(p, &info1[i++], snum);
557 ctr->share.info1 = info1;
558 break;
561 case 2:
563 SRV_SHARE_INFO_2 *info2;
564 int i = 0;
566 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
568 for (snum = *resume_hnd; snum < num_services; snum++) {
569 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
570 init_srv_share_info_2(p, &info2[i++], snum);
574 ctr->share.info2 = info2;
575 break;
578 case 501:
580 SRV_SHARE_INFO_501 *info501;
581 int i = 0;
583 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
585 for (snum = *resume_hnd; snum < num_services; snum++) {
586 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
587 init_srv_share_info_501(p, &info501[i++], snum);
591 ctr->share.info501 = info501;
592 break;
595 case 502:
597 SRV_SHARE_INFO_502 *info502;
598 int i = 0;
600 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
602 for (snum = *resume_hnd; snum < num_services; snum++) {
603 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
604 init_srv_share_info_502(p, &info502[i++], snum);
608 ctr->share.info502 = info502;
609 break;
612 /* here for completeness but not currently used with enum (1004 - 1501)*/
614 case 1004:
616 SRV_SHARE_INFO_1004 *info1004;
617 int i = 0;
619 info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
621 for (snum = *resume_hnd; snum < num_services; snum++) {
622 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
623 init_srv_share_info_1004(p, &info1004[i++], snum);
627 ctr->share.info1004 = info1004;
628 break;
631 case 1005:
633 SRV_SHARE_INFO_1005 *info1005;
634 int i = 0;
636 info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
638 for (snum = *resume_hnd; snum < num_services; snum++) {
639 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
640 init_srv_share_info_1005(p, &info1005[i++], snum);
644 ctr->share.info1005 = info1005;
645 break;
648 case 1006:
650 SRV_SHARE_INFO_1006 *info1006;
651 int i = 0;
653 info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
655 for (snum = *resume_hnd; snum < num_services; snum++) {
656 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
657 init_srv_share_info_1006(p, &info1006[i++], snum);
661 ctr->share.info1006 = info1006;
662 break;
665 case 1007:
667 SRV_SHARE_INFO_1007 *info1007;
668 int i = 0;
670 info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
672 for (snum = *resume_hnd; snum < num_services; snum++) {
673 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
674 init_srv_share_info_1007(p, &info1007[i++], snum);
678 ctr->share.info1007 = info1007;
679 break;
682 case 1501:
684 SRV_SHARE_INFO_1501 *info1501;
685 int i = 0;
687 info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
689 for (snum = *resume_hnd; snum < num_services; snum++) {
690 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
691 init_srv_share_info_1501(p, &info1501[i++], snum);
695 ctr->share.info1501 = info1501;
696 break;
698 default:
699 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
700 return False;
703 return True;
706 /*******************************************************************
707 Inits a SRV_R_NET_SHARE_ENUM structure.
708 ********************************************************************/
710 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
711 uint32 info_level, uint32 resume_hnd, BOOL all)
713 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
715 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
716 &resume_hnd, &r_n->total_entries, all)) {
717 r_n->status = WERR_OK;
718 } else {
719 r_n->status = WERR_UNKNOWN_LEVEL;
722 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
725 /*******************************************************************
726 Inits a SRV_R_NET_SHARE_GET_INFO structure.
727 ********************************************************************/
729 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
730 char *share_name, uint32 info_level)
732 WERROR status = WERR_OK;
733 int snum;
735 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
737 r_n->info.switch_value = info_level;
739 snum = find_service(share_name);
741 if (snum >= 0) {
742 switch (info_level) {
743 case 0:
744 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
745 break;
746 case 1:
747 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
748 break;
749 case 2:
750 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
751 break;
752 case 501:
753 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
754 break;
755 case 502:
756 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
757 break;
759 /* here for completeness */
760 case 1004:
761 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
762 break;
763 case 1005:
764 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
765 break;
767 /* here for completeness 1006 - 1501 */
768 case 1006:
769 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
770 break;
771 case 1007:
772 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
773 break;
774 case 1501:
775 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
776 break;
777 default:
778 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
779 status = WERR_UNKNOWN_LEVEL;
780 break;
782 } else {
783 status = WERR_INVALID_NAME;
786 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
787 r_n->status = status;
790 /*******************************************************************
791 fill in a sess info level 1 structure.
792 ********************************************************************/
794 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
796 init_srv_sess_info0(se0, name);
797 init_srv_sess_info0_str(str0, name);
800 /*******************************************************************
801 fill in a sess info level 0 structure.
802 ********************************************************************/
804 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
806 struct sessionid *session_list;
807 uint32 num_entries = 0;
808 (*stot) = list_sessions(&session_list);
810 if (ss0 == NULL) {
811 (*snum) = 0;
812 SAFE_FREE(session_list);
813 return;
816 DEBUG(5,("init_srv_sess_0_ss0\n"));
818 if (snum) {
819 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
820 init_srv_sess_0_info(&ss0->info_0[num_entries],
821 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
823 /* move on to creating next session */
824 /* move on to creating next sess */
825 num_entries++;
828 ss0->num_entries_read = num_entries;
829 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
830 ss0->num_entries_read2 = num_entries;
832 if ((*snum) >= (*stot)) {
833 (*snum) = 0;
836 } else {
837 ss0->num_entries_read = 0;
838 ss0->ptr_sess_info = 0;
839 ss0->num_entries_read2 = 0;
841 SAFE_FREE(session_list);
844 /*******************************************************************
845 fill in a sess info level 1 structure.
846 ********************************************************************/
848 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
849 char *name, char *user,
850 uint32 num_opens,
851 uint32 open_time, uint32 idle_time,
852 uint32 usr_flgs)
854 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
855 init_srv_sess_info1_str(str1, name, user);
858 /*******************************************************************
859 fill in a sess info level 1 structure.
860 ********************************************************************/
862 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
864 struct sessionid *session_list;
865 uint32 num_entries = 0;
866 (*stot) = list_sessions(&session_list);
868 if (ss1 == NULL) {
869 (*snum) = 0;
870 SAFE_FREE(session_list);
871 return;
874 DEBUG(5,("init_srv_sess_1_ss1\n"));
876 if (snum) {
877 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
878 init_srv_sess_1_info(&ss1->info_1[num_entries],
879 &ss1->info_1_str[num_entries],
880 session_list[*snum].remote_machine,
881 session_list[*snum].username,
882 1, 10, 5, 0);
884 /* move on to creating next session */
885 /* move on to creating next sess */
886 num_entries++;
889 ss1->num_entries_read = num_entries;
890 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
891 ss1->num_entries_read2 = num_entries;
893 if ((*snum) >= (*stot)) {
894 (*snum) = 0;
897 } else {
898 ss1->num_entries_read = 0;
899 ss1->ptr_sess_info = 0;
900 ss1->num_entries_read2 = 0;
902 (*stot) = 0;
906 /*******************************************************************
907 makes a SRV_R_NET_SESS_ENUM structure.
908 ********************************************************************/
910 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
911 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
913 WERROR status = WERR_OK;
914 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
916 ctr->switch_value = switch_value;
918 switch (switch_value) {
919 case 0:
920 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
921 ctr->ptr_sess_ctr = 1;
922 break;
923 case 1:
924 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
925 ctr->ptr_sess_ctr = 1;
926 break;
927 default:
928 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
929 (*resume_hnd) = 0;
930 (*total_entries) = 0;
931 ctr->ptr_sess_ctr = 0;
932 status = WERR_UNKNOWN_LEVEL;
933 break;
936 return status;
939 /*******************************************************************
940 makes a SRV_R_NET_SESS_ENUM structure.
941 ********************************************************************/
943 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
944 uint32 resume_hnd, int sess_level, int switch_value)
946 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
948 r_n->sess_level = sess_level;
950 if (sess_level == -1)
951 r_n->status = WERR_UNKNOWN_LEVEL;
952 else
953 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
955 if (!W_ERROR_IS_OK(r_n->status))
956 resume_hnd = 0;
958 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
961 /*******************************************************************
962 fill in a conn info level 0 structure.
963 ********************************************************************/
965 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
967 uint32 num_entries = 0;
968 (*stot) = 1;
970 if (ss0 == NULL) {
971 (*snum) = 0;
972 return;
975 DEBUG(5,("init_srv_conn_0_ss0\n"));
977 if (snum) {
978 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
980 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
982 /* move on to creating next connection */
983 /* move on to creating next conn */
984 num_entries++;
987 ss0->num_entries_read = num_entries;
988 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
989 ss0->num_entries_read2 = num_entries;
991 if ((*snum) >= (*stot)) {
992 (*snum) = 0;
995 } else {
996 ss0->num_entries_read = 0;
997 ss0->ptr_conn_info = 0;
998 ss0->num_entries_read2 = 0;
1000 (*stot) = 0;
1004 /*******************************************************************
1005 fill in a conn info level 1 structure.
1006 ********************************************************************/
1008 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1009 uint32 id, uint32 type,
1010 uint32 num_opens, uint32 num_users, uint32 open_time,
1011 const char *usr_name, const char *net_name)
1013 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1014 init_srv_conn_info1_str(str1, usr_name, net_name);
1017 /*******************************************************************
1018 fill in a conn info level 1 structure.
1019 ********************************************************************/
1021 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1023 uint32 num_entries = 0;
1024 (*stot) = 1;
1026 if (ss1 == NULL) {
1027 (*snum) = 0;
1028 return;
1031 DEBUG(5,("init_srv_conn_1_ss1\n"));
1033 if (snum) {
1034 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1035 init_srv_conn_1_info(&ss1->info_1[num_entries],
1036 &ss1->info_1_str[num_entries],
1037 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1039 /* move on to creating next connection */
1040 /* move on to creating next conn */
1041 num_entries++;
1044 ss1->num_entries_read = num_entries;
1045 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1046 ss1->num_entries_read2 = num_entries;
1049 if ((*snum) >= (*stot)) {
1050 (*snum) = 0;
1053 } else {
1054 ss1->num_entries_read = 0;
1055 ss1->ptr_conn_info = 0;
1056 ss1->num_entries_read2 = 0;
1058 (*stot) = 0;
1062 /*******************************************************************
1063 makes a SRV_R_NET_CONN_ENUM structure.
1064 ********************************************************************/
1066 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1067 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1069 WERROR status = WERR_OK;
1070 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1072 ctr->switch_value = switch_value;
1074 switch (switch_value) {
1075 case 0:
1076 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1077 ctr->ptr_conn_ctr = 1;
1078 break;
1079 case 1:
1080 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1081 ctr->ptr_conn_ctr = 1;
1082 break;
1083 default:
1084 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1085 (*resume_hnd = 0);
1086 (*total_entries) = 0;
1087 ctr->ptr_conn_ctr = 0;
1088 status = WERR_UNKNOWN_LEVEL;
1089 break;
1092 return status;
1095 /*******************************************************************
1096 makes a SRV_R_NET_CONN_ENUM structure.
1097 ********************************************************************/
1099 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1100 uint32 resume_hnd, int conn_level, int switch_value)
1102 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1104 r_n->conn_level = conn_level;
1105 if (conn_level == -1)
1106 r_n->status = WERR_UNKNOWN_LEVEL;
1107 else
1108 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1110 if (!W_ERROR_IS_OK(r_n->status))
1111 resume_hnd = 0;
1113 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1116 /*******************************************************************
1117 makes a SRV_R_NET_FILE_ENUM structure.
1118 ********************************************************************/
1120 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1121 int switch_value, uint32 *resume_hnd,
1122 uint32 *total_entries)
1124 WERROR status = WERR_OK;
1125 TALLOC_CTX *ctx = p->mem_ctx;
1126 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1127 *total_entries = 1; /* dummy entries only, for */
1129 ctr->switch_value = switch_value;
1130 ctr->num_entries = *total_entries - *resume_hnd;
1131 ctr->num_entries2 = ctr->num_entries;
1133 switch (switch_value) {
1134 case 3: {
1135 int i;
1136 if (*total_entries > 0) {
1137 ctr->ptr_entries = 1;
1138 ctr->file.info3 = talloc(ctx, ctr->num_entries *
1139 sizeof(SRV_FILE_INFO_3));
1141 for (i=0 ;i<ctr->num_entries;i++) {
1142 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1143 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1146 ctr->ptr_file_info = 1;
1147 *resume_hnd = 0;
1148 break;
1150 default:
1151 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1152 (*resume_hnd = 0);
1153 (*total_entries) = 0;
1154 ctr->ptr_entries = 0;
1155 status = WERR_UNKNOWN_LEVEL;
1156 break;
1159 return status;
1162 /*******************************************************************
1163 makes a SRV_R_NET_FILE_ENUM structure.
1164 ********************************************************************/
1166 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1167 uint32 resume_hnd, int file_level, int switch_value)
1169 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1171 r_n->file_level = file_level;
1172 if (file_level == 0)
1173 r_n->status = WERR_UNKNOWN_LEVEL;
1174 else
1175 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1177 if (!W_ERROR_IS_OK(r_n->status))
1178 resume_hnd = 0;
1180 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1183 /*******************************************************************
1184 net server get info
1185 ********************************************************************/
1187 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)
1189 WERROR status = WERR_OK;
1190 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1192 if (!ctr)
1193 return WERR_NOMEM;
1195 ZERO_STRUCTP(ctr);
1197 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1199 if (!pipe_access_check(p)) {
1200 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1201 return WERR_ACCESS_DENIED;
1204 switch (q_u->switch_value) {
1206 /* Technically level 102 should only be available to
1207 Administrators but there isn't anything super-secret
1208 here, as most of it is made up. */
1210 case 102:
1211 init_srv_info_102(&ctr->srv.sv102,
1212 500, global_myname(),
1213 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1214 lp_major_announce_version(), lp_minor_announce_version(),
1215 lp_default_server_announce(),
1216 0xffffffff, /* users */
1217 0xf, /* disc */
1218 0, /* hidden */
1219 240, /* announce */
1220 3000, /* announce delta */
1221 100000, /* licenses */
1222 "c:\\"); /* user path */
1223 break;
1224 case 101:
1225 init_srv_info_101(&ctr->srv.sv101,
1226 500, global_myname(),
1227 lp_major_announce_version(), lp_minor_announce_version(),
1228 lp_default_server_announce(),
1229 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1230 break;
1231 case 100:
1232 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1233 break;
1234 default:
1235 status = WERR_UNKNOWN_LEVEL;
1236 break;
1239 /* set up the net server get info structure */
1240 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1242 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1244 return r_u->status;
1247 /*******************************************************************
1248 net server set info
1249 ********************************************************************/
1251 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)
1253 WERROR status = WERR_OK;
1255 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1257 /* Set up the net server set info structure. */
1259 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1261 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1263 return r_u->status;
1266 /*******************************************************************
1267 net file enum
1268 ********************************************************************/
1270 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1272 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1274 /* set up the */
1275 init_srv_r_net_file_enum(p, r_u,
1276 get_enum_hnd(&q_u->enum_hnd),
1277 q_u->file_level,
1278 q_u->ctr.switch_value);
1280 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1282 return r_u->status;
1285 /*******************************************************************
1286 net conn enum
1287 ********************************************************************/
1289 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1291 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1293 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1294 if (!r_u->ctr)
1295 return WERR_NOMEM;
1297 ZERO_STRUCTP(r_u->ctr);
1299 /* set up the */
1300 init_srv_r_net_conn_enum(r_u,
1301 get_enum_hnd(&q_u->enum_hnd),
1302 q_u->conn_level,
1303 q_u->ctr->switch_value);
1305 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1307 return r_u->status;
1310 /*******************************************************************
1311 net sess enum
1312 ********************************************************************/
1314 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1316 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1318 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1319 if (!r_u->ctr)
1320 return WERR_NOMEM;
1322 ZERO_STRUCTP(r_u->ctr);
1324 /* set up the */
1325 init_srv_r_net_sess_enum(r_u,
1326 get_enum_hnd(&q_u->enum_hnd),
1327 q_u->sess_level,
1328 q_u->ctr->switch_value);
1330 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1332 return r_u->status;
1335 /*******************************************************************
1336 Net share enum all.
1337 ********************************************************************/
1339 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1341 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1343 if (!pipe_access_check(p)) {
1344 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1345 return WERR_ACCESS_DENIED;
1348 /* Create the list of shares for the response. */
1349 init_srv_r_net_share_enum(p, r_u,
1350 q_u->ctr.info_level,
1351 get_enum_hnd(&q_u->enum_hnd), True);
1353 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1355 return r_u->status;
1358 /*******************************************************************
1359 Net share enum.
1360 ********************************************************************/
1362 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1364 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1366 if (!pipe_access_check(p)) {
1367 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1368 return WERR_ACCESS_DENIED;
1371 /* Create the list of shares for the response. */
1372 init_srv_r_net_share_enum(p, r_u,
1373 q_u->ctr.info_level,
1374 get_enum_hnd(&q_u->enum_hnd), False);
1376 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1378 return r_u->status;
1381 /*******************************************************************
1382 Net share get info.
1383 ********************************************************************/
1385 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)
1387 fstring share_name;
1389 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1391 /* Create the list of shares for the response. */
1392 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1393 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1395 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1397 return r_u->status;
1400 /*******************************************************************
1401 Check a given DOS pathname is valid for a share.
1402 ********************************************************************/
1404 static char *valid_share_pathname(char *dos_pathname)
1406 pstring saved_pathname;
1407 pstring unix_pathname;
1408 char *ptr;
1409 int ret;
1411 /* Convert any '\' paths to '/' */
1412 unix_format(dos_pathname);
1413 unix_clean_name(dos_pathname);
1415 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1416 ptr = dos_pathname;
1417 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1418 ptr += 2;
1420 /* Only abolute paths allowed. */
1421 if (*ptr != '/')
1422 return NULL;
1424 /* Can we cd to it ? */
1426 /* First save our current directory. */
1427 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1428 return False;
1430 pstrcpy(unix_pathname, ptr);
1432 ret = chdir(unix_pathname);
1434 /* We *MUST* be able to chdir back. Abort if we can't. */
1435 if (chdir(saved_pathname) == -1)
1436 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1438 return (ret != -1) ? ptr : NULL;
1441 /*******************************************************************
1442 Net share set info. Modify share details.
1443 ********************************************************************/
1445 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)
1447 struct current_user user;
1448 pstring command;
1449 fstring share_name;
1450 fstring comment;
1451 pstring pathname;
1452 int type;
1453 int snum;
1454 int ret;
1455 char *ptr;
1456 SEC_DESC *psd = NULL;
1458 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1460 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1462 r_u->parm_error = 0;
1464 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1465 return WERR_ACCESS_DENIED;
1467 snum = find_service(share_name);
1469 /* Does this share exist ? */
1470 if (snum < 0)
1471 return WERR_INVALID_NAME;
1473 /* No change to printer shares. */
1474 if (lp_print_ok(snum))
1475 return WERR_ACCESS_DENIED;
1477 get_current_user(&user,p);
1479 if (user.uid != sec_initial_uid())
1480 return WERR_ACCESS_DENIED;
1482 switch (q_u->info_level) {
1483 case 1:
1484 pstrcpy(pathname, lp_pathname(snum));
1485 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1486 type = q_u->info.share.info2.info_2.type;
1487 psd = NULL;
1488 break;
1489 case 2:
1490 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1491 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1492 type = q_u->info.share.info2.info_2.type;
1493 psd = NULL;
1494 break;
1495 #if 0
1496 /* not supported on set but here for completeness */
1497 case 501:
1498 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1499 type = q_u->info.share.info501.info_501.type;
1500 psd = NULL;
1501 break;
1502 #endif
1503 case 502:
1504 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1505 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1506 type = q_u->info.share.info502.info_502.type;
1507 psd = q_u->info.share.info502.info_502_str.sd;
1508 map_generic_share_sd_bits(psd);
1509 break;
1510 case 1004:
1511 pstrcpy(pathname, lp_pathname(snum));
1512 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1513 type = STYPE_DISKTREE;
1514 break;
1515 case 1005:
1516 case 1006:
1517 case 1007:
1518 return WERR_ACCESS_DENIED;
1519 break;
1520 case 1501:
1521 pstrcpy(pathname, lp_pathname(snum));
1522 fstrcpy(comment, lp_comment(snum));
1523 psd = q_u->info.share.info1501.sdb->sec;
1524 map_generic_share_sd_bits(psd);
1525 type = STYPE_DISKTREE;
1526 break;
1527 default:
1528 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1529 return WERR_UNKNOWN_LEVEL;
1532 /* We can only modify disk shares. */
1533 if (type != STYPE_DISKTREE)
1534 return WERR_ACCESS_DENIED;
1536 /* Check if the pathname is valid. */
1537 if (!(ptr = valid_share_pathname( pathname )))
1538 return WERR_OBJECT_PATH_INVALID;
1540 /* Ensure share name, pathname and comment don't contain '"' characters. */
1541 string_replace(share_name, '"', ' ');
1542 string_replace(ptr, '"', ' ');
1543 string_replace(comment, '"', ' ');
1545 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1546 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1548 /* Only call modify function if something changed. */
1550 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1551 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1552 return WERR_ACCESS_DENIED;
1554 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1555 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1557 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1558 if ((ret = smbrun(command, NULL)) != 0) {
1559 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1560 return WERR_ACCESS_DENIED;
1563 /* Tell everyone we updated smb.conf. */
1564 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1566 } else {
1567 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1570 /* Replace SD if changed. */
1571 if (psd) {
1572 SEC_DESC *old_sd;
1573 size_t sd_size;
1575 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1577 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1578 if (!set_share_security(p->mem_ctx, share_name, psd))
1579 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1580 share_name ));
1584 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1586 return WERR_OK;
1589 /*******************************************************************
1590 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1591 ********************************************************************/
1593 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1595 struct current_user user;
1596 pstring command;
1597 fstring share_name;
1598 fstring comment;
1599 pstring pathname;
1600 int type;
1601 int snum;
1602 int ret;
1603 char *ptr;
1604 SEC_DESC *psd = NULL;
1606 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1608 r_u->parm_error = 0;
1610 get_current_user(&user,p);
1612 if (user.uid != sec_initial_uid()) {
1613 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1614 return WERR_ACCESS_DENIED;
1617 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1618 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1619 return WERR_ACCESS_DENIED;
1622 switch (q_u->info_level) {
1623 case 0:
1624 /* No path. Not enough info in a level 0 to do anything. */
1625 return WERR_ACCESS_DENIED;
1626 case 1:
1627 /* Not enough info in a level 1 to do anything. */
1628 return WERR_ACCESS_DENIED;
1629 case 2:
1630 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1631 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1632 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1633 type = q_u->info.share.info2.info_2.type;
1634 break;
1635 case 501:
1636 /* No path. Not enough info in a level 501 to do anything. */
1637 return WERR_ACCESS_DENIED;
1638 case 502:
1639 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1640 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1641 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1642 type = q_u->info.share.info502.info_502.type;
1643 psd = q_u->info.share.info502.info_502_str.sd;
1644 map_generic_share_sd_bits(psd);
1645 break;
1647 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1649 case 1004:
1650 case 1005:
1651 case 1006:
1652 case 1007:
1653 return WERR_ACCESS_DENIED;
1654 break;
1655 case 1501:
1656 /* DFS only level. */
1657 return WERR_ACCESS_DENIED;
1658 default:
1659 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1660 return WERR_UNKNOWN_LEVEL;
1663 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1664 return WERR_ACCESS_DENIED;
1666 snum = find_service(share_name);
1668 /* Share already exists. */
1669 if (snum >= 0)
1670 return WERR_ALREADY_EXISTS;
1672 /* We can only add disk shares. */
1673 if (type != STYPE_DISKTREE)
1674 return WERR_ACCESS_DENIED;
1676 /* Check if the pathname is valid. */
1677 if (!(ptr = valid_share_pathname( pathname )))
1678 return WERR_OBJECT_PATH_INVALID;
1680 /* Ensure share name, pathname and comment don't contain '"' characters. */
1681 string_replace(share_name, '"', ' ');
1682 string_replace(ptr, '"', ' ');
1683 string_replace(comment, '"', ' ');
1685 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1686 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1688 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1689 if ((ret = smbrun(command, NULL)) != 0) {
1690 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1691 return WERR_ACCESS_DENIED;
1694 if (psd) {
1695 if (!set_share_security(p->mem_ctx, share_name, psd))
1696 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1697 share_name ));
1700 /* Tell everyone we updated smb.conf. */
1701 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1704 * We don't call reload_services() here, the message will
1705 * cause this to be done before the next packet is read
1706 * from the client. JRA.
1709 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1711 return WERR_OK;
1714 /*******************************************************************
1715 Net share delete. Call "delete share command" with the share name as
1716 a parameter.
1717 ********************************************************************/
1719 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1721 struct current_user user;
1722 pstring command;
1723 fstring share_name;
1724 int ret;
1725 int snum;
1727 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1729 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1731 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1732 return WERR_ACCESS_DENIED;
1734 snum = find_service(share_name);
1736 if (snum < 0)
1737 return WERR_NO_SUCH_SHARE;
1739 /* No change to printer shares. */
1740 if (lp_print_ok(snum))
1741 return WERR_ACCESS_DENIED;
1743 get_current_user(&user,p);
1745 if (user.uid != sec_initial_uid())
1746 return WERR_ACCESS_DENIED;
1748 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1749 return WERR_ACCESS_DENIED;
1751 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1752 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1754 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1755 if ((ret = smbrun(command, NULL)) != 0) {
1756 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1757 return WERR_ACCESS_DENIED;
1760 /* Delete the SD in the database. */
1761 delete_share_security(snum);
1763 /* Tell everyone we updated smb.conf. */
1764 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1766 lp_killservice(snum);
1768 return WERR_OK;
1771 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1773 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1775 return _srv_net_share_del(p, q_u, r_u);
1778 /*******************************************************************
1779 time of day
1780 ********************************************************************/
1782 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1784 TIME_OF_DAY_INFO *tod;
1785 struct tm *t;
1786 time_t unixdate = time(NULL);
1788 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1789 if (!tod)
1790 return WERR_NOMEM;
1792 ZERO_STRUCTP(tod);
1794 r_u->tod = tod;
1795 r_u->ptr_srv_tod = 0x1;
1796 r_u->status = WERR_OK;
1798 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1800 t = gmtime(&unixdate);
1802 /* set up the */
1803 init_time_of_day_info(tod,
1804 unixdate,
1806 t->tm_hour,
1807 t->tm_min,
1808 t->tm_sec,
1810 TimeDiff(unixdate)/60,
1811 10000,
1812 t->tm_mday,
1813 t->tm_mon + 1,
1814 1900+t->tm_year,
1815 t->tm_wday);
1817 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1819 return r_u->status;
1822 /***********************************************************************************
1823 Win9x NT tools get security descriptor.
1824 ***********************************************************************************/
1826 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1827 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1829 SEC_DESC *psd = NULL;
1830 size_t sd_size;
1831 DATA_BLOB null_pw;
1832 pstring filename;
1833 pstring qualname;
1834 files_struct *fsp = NULL;
1835 SMB_STRUCT_STAT st;
1836 BOOL bad_path;
1837 int access_mode;
1838 int action;
1839 NTSTATUS nt_status;
1840 struct current_user user;
1841 connection_struct *conn = NULL;
1842 BOOL became_user = False;
1844 ZERO_STRUCT(st);
1846 r_u->status = WERR_OK;
1848 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1850 /* Null password is ok - we are already an authenticated user... */
1851 null_pw = data_blob(NULL, 0);
1853 get_current_user(&user, p);
1855 become_root();
1856 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1857 unbecome_root();
1859 if (conn == NULL) {
1860 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1861 r_u->status = ntstatus_to_werror(nt_status);
1862 goto error_exit;
1865 if (!become_user(conn, conn->vuid)) {
1866 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1867 r_u->status = WERR_ACCESS_DENIED;
1868 goto error_exit;
1870 became_user = True;
1872 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1873 unix_convert(filename, conn, NULL, &bad_path, &st);
1874 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1875 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1877 if (!fsp) {
1878 /* Perhaps it is a directory */
1879 if (errno == EISDIR)
1880 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1881 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1883 if (!fsp) {
1884 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1885 r_u->status = WERR_ACCESS_DENIED;
1886 goto error_exit;
1890 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, &psd);
1892 if (sd_size == 0) {
1893 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1894 r_u->status = WERR_ACCESS_DENIED;
1895 goto error_exit;
1898 r_u->ptr_response = 1;
1899 r_u->size_response = sd_size;
1900 r_u->ptr_secdesc = 1;
1901 r_u->size_secdesc = sd_size;
1902 r_u->sec_desc = psd;
1904 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1906 close_file(fsp, True);
1907 unbecome_user();
1908 close_cnum(conn, user.vuid);
1909 return r_u->status;
1911 error_exit:
1913 if(fsp) {
1914 close_file(fsp, True);
1917 if (became_user)
1918 unbecome_user();
1920 if (conn)
1921 close_cnum(conn, user.vuid);
1923 return r_u->status;
1926 /***********************************************************************************
1927 Win9x NT tools set security descriptor.
1928 ***********************************************************************************/
1930 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1931 SRV_R_NET_FILE_SET_SECDESC *r_u)
1933 BOOL ret;
1934 pstring filename;
1935 pstring qualname;
1936 DATA_BLOB null_pw;
1937 files_struct *fsp = NULL;
1938 SMB_STRUCT_STAT st;
1939 BOOL bad_path;
1940 int access_mode;
1941 int action;
1942 NTSTATUS nt_status;
1943 struct current_user user;
1944 connection_struct *conn = NULL;
1945 BOOL became_user = False;
1947 ZERO_STRUCT(st);
1949 r_u->status = WERR_OK;
1951 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1953 /* Null password is ok - we are already an authenticated user... */
1954 null_pw = data_blob(NULL, 0);
1956 get_current_user(&user, p);
1958 become_root();
1959 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1960 unbecome_root();
1962 if (conn == NULL) {
1963 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1964 r_u->status = ntstatus_to_werror(nt_status);
1965 goto error_exit;
1968 if (!become_user(conn, conn->vuid)) {
1969 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1970 r_u->status = WERR_ACCESS_DENIED;
1971 goto error_exit;
1973 became_user = True;
1975 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1976 unix_convert(filename, conn, NULL, &bad_path, &st);
1978 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1979 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1981 if (!fsp) {
1982 /* Perhaps it is a directory */
1983 if (errno == EISDIR)
1984 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1985 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1987 if (!fsp) {
1988 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1989 r_u->status = WERR_ACCESS_DENIED;
1990 goto error_exit;
1994 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1996 if (ret == False) {
1997 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1998 r_u->status = WERR_ACCESS_DENIED;
1999 goto error_exit;
2002 close_file(fsp, True);
2003 unbecome_user();
2004 close_cnum(conn, user.vuid);
2005 return r_u->status;
2007 error_exit:
2009 if(fsp) {
2010 close_file(fsp, True);
2013 if (became_user)
2014 unbecome_user();
2016 if (conn)
2017 close_cnum(conn, user.vuid);
2019 return r_u->status;
2022 /***********************************************************************************
2023 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2024 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2025 These disks would the disks listed by this function.
2026 Users could then create shares relative to these disks. Watch out for moving these disks around.
2027 "Nigel Williams" <nigel@veritas.com>.
2028 ***********************************************************************************/
2030 static const char *server_disks[] = {"C:"};
2032 static uint32 get_server_disk_count(void)
2034 return sizeof(server_disks)/sizeof(server_disks[0]);
2037 static uint32 init_server_disk_enum(uint32 *resume)
2039 uint32 server_disk_count = get_server_disk_count();
2041 /*resume can be an offset into the list for now*/
2043 if(*resume & 0x80000000)
2044 *resume = 0;
2046 if(*resume > server_disk_count)
2047 *resume = server_disk_count;
2049 return server_disk_count - *resume;
2052 static const char *next_server_disk_enum(uint32 *resume)
2054 const char *disk;
2056 if(init_server_disk_enum(resume) == 0)
2057 return NULL;
2059 disk = server_disks[*resume];
2061 (*resume)++;
2063 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2065 return disk;
2068 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2070 uint32 i;
2071 const char *disk_name;
2072 TALLOC_CTX *ctx = p->mem_ctx;
2073 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2075 r_u->status=WERR_OK;
2077 r_u->total_entries = init_server_disk_enum(&resume);
2079 r_u->disk_enum_ctr.unknown = 0;
2082 DISK_INFO *dinfo;
2084 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2086 if(!(dinfo = talloc(ctx, dinfo_size))) {
2087 return WERR_NOMEM;
2090 r_u->disk_enum_ctr.disk_info = dinfo;
2093 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2095 /*allow one DISK_INFO for null terminator*/
2097 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2099 r_u->disk_enum_ctr.entries_read++;
2101 /*copy disk name into a unicode string*/
2103 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2106 /* add a terminating null string. Is this there if there is more data to come? */
2108 r_u->disk_enum_ctr.entries_read++;
2110 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2112 init_enum_hnd(&r_u->enum_hnd, resume);
2114 return r_u->status;
2117 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2119 int snum;
2120 fstring share_name;
2122 r_u->status=WERR_OK;
2124 switch(q_u->type) {
2126 case 0x9:
2128 /*check if share name is ok*/
2129 /*also check if we already have a share with this name*/
2131 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2132 snum = find_service(share_name);
2134 /* Share already exists. */
2135 if (snum >= 0)
2136 r_u->status = WERR_ALREADY_EXISTS;
2137 break;
2139 default:
2140 /*unsupported type*/
2141 r_u->status = WERR_UNKNOWN_LEVEL;
2142 break;
2145 return r_u->status;