* small formatting fixes
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob5c1038949b522a4c78641d59ef8b095d2d0a07c6
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 extern pstring global_myname;
32 /*******************************************************************
33 Utility function to get the 'type' of a share from an snum.
34 ********************************************************************/
35 static uint32 get_share_type(int snum)
37 char *net_name = lp_servicename(snum);
38 int len_net_name = strlen(net_name);
40 /* work out the share type */
41 uint32 type = STYPE_DISKTREE;
43 if (lp_print_ok(snum))
44 type = STYPE_PRINTQ;
45 if (strequal(lp_fstype(snum), "IPC"))
46 type = STYPE_IPC;
47 if (net_name[len_net_name] == '$')
48 type |= STYPE_HIDDEN;
50 return type;
53 /*******************************************************************
54 Fill in a share info level 0 structure.
55 ********************************************************************/
57 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
59 pstring net_name;
61 pstrcpy(net_name, lp_servicename(snum));
63 init_srv_share_info0(&sh0->info_0, net_name);
64 init_srv_share_info0_str(&sh0->info_0_str, net_name);
67 /*******************************************************************
68 Fill in a share info level 1 structure.
69 ********************************************************************/
71 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
73 pstring remark;
75 char *net_name = lp_servicename(snum);
76 pstrcpy(remark, lp_comment(snum));
77 standard_sub_conn(p->conn, remark,sizeof(remark));
79 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
80 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
83 /*******************************************************************
84 Fill in a share info level 2 structure.
85 ********************************************************************/
87 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
89 pstring remark;
90 pstring path;
91 pstring passwd;
93 char *net_name = lp_servicename(snum);
94 pstrcpy(remark, lp_comment(snum));
95 standard_sub_conn(p->conn, remark,sizeof(remark));
96 pstrcpy(path, "C:");
97 pstrcat(path, lp_pathname(snum));
100 * Change / to \\ so that win2k will see it as a valid path. This was added to
101 * enable use of browsing in win2k add share dialog.
104 string_replace(path, '/', '\\');
106 pstrcpy(passwd, "");
108 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
109 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
112 /*******************************************************************
113 What to do when smb.conf is updated.
114 ********************************************************************/
116 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
118 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
119 reload_services(False);
122 /*******************************************************************
123 Create the share security tdb.
124 ********************************************************************/
126 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
127 #define SHARE_DATABASE_VERSION_V1 1
128 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
130 BOOL share_info_db_init(void)
132 static pid_t local_pid;
133 char *vstring = "INFO/version";
134 int32 vers_id;
136 if (share_tdb && local_pid == sys_getpid())
137 return True;
138 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
139 if (!share_tdb) {
140 DEBUG(0,("Failed to open share info database %s (%s)\n",
141 lock_path("share_info.tdb"), strerror(errno) ));
142 return False;
145 local_pid = sys_getpid();
147 /* handle a Samba upgrade */
148 tdb_lock_bystring(share_tdb, vstring);
150 /* Cope with byte-reversed older versions of the db. */
151 vers_id = tdb_fetch_int32(share_tdb, vstring);
152 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
153 /* Written on a bigendian machine with old fetch_int code. Save as le. */
154 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
155 vers_id = SHARE_DATABASE_VERSION_V2;
158 if (vers_id != SHARE_DATABASE_VERSION_V2) {
159 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
160 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
162 tdb_unlock_bystring(share_tdb, vstring);
164 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
166 return True;
169 /*******************************************************************
170 Fake up a Everyone, full access as a default.
171 ********************************************************************/
173 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
175 extern DOM_SID global_sid_World;
176 extern struct generic_mapping file_generic_mapping;
177 SEC_ACCESS sa;
178 SEC_ACE ace;
179 SEC_ACL *psa = NULL;
180 SEC_DESC *psd = NULL;
181 uint32 def_access = GENERIC_ALL_ACCESS;
183 se_map_generic(&def_access, &file_generic_mapping);
185 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
186 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
188 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
189 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
192 if (!psd) {
193 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
194 return NULL;
197 return psd;
200 /*******************************************************************
201 Pull a security descriptor from the share tdb.
202 ********************************************************************/
204 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
206 prs_struct ps;
207 fstring key;
208 SEC_DESC *psd = NULL;
210 *psize = 0;
212 /* Fetch security descriptor from tdb */
214 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
216 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
217 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
219 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
221 return get_share_security_default(ctx, snum, psize);
224 if (psd)
225 *psize = sec_desc_size(psd);
227 prs_mem_free(&ps);
228 return psd;
231 /*******************************************************************
232 Store a security descriptor in the share db.
233 ********************************************************************/
235 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
237 prs_struct ps;
238 TALLOC_CTX *mem_ctx = NULL;
239 fstring key;
240 BOOL ret = False;
242 mem_ctx = talloc_init();
243 if (mem_ctx == NULL)
244 return False;
246 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
248 if (!sec_io_desc("share_security", &psd, &ps, 1))
249 goto out;
251 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
253 if (tdb_prs_store(share_tdb, key, &ps)==0) {
254 ret = True;
255 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
256 } else {
257 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
260 /* Free malloc'ed memory */
262 out:
264 prs_mem_free(&ps);
265 if (mem_ctx)
266 talloc_destroy(mem_ctx);
267 return ret;
270 /*******************************************************************
271 Delete a security descriptor.
272 ********************************************************************/
274 static BOOL delete_share_security(int snum)
276 TDB_DATA kbuf;
277 fstring key;
279 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
280 kbuf.dptr = key;
281 kbuf.dsize = strlen(key)+1;
283 if (tdb_delete(share_tdb, kbuf) != 0) {
284 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
285 lp_servicename(snum) ));
286 return False;
289 return True;
292 /*******************************************************************
293 Map any generic bits to file specific bits.
294 ********************************************************************/
296 void map_generic_share_sd_bits(SEC_DESC *psd)
298 extern struct generic_mapping file_generic_mapping;
299 int i;
300 SEC_ACL *ps_dacl = NULL;
302 if (!psd)
303 return;
305 ps_dacl = psd->dacl;
306 if (!ps_dacl)
307 return;
309 for (i = 0; i < ps_dacl->num_aces; i++) {
310 SEC_ACE *psa = &ps_dacl->ace[i];
311 uint32 orig_mask = psa->info.mask;
313 se_map_generic(&psa->info.mask, &file_generic_mapping);
314 psa->info.mask |= orig_mask;
318 /*******************************************************************
319 Can this user access with share with the required permissions ?
320 ********************************************************************/
322 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
324 uint32 granted;
325 NTSTATUS status;
326 TALLOC_CTX *mem_ctx = NULL;
327 SEC_DESC *psd = NULL;
328 size_t sd_size;
329 NT_USER_TOKEN *token = NULL;
330 BOOL ret = True;
332 mem_ctx = talloc_init();
333 if (mem_ctx == NULL)
334 return False;
336 psd = get_share_security(mem_ctx, snum, &sd_size);
338 if (!psd)
339 goto out;
341 if (vuser)
342 token = vuser->nt_user_token;
343 else
344 token = conn->nt_user_token;
346 ret = se_access_check(psd, token, desired_access, &granted, &status);
348 out:
350 talloc_destroy(mem_ctx);
352 return ret;
355 /*******************************************************************
356 Fill in a share info level 501 structure.
357 ********************************************************************/
359 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
361 int len_net_name;
362 pstring remark;
364 char *net_name = lp_servicename(snum);
365 pstrcpy(remark, lp_comment(snum));
366 standard_sub_conn(p->conn, remark, sizeof(remark));
368 len_net_name = strlen(net_name);
370 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
371 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
374 /*******************************************************************
375 Fill in a share info level 502 structure.
376 ********************************************************************/
378 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
380 int len_net_name;
381 pstring net_name;
382 pstring remark;
383 pstring path;
384 pstring passwd;
385 SEC_DESC *sd;
386 size_t sd_size;
387 TALLOC_CTX *ctx = p->mem_ctx;
390 ZERO_STRUCTP(sh502);
392 pstrcpy(net_name, lp_servicename(snum));
393 pstrcpy(remark, lp_comment(snum));
394 standard_sub_conn(p->conn, remark,sizeof(remark));
395 pstrcpy(path, "C:");
396 pstrcat(path, lp_pathname(snum));
399 * Change / to \\ so that win2k will see it as a valid path. This was added to
400 * enable use of browsing in win2k add share dialog.
403 string_replace(path, '/', '\\');
405 pstrcpy(passwd, "");
406 len_net_name = strlen(net_name);
408 sd = get_share_security(ctx, snum, &sd_size);
410 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
411 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
414 /***************************************************************************
415 Fill in a share info level 1004 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
420 pstring remark;
422 pstrcpy(remark, lp_comment(snum));
423 standard_sub_conn(p->conn, remark, sizeof(remark));
425 ZERO_STRUCTP(sh1004);
427 init_srv_share_info1004(&sh1004->info_1004, remark);
428 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
431 /***************************************************************************
432 Fill in a share info level 1005 structure.
433 ***************************************************************************/
435 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
437 sh1005->dfs_root_flag = 0;
439 if(lp_host_msdfs() && lp_msdfs_root(snum))
440 sh1005->dfs_root_flag = 3;
442 /***************************************************************************
443 Fill in a share info level 1006 structure.
444 ***************************************************************************/
446 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
448 sh1006->max_uses = -1;
451 /***************************************************************************
452 Fill in a share info level 1007 structure.
453 ***************************************************************************/
455 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
457 pstring alternate_directory_name = "";
458 uint32 flags = 0;
460 ZERO_STRUCTP(sh1007);
462 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
463 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
466 /*******************************************************************
467 Fill in a share info level 1501 structure.
468 ********************************************************************/
470 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
472 SEC_DESC *sd;
473 size_t sd_size;
474 TALLOC_CTX *ctx = p->mem_ctx;
476 ZERO_STRUCTP(sh1501);
478 sd = get_share_security(ctx, snum, &sd_size);
480 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
483 /*******************************************************************
484 True if it ends in '$'.
485 ********************************************************************/
487 static BOOL is_hidden_share(int snum)
489 pstring net_name;
491 pstrcpy(net_name, lp_servicename(snum));
492 return (net_name[strlen(net_name)] == '$') ? True : False;
495 /*******************************************************************
496 Fill in a share info structure.
497 ********************************************************************/
499 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
500 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
502 int num_entries = 0;
503 int num_services = lp_numservices();
504 int snum;
505 TALLOC_CTX *ctx = p->mem_ctx;
507 DEBUG(5,("init_srv_share_info_ctr\n"));
509 ZERO_STRUCTPN(ctr);
511 ctr->info_level = ctr->switch_value = info_level;
512 *resume_hnd = 0;
514 /* Count the number of entries. */
515 for (snum = 0; snum < num_services; snum++) {
516 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
517 num_entries++;
520 *total_entries = num_entries;
521 ctr->num_entries2 = ctr->num_entries = num_entries;
522 ctr->ptr_share_info = ctr->ptr_entries = 1;
524 if (!num_entries)
525 return True;
527 switch (info_level) {
528 case 0:
530 SRV_SHARE_INFO_0 *info0;
531 int i = 0;
533 info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
535 for (snum = *resume_hnd; snum < num_services; snum++) {
536 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
537 init_srv_share_info_0(p, &info0[i++], snum);
541 ctr->share.info0 = info0;
542 break;
546 case 1:
548 SRV_SHARE_INFO_1 *info1;
549 int i = 0;
551 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
553 for (snum = *resume_hnd; snum < num_services; snum++) {
554 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
555 init_srv_share_info_1(p, &info1[i++], snum);
559 ctr->share.info1 = info1;
560 break;
563 case 2:
565 SRV_SHARE_INFO_2 *info2;
566 int i = 0;
568 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
570 for (snum = *resume_hnd; snum < num_services; snum++) {
571 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
572 init_srv_share_info_2(p, &info2[i++], snum);
576 ctr->share.info2 = info2;
577 break;
580 case 501:
582 SRV_SHARE_INFO_501 *info501;
583 int i = 0;
585 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
587 for (snum = *resume_hnd; snum < num_services; snum++) {
588 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
589 init_srv_share_info_501(p, &info501[i++], snum);
593 ctr->share.info501 = info501;
594 break;
597 case 502:
599 SRV_SHARE_INFO_502 *info502;
600 int i = 0;
602 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
604 for (snum = *resume_hnd; snum < num_services; snum++) {
605 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
606 init_srv_share_info_502(p, &info502[i++], snum);
610 ctr->share.info502 = info502;
611 break;
614 /* here for completeness but not currently used with enum (1004 - 1501)*/
616 case 1004:
618 SRV_SHARE_INFO_1004 *info1004;
619 int i = 0;
621 info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
623 for (snum = *resume_hnd; snum < num_services; snum++) {
624 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
625 init_srv_share_info_1004(p, &info1004[i++], snum);
629 ctr->share.info1004 = info1004;
630 break;
633 case 1005:
635 SRV_SHARE_INFO_1005 *info1005;
636 int i = 0;
638 info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
640 for (snum = *resume_hnd; snum < num_services; snum++) {
641 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
642 init_srv_share_info_1005(p, &info1005[i++], snum);
646 ctr->share.info1005 = info1005;
647 break;
650 case 1006:
652 SRV_SHARE_INFO_1006 *info1006;
653 int i = 0;
655 info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
657 for (snum = *resume_hnd; snum < num_services; snum++) {
658 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
659 init_srv_share_info_1006(p, &info1006[i++], snum);
663 ctr->share.info1006 = info1006;
664 break;
667 case 1007:
669 SRV_SHARE_INFO_1007 *info1007;
670 int i = 0;
672 info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
674 for (snum = *resume_hnd; snum < num_services; snum++) {
675 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
676 init_srv_share_info_1007(p, &info1007[i++], snum);
680 ctr->share.info1007 = info1007;
681 break;
684 case 1501:
686 SRV_SHARE_INFO_1501 *info1501;
687 int i = 0;
689 info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
691 for (snum = *resume_hnd; snum < num_services; snum++) {
692 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
693 init_srv_share_info_1501(p, &info1501[i++], snum);
697 ctr->share.info1501 = info1501;
698 break;
700 default:
701 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
702 return False;
705 return True;
708 /*******************************************************************
709 Inits a SRV_R_NET_SHARE_ENUM structure.
710 ********************************************************************/
712 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
713 uint32 info_level, uint32 resume_hnd, BOOL all)
715 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
717 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
718 &resume_hnd, &r_n->total_entries, all)) {
719 r_n->status = WERR_OK;
720 } else {
721 r_n->status = WERR_UNKNOWN_LEVEL;
724 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
727 /*******************************************************************
728 Inits a SRV_R_NET_SHARE_GET_INFO structure.
729 ********************************************************************/
731 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
732 char *share_name, uint32 info_level)
734 WERROR status = WERR_OK;
735 int snum;
737 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
739 r_n->info.switch_value = info_level;
741 snum = find_service(share_name);
743 if (snum >= 0) {
744 switch (info_level) {
745 case 0:
746 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
747 break;
748 case 1:
749 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
750 break;
751 case 2:
752 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
753 break;
754 case 501:
755 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
756 break;
757 case 502:
758 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
759 break;
761 /* here for completeness */
762 case 1004:
763 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
764 break;
765 case 1005:
766 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
767 break;
769 /* here for completeness 1006 - 1501 */
770 case 1006:
771 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
772 break;
773 case 1007:
774 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
775 break;
776 case 1501:
777 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
778 break;
779 default:
780 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
781 status = WERR_UNKNOWN_LEVEL;
782 break;
784 } else {
785 status = WERR_INVALID_NAME;
788 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
789 r_n->status = status;
792 /*******************************************************************
793 fill in a sess info level 1 structure.
794 ********************************************************************/
796 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
798 init_srv_sess_info0(se0, name);
799 init_srv_sess_info0_str(str0, name);
802 /*******************************************************************
803 fill in a sess info level 0 structure.
804 ********************************************************************/
806 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
808 struct sessionid *session_list;
809 uint32 num_entries = 0;
810 (*stot) = list_sessions(&session_list);
812 if (ss0 == NULL) {
813 (*snum) = 0;
814 SAFE_FREE(session_list);
815 return;
818 DEBUG(5,("init_srv_sess_0_ss0\n"));
820 if (snum) {
821 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
822 init_srv_sess_0_info(&ss0->info_0[num_entries],
823 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
825 /* move on to creating next session */
826 /* move on to creating next sess */
827 num_entries++;
830 ss0->num_entries_read = num_entries;
831 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
832 ss0->num_entries_read2 = num_entries;
834 if ((*snum) >= (*stot)) {
835 (*snum) = 0;
838 } else {
839 ss0->num_entries_read = 0;
840 ss0->ptr_sess_info = 0;
841 ss0->num_entries_read2 = 0;
843 SAFE_FREE(session_list);
846 /*******************************************************************
847 fill in a sess info level 1 structure.
848 ********************************************************************/
850 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
851 char *name, char *user,
852 uint32 num_opens,
853 uint32 open_time, uint32 idle_time,
854 uint32 usr_flgs)
856 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
857 init_srv_sess_info1_str(str1, name, user);
860 /*******************************************************************
861 fill in a sess info level 1 structure.
862 ********************************************************************/
864 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
866 struct sessionid *session_list;
867 uint32 num_entries = 0;
868 (*stot) = list_sessions(&session_list);
870 if (ss1 == NULL) {
871 (*snum) = 0;
872 SAFE_FREE(session_list);
873 return;
876 DEBUG(5,("init_srv_sess_1_ss1\n"));
878 if (snum) {
879 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
880 init_srv_sess_1_info(&ss1->info_1[num_entries],
881 &ss1->info_1_str[num_entries],
882 session_list[*snum].remote_machine,
883 session_list[*snum].username,
884 1, 10, 5, 0);
886 /* move on to creating next session */
887 /* move on to creating next sess */
888 num_entries++;
891 ss1->num_entries_read = num_entries;
892 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
893 ss1->num_entries_read2 = num_entries;
895 if ((*snum) >= (*stot)) {
896 (*snum) = 0;
899 } else {
900 ss1->num_entries_read = 0;
901 ss1->ptr_sess_info = 0;
902 ss1->num_entries_read2 = 0;
904 (*stot) = 0;
908 /*******************************************************************
909 makes a SRV_R_NET_SESS_ENUM structure.
910 ********************************************************************/
912 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
913 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
915 WERROR status = WERR_OK;
916 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
918 ctr->switch_value = switch_value;
920 switch (switch_value) {
921 case 0:
922 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
923 ctr->ptr_sess_ctr = 1;
924 break;
925 case 1:
926 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
927 ctr->ptr_sess_ctr = 1;
928 break;
929 default:
930 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
931 (*resume_hnd) = 0;
932 (*total_entries) = 0;
933 ctr->ptr_sess_ctr = 0;
934 status = WERR_UNKNOWN_LEVEL;
935 break;
938 return status;
941 /*******************************************************************
942 makes a SRV_R_NET_SESS_ENUM structure.
943 ********************************************************************/
945 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
946 uint32 resume_hnd, int sess_level, int switch_value)
948 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
950 r_n->sess_level = sess_level;
952 if (sess_level == -1)
953 r_n->status = WERR_UNKNOWN_LEVEL;
954 else
955 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
957 if (!W_ERROR_IS_OK(r_n->status))
958 resume_hnd = 0;
960 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
963 /*******************************************************************
964 fill in a conn info level 0 structure.
965 ********************************************************************/
967 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
969 uint32 num_entries = 0;
970 (*stot) = 1;
972 if (ss0 == NULL) {
973 (*snum) = 0;
974 return;
977 DEBUG(5,("init_srv_conn_0_ss0\n"));
979 if (snum) {
980 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
982 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
984 /* move on to creating next connection */
985 /* move on to creating next conn */
986 num_entries++;
989 ss0->num_entries_read = num_entries;
990 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
991 ss0->num_entries_read2 = num_entries;
993 if ((*snum) >= (*stot)) {
994 (*snum) = 0;
997 } else {
998 ss0->num_entries_read = 0;
999 ss0->ptr_conn_info = 0;
1000 ss0->num_entries_read2 = 0;
1002 (*stot) = 0;
1006 /*******************************************************************
1007 fill in a conn info level 1 structure.
1008 ********************************************************************/
1010 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1011 uint32 id, uint32 type,
1012 uint32 num_opens, uint32 num_users, uint32 open_time,
1013 char *usr_name, char *net_name)
1015 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1016 init_srv_conn_info1_str(str1, usr_name, net_name);
1019 /*******************************************************************
1020 fill in a conn info level 1 structure.
1021 ********************************************************************/
1023 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1025 uint32 num_entries = 0;
1026 (*stot) = 1;
1028 if (ss1 == NULL) {
1029 (*snum) = 0;
1030 return;
1033 DEBUG(5,("init_srv_conn_1_ss1\n"));
1035 if (snum) {
1036 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1037 init_srv_conn_1_info(&ss1->info_1[num_entries],
1038 &ss1->info_1_str[num_entries],
1039 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1041 /* move on to creating next connection */
1042 /* move on to creating next conn */
1043 num_entries++;
1046 ss1->num_entries_read = num_entries;
1047 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1048 ss1->num_entries_read2 = num_entries;
1051 if ((*snum) >= (*stot)) {
1052 (*snum) = 0;
1055 } else {
1056 ss1->num_entries_read = 0;
1057 ss1->ptr_conn_info = 0;
1058 ss1->num_entries_read2 = 0;
1060 (*stot) = 0;
1064 /*******************************************************************
1065 makes a SRV_R_NET_CONN_ENUM structure.
1066 ********************************************************************/
1068 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1069 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1071 WERROR status = WERR_OK;
1072 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1074 ctr->switch_value = switch_value;
1076 switch (switch_value) {
1077 case 0:
1078 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1079 ctr->ptr_conn_ctr = 1;
1080 break;
1081 case 1:
1082 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1083 ctr->ptr_conn_ctr = 1;
1084 break;
1085 default:
1086 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1087 (*resume_hnd = 0);
1088 (*total_entries) = 0;
1089 ctr->ptr_conn_ctr = 0;
1090 status = WERR_UNKNOWN_LEVEL;
1091 break;
1094 return status;
1097 /*******************************************************************
1098 makes a SRV_R_NET_CONN_ENUM structure.
1099 ********************************************************************/
1101 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1102 uint32 resume_hnd, int conn_level, int switch_value)
1104 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1106 r_n->conn_level = conn_level;
1107 if (conn_level == -1)
1108 r_n->status = WERR_UNKNOWN_LEVEL;
1109 else
1110 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1112 if (!W_ERROR_IS_OK(r_n->status))
1113 resume_hnd = 0;
1115 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1118 /*******************************************************************
1119 makes a SRV_R_NET_FILE_ENUM structure.
1120 ********************************************************************/
1122 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1123 int switch_value, uint32 *resume_hnd,
1124 uint32 *total_entries)
1126 WERROR status = WERR_OK;
1127 TALLOC_CTX *ctx = p->mem_ctx;
1128 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1129 *total_entries = 1; /* dummy entries only, for */
1131 ctr->switch_value = switch_value;
1132 ctr->num_entries = *total_entries - *resume_hnd;
1133 ctr->num_entries2 = ctr->num_entries;
1135 switch (switch_value) {
1136 case 3: {
1137 int i;
1138 if (*total_entries > 0) {
1139 ctr->ptr_entries = 1;
1140 ctr->file.info3 = talloc(ctx, ctr->num_entries *
1141 sizeof(SRV_FILE_INFO_3));
1143 for (i=0 ;i<ctr->num_entries;i++) {
1144 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1145 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1148 ctr->ptr_file_info = 1;
1149 *resume_hnd = 0;
1150 break;
1152 default:
1153 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1154 (*resume_hnd = 0);
1155 (*total_entries) = 0;
1156 ctr->ptr_entries = 0;
1157 status = WERR_UNKNOWN_LEVEL;
1158 break;
1161 return status;
1164 /*******************************************************************
1165 makes a SRV_R_NET_FILE_ENUM structure.
1166 ********************************************************************/
1168 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1169 uint32 resume_hnd, int file_level, int switch_value)
1171 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1173 r_n->file_level = file_level;
1174 if (file_level == 0)
1175 r_n->status = WERR_UNKNOWN_LEVEL;
1176 else
1177 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1179 if (!W_ERROR_IS_OK(r_n->status))
1180 resume_hnd = 0;
1182 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1185 /*******************************************************************
1186 net server get info
1187 ********************************************************************/
1189 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)
1191 WERROR status = WERR_OK;
1192 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1194 if (!ctr)
1195 return WERR_NOMEM;
1197 ZERO_STRUCTP(ctr);
1199 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1201 if (!pipe_access_check(p)) {
1202 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1203 return WERR_ACCESS_DENIED;
1206 switch (q_u->switch_value) {
1208 /* Technically level 102 should only be available to
1209 Administrators but there isn't anything super-secret
1210 here, as most of it is made up. */
1212 case 102:
1213 init_srv_info_102(&ctr->srv.sv102,
1214 500, global_myname,
1215 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1216 lp_major_announce_version(), lp_minor_announce_version(),
1217 lp_default_server_announce(),
1218 0xffffffff, /* users */
1219 0xf, /* disc */
1220 0, /* hidden */
1221 240, /* announce */
1222 3000, /* announce delta */
1223 100000, /* licenses */
1224 "c:\\"); /* user path */
1225 break;
1226 case 101:
1227 init_srv_info_101(&ctr->srv.sv101,
1228 500, global_myname,
1229 lp_major_announce_version(), lp_minor_announce_version(),
1230 lp_default_server_announce(),
1231 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1232 break;
1233 case 100:
1234 init_srv_info_100(&ctr->srv.sv100, 500, global_myname);
1235 break;
1236 default:
1237 status = WERR_UNKNOWN_LEVEL;
1238 break;
1241 /* set up the net server get info structure */
1242 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1244 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1246 return r_u->status;
1249 /*******************************************************************
1250 net server set info
1251 ********************************************************************/
1253 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)
1255 WERROR status = WERR_OK;
1257 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1259 /* Set up the net server set info structure. */
1261 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1263 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1265 return r_u->status;
1268 /*******************************************************************
1269 net file enum
1270 ********************************************************************/
1272 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1274 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1276 /* set up the */
1277 init_srv_r_net_file_enum(p, r_u,
1278 get_enum_hnd(&q_u->enum_hnd),
1279 q_u->file_level,
1280 q_u->ctr.switch_value);
1282 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1284 return r_u->status;
1287 /*******************************************************************
1288 net conn enum
1289 ********************************************************************/
1291 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1293 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1295 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1296 if (!r_u->ctr)
1297 return WERR_NOMEM;
1299 ZERO_STRUCTP(r_u->ctr);
1301 /* set up the */
1302 init_srv_r_net_conn_enum(r_u,
1303 get_enum_hnd(&q_u->enum_hnd),
1304 q_u->conn_level,
1305 q_u->ctr->switch_value);
1307 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1309 return r_u->status;
1312 /*******************************************************************
1313 net sess enum
1314 ********************************************************************/
1316 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1318 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1320 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1321 if (!r_u->ctr)
1322 return WERR_NOMEM;
1324 ZERO_STRUCTP(r_u->ctr);
1326 /* set up the */
1327 init_srv_r_net_sess_enum(r_u,
1328 get_enum_hnd(&q_u->enum_hnd),
1329 q_u->sess_level,
1330 q_u->ctr->switch_value);
1332 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1334 return r_u->status;
1337 /*******************************************************************
1338 Net share enum all.
1339 ********************************************************************/
1341 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1343 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1345 if (!pipe_access_check(p)) {
1346 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1347 return WERR_ACCESS_DENIED;
1350 /* Create the list of shares for the response. */
1351 init_srv_r_net_share_enum(p, r_u,
1352 q_u->ctr.info_level,
1353 get_enum_hnd(&q_u->enum_hnd), True);
1355 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1357 return r_u->status;
1360 /*******************************************************************
1361 Net share enum.
1362 ********************************************************************/
1364 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1366 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1368 if (!pipe_access_check(p)) {
1369 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1370 return WERR_ACCESS_DENIED;
1373 /* Create the list of shares for the response. */
1374 init_srv_r_net_share_enum(p, r_u,
1375 q_u->ctr.info_level,
1376 get_enum_hnd(&q_u->enum_hnd), False);
1378 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1380 return r_u->status;
1383 /*******************************************************************
1384 Net share get info.
1385 ********************************************************************/
1387 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)
1389 fstring share_name;
1391 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1393 /* Create the list of shares for the response. */
1394 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1395 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1397 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1399 return r_u->status;
1402 /*******************************************************************
1403 Check a given DOS pathname is valid for a share.
1404 ********************************************************************/
1406 static char *valid_share_pathname(char *dos_pathname)
1408 pstring saved_pathname;
1409 pstring unix_pathname;
1410 char *ptr;
1411 int ret;
1413 /* Convert any '\' paths to '/' */
1414 unix_format(dos_pathname);
1415 unix_clean_name(dos_pathname);
1417 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1418 ptr = dos_pathname;
1419 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1420 ptr += 2;
1422 /* Only abolute paths allowed. */
1423 if (*ptr != '/')
1424 return NULL;
1426 /* Can we cd to it ? */
1428 /* First save our current directory. */
1429 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1430 return False;
1432 pstrcpy(unix_pathname, ptr);
1434 ret = chdir(unix_pathname);
1436 /* We *MUST* be able to chdir back. Abort if we can't. */
1437 if (chdir(saved_pathname) == -1)
1438 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1440 return (ret != -1) ? ptr : NULL;
1443 /*******************************************************************
1444 Net share set info. Modify share details.
1445 ********************************************************************/
1447 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)
1449 struct current_user user;
1450 pstring command;
1451 fstring share_name;
1452 fstring comment;
1453 pstring pathname;
1454 int type;
1455 int snum;
1456 int ret;
1457 char *ptr;
1458 SEC_DESC *psd = NULL;
1460 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1462 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1464 r_u->parm_error = 0;
1466 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1467 return WERR_ACCESS_DENIED;
1469 snum = find_service(share_name);
1471 /* Does this share exist ? */
1472 if (snum < 0)
1473 return WERR_INVALID_NAME;
1475 /* No change to printer shares. */
1476 if (lp_print_ok(snum))
1477 return WERR_ACCESS_DENIED;
1479 get_current_user(&user,p);
1481 if (user.uid != sec_initial_uid())
1482 return WERR_ACCESS_DENIED;
1484 switch (q_u->info_level) {
1485 case 1:
1486 fstrcpy(pathname, lp_pathname(snum));
1487 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1488 type = q_u->info.share.info2.info_2.type;
1489 psd = NULL;
1490 break;
1491 case 2:
1492 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1493 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1494 type = q_u->info.share.info2.info_2.type;
1495 psd = NULL;
1496 break;
1497 #if 0
1498 /* not supported on set but here for completeness */
1499 case 501:
1500 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1501 type = q_u->info.share.info501.info_501.type;
1502 psd = NULL;
1503 break;
1504 #endif
1505 case 502:
1506 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1507 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1508 type = q_u->info.share.info502.info_502.type;
1509 psd = q_u->info.share.info502.info_502_str.sd;
1510 map_generic_share_sd_bits(psd);
1511 break;
1512 case 1004:
1513 fstrcpy(pathname, lp_pathname(snum));
1514 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1515 type = STYPE_DISKTREE;
1516 break;
1517 case 1005:
1518 case 1006:
1519 case 1007:
1520 return WERR_ACCESS_DENIED;
1521 break;
1522 case 1501:
1523 fstrcpy(pathname, lp_pathname(snum));
1524 fstrcpy(comment, lp_comment(snum));
1525 psd = q_u->info.share.info1501.sdb->sec;
1526 map_generic_share_sd_bits(psd);
1527 type = STYPE_DISKTREE;
1528 break;
1529 default:
1530 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1531 return WERR_UNKNOWN_LEVEL;
1534 /* We can only modify disk shares. */
1535 if (type != STYPE_DISKTREE)
1536 return WERR_ACCESS_DENIED;
1538 /* Check if the pathname is valid. */
1539 if (!(ptr = valid_share_pathname( pathname )))
1540 return WERR_OBJECT_PATH_INVALID;
1542 /* Ensure share name, pathname and comment don't contain '"' characters. */
1543 string_replace(share_name, '"', ' ');
1544 string_replace(ptr, '"', ' ');
1545 string_replace(comment, '"', ' ');
1547 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1548 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1550 /* Only call modify function if something changed. */
1552 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1553 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1554 return WERR_ACCESS_DENIED;
1556 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1557 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1559 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1560 if ((ret = smbrun(command, NULL)) != 0) {
1561 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1562 return WERR_ACCESS_DENIED;
1565 /* Tell everyone we updated smb.conf. */
1566 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1568 } else {
1569 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1572 /* Replace SD if changed. */
1573 if (psd) {
1574 SEC_DESC *old_sd;
1575 size_t sd_size;
1577 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1579 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1580 if (!set_share_security(p->mem_ctx, share_name, psd))
1581 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1582 share_name ));
1586 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1588 return WERR_OK;
1591 /*******************************************************************
1592 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1593 ********************************************************************/
1595 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1597 struct current_user user;
1598 pstring command;
1599 fstring share_name;
1600 fstring comment;
1601 pstring pathname;
1602 int type;
1603 int snum;
1604 int ret;
1605 char *ptr;
1606 SEC_DESC *psd = NULL;
1608 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1610 r_u->parm_error = 0;
1612 get_current_user(&user,p);
1614 if (user.uid != sec_initial_uid()) {
1615 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1616 return WERR_ACCESS_DENIED;
1619 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1620 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1621 return WERR_ACCESS_DENIED;
1624 switch (q_u->info_level) {
1625 case 0:
1626 /* No path. Not enough info in a level 0 to do anything. */
1627 return WERR_ACCESS_DENIED;
1628 case 1:
1629 /* Not enough info in a level 1 to do anything. */
1630 return WERR_ACCESS_DENIED;
1631 case 2:
1632 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1633 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1634 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1635 type = q_u->info.share.info2.info_2.type;
1636 break;
1637 case 501:
1638 /* No path. Not enough info in a level 501 to do anything. */
1639 return WERR_ACCESS_DENIED;
1640 case 502:
1641 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1642 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1643 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1644 type = q_u->info.share.info502.info_502.type;
1645 psd = q_u->info.share.info502.info_502_str.sd;
1646 map_generic_share_sd_bits(psd);
1647 break;
1649 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1651 case 1004:
1652 case 1005:
1653 case 1006:
1654 case 1007:
1655 return WERR_ACCESS_DENIED;
1656 break;
1657 case 1501:
1658 /* DFS only level. */
1659 return WERR_ACCESS_DENIED;
1660 default:
1661 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1662 return WERR_UNKNOWN_LEVEL;
1665 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1666 return WERR_ACCESS_DENIED;
1668 snum = find_service(share_name);
1670 /* Share already exists. */
1671 if (snum >= 0)
1672 return WERR_ALREADY_EXISTS;
1674 /* We can only add disk shares. */
1675 if (type != STYPE_DISKTREE)
1676 return WERR_ACCESS_DENIED;
1678 /* Check if the pathname is valid. */
1679 if (!(ptr = valid_share_pathname( pathname )))
1680 return WERR_OBJECT_PATH_INVALID;
1682 /* Ensure share name, pathname and comment don't contain '"' characters. */
1683 string_replace(share_name, '"', ' ');
1684 string_replace(ptr, '"', ' ');
1685 string_replace(comment, '"', ' ');
1687 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1688 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1690 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1691 if ((ret = smbrun(command, NULL)) != 0) {
1692 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1693 return WERR_ACCESS_DENIED;
1696 if (psd) {
1697 if (!set_share_security(p->mem_ctx, share_name, psd))
1698 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1699 share_name ));
1702 /* Tell everyone we updated smb.conf. */
1703 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1706 * We don't call reload_services() here, the message will
1707 * cause this to be done before the next packet is read
1708 * from the client. JRA.
1711 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1713 return WERR_OK;
1716 /*******************************************************************
1717 Net share delete. Call "delete share command" with the share name as
1718 a parameter.
1719 ********************************************************************/
1721 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1723 struct current_user user;
1724 pstring command;
1725 fstring share_name;
1726 int ret;
1727 int snum;
1729 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1731 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1733 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1734 return WERR_ACCESS_DENIED;
1736 snum = find_service(share_name);
1738 if (snum < 0)
1739 return WERR_NO_SUCH_SHARE;
1741 /* No change to printer shares. */
1742 if (lp_print_ok(snum))
1743 return WERR_ACCESS_DENIED;
1745 get_current_user(&user,p);
1747 if (user.uid != sec_initial_uid())
1748 return WERR_ACCESS_DENIED;
1750 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1751 return WERR_ACCESS_DENIED;
1753 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1754 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1756 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1757 if ((ret = smbrun(command, NULL)) != 0) {
1758 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1759 return WERR_ACCESS_DENIED;
1762 /* Delete the SD in the database. */
1763 delete_share_security(snum);
1765 /* Tell everyone we updated smb.conf. */
1766 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1768 lp_killservice(snum);
1770 return WERR_OK;
1773 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1775 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1777 return _srv_net_share_del(p, q_u, r_u);
1780 /*******************************************************************
1781 time of day
1782 ********************************************************************/
1784 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1786 TIME_OF_DAY_INFO *tod;
1787 struct tm *t;
1788 time_t unixdate = time(NULL);
1790 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1791 if (!tod)
1792 return WERR_NOMEM;
1794 ZERO_STRUCTP(tod);
1796 r_u->tod = tod;
1797 r_u->ptr_srv_tod = 0x1;
1798 r_u->status = WERR_OK;
1800 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1802 t = gmtime(&unixdate);
1804 /* set up the */
1805 init_time_of_day_info(tod,
1806 unixdate,
1808 t->tm_hour,
1809 t->tm_min,
1810 t->tm_sec,
1812 TimeDiff(unixdate)/60,
1813 10000,
1814 t->tm_mday,
1815 t->tm_mon + 1,
1816 1900+t->tm_year,
1817 t->tm_wday);
1819 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1821 return r_u->status;
1824 /***********************************************************************************
1825 Win9x NT tools get security descriptor.
1826 ***********************************************************************************/
1828 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1829 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1831 SEC_DESC *psd = NULL;
1832 size_t sd_size;
1833 DATA_BLOB null_pw;
1834 pstring filename;
1835 pstring qualname;
1836 files_struct *fsp = NULL;
1837 SMB_STRUCT_STAT st;
1838 BOOL bad_path;
1839 int access_mode;
1840 int action;
1841 NTSTATUS nt_status;
1842 struct current_user user;
1843 connection_struct *conn = NULL;
1844 BOOL became_user = False;
1846 ZERO_STRUCT(st);
1848 r_u->status = WERR_OK;
1850 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1852 /* Null password is ok - we are already an authenticated user... */
1853 null_pw = data_blob(NULL, 0);
1855 get_current_user(&user, p);
1857 become_root();
1858 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1859 unbecome_root();
1861 if (conn == NULL) {
1862 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1863 r_u->status = ntstatus_to_werror(nt_status);
1864 goto error_exit;
1867 if (!become_user(conn, conn->vuid)) {
1868 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1869 r_u->status = WERR_ACCESS_DENIED;
1870 goto error_exit;
1872 became_user = True;
1874 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1875 unix_convert(filename, conn, NULL, &bad_path, &st);
1876 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1877 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1879 if (!fsp) {
1880 /* Perhaps it is a directory */
1881 if (errno == EISDIR)
1882 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1883 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1885 if (!fsp) {
1886 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1887 r_u->status = WERR_ACCESS_DENIED;
1888 goto error_exit;
1892 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1894 if (sd_size == 0) {
1895 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1896 r_u->status = WERR_ACCESS_DENIED;
1897 goto error_exit;
1900 r_u->ptr_response = 1;
1901 r_u->size_response = sd_size;
1902 r_u->ptr_secdesc = 1;
1903 r_u->size_secdesc = sd_size;
1904 r_u->sec_desc = psd;
1906 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1908 close_file(fsp, True);
1909 unbecome_user();
1910 close_cnum(conn, user.vuid);
1911 return r_u->status;
1913 error_exit:
1915 if(fsp) {
1916 close_file(fsp, True);
1919 if (became_user)
1920 unbecome_user();
1922 if (conn)
1923 close_cnum(conn, user.vuid);
1925 return r_u->status;
1928 /***********************************************************************************
1929 Win9x NT tools set security descriptor.
1930 ***********************************************************************************/
1932 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1933 SRV_R_NET_FILE_SET_SECDESC *r_u)
1935 BOOL ret;
1936 pstring filename;
1937 pstring qualname;
1938 DATA_BLOB null_pw;
1939 files_struct *fsp = NULL;
1940 SMB_STRUCT_STAT st;
1941 BOOL bad_path;
1942 int access_mode;
1943 int action;
1944 NTSTATUS nt_status;
1945 struct current_user user;
1946 connection_struct *conn = NULL;
1947 BOOL became_user = False;
1949 ZERO_STRUCT(st);
1951 r_u->status = WERR_OK;
1953 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1955 /* Null password is ok - we are already an authenticated user... */
1956 null_pw = data_blob(NULL, 0);
1958 get_current_user(&user, p);
1960 become_root();
1961 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1962 unbecome_root();
1964 if (conn == NULL) {
1965 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1966 r_u->status = ntstatus_to_werror(nt_status);
1967 goto error_exit;
1970 if (!become_user(conn, conn->vuid)) {
1971 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1972 r_u->status = WERR_ACCESS_DENIED;
1973 goto error_exit;
1975 became_user = True;
1977 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1978 unix_convert(filename, conn, NULL, &bad_path, &st);
1980 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1981 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1983 if (!fsp) {
1984 /* Perhaps it is a directory */
1985 if (errno == EISDIR)
1986 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1987 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1989 if (!fsp) {
1990 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1991 r_u->status = WERR_ACCESS_DENIED;
1992 goto error_exit;
1996 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1998 if (ret == False) {
1999 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2000 r_u->status = WERR_ACCESS_DENIED;
2001 goto error_exit;
2004 close_file(fsp, True);
2005 unbecome_user();
2006 close_cnum(conn, user.vuid);
2007 return r_u->status;
2009 error_exit:
2011 if(fsp) {
2012 close_file(fsp, True);
2015 if (became_user)
2016 unbecome_user();
2018 if (conn)
2019 close_cnum(conn, user.vuid);
2021 return r_u->status;
2024 /***********************************************************************************
2025 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2026 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2027 These disks would the disks listed by this function.
2028 Users could then create shares relative to these disks. Watch out for moving these disks around.
2029 "Nigel Williams" <nigel@veritas.com>.
2030 ***********************************************************************************/
2032 static const char *server_disks[] = {"C:"};
2034 static uint32 get_server_disk_count(void)
2036 return sizeof(server_disks)/sizeof(server_disks[0]);
2039 static uint32 init_server_disk_enum(uint32 *resume)
2041 uint32 server_disk_count = get_server_disk_count();
2043 /*resume can be an offset into the list for now*/
2045 if(*resume & 0x80000000)
2046 *resume = 0;
2048 if(*resume > server_disk_count)
2049 *resume = server_disk_count;
2051 return server_disk_count - *resume;
2054 static const char *next_server_disk_enum(uint32 *resume)
2056 const char *disk;
2058 if(init_server_disk_enum(resume) == 0)
2059 return NULL;
2061 disk = server_disks[*resume];
2063 (*resume)++;
2065 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2067 return disk;
2070 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2072 uint32 i;
2073 const char *disk_name;
2074 TALLOC_CTX *ctx = p->mem_ctx;
2075 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2077 r_u->status=WERR_OK;
2079 r_u->total_entries = init_server_disk_enum(&resume);
2081 r_u->disk_enum_ctr.unknown = 0;
2084 DISK_INFO *dinfo;
2086 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2088 if(!(dinfo = talloc(ctx, dinfo_size))) {
2089 return WERR_NOMEM;
2092 r_u->disk_enum_ctr.disk_info = dinfo;
2095 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2097 /*allow one DISK_INFO for null terminator*/
2099 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2101 r_u->disk_enum_ctr.entries_read++;
2103 /*copy disk name into a unicode string*/
2105 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2108 /* add a terminating null string. Is this there if there is more data to come? */
2110 r_u->disk_enum_ctr.entries_read++;
2112 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2114 init_enum_hnd(&r_u->enum_hnd, resume);
2116 return r_u->status;
2119 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2121 int snum;
2122 fstring share_name;
2124 r_u->status=WERR_OK;
2126 switch(q_u->type) {
2128 case 0x9:
2130 /*check if share name is ok*/
2131 /*also check if we already have a share with this name*/
2133 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2134 snum = find_service(share_name);
2136 /* Share already exists. */
2137 if (snum >= 0)
2138 r_u->status = WERR_ALREADY_EXISTS;
2139 break;
2141 default:
2142 /*unsupported type*/
2143 r_u->status = WERR_UNKNOWN_LEVEL;
2144 break;
2147 return r_u->status;