don't dereference null pointer
[Samba/gebeck_regimport.git] / source4 / rpc_server / srv_srvsvc_nt.c
blob44a63f2b853b249c92a7991442dfb3e0e4ce4f4e
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(struct request_context *req, struct tcon_context *conn, int snum, uint32 desired_access)
322 uint32 granted;
323 NTSTATUS status;
324 SEC_DESC *psd = NULL;
325 size_t sd_size;
326 NT_USER_TOKEN *token = NULL;
327 BOOL ret = True;
328 struct tcon_context *conn = req->conn;
330 psd = get_share_security(req->mem_ctx, snum, &sd_size);
332 if (!psd)
333 goto out;
335 if (conn->nt_user_token)
336 token = conn->nt_user_token;
337 else
338 token = req->user_ctx->nt_user_token;
340 ret = se_access_check(psd, token, desired_access, &granted, &status);
342 return ret;
345 /*******************************************************************
346 Fill in a share info level 501 structure.
347 ********************************************************************/
349 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
351 int len_net_name;
352 pstring remark;
354 char *net_name = lp_servicename(snum);
355 pstrcpy(remark, lp_comment(snum));
356 standard_sub_conn(p->conn, remark, sizeof(remark));
358 len_net_name = strlen(net_name);
360 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
361 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
364 /*******************************************************************
365 Fill in a share info level 502 structure.
366 ********************************************************************/
368 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
370 int len_net_name;
371 pstring net_name;
372 pstring remark;
373 pstring path;
374 pstring passwd;
375 SEC_DESC *sd;
376 size_t sd_size;
377 TALLOC_CTX *ctx = p->mem_ctx;
380 ZERO_STRUCTP(sh502);
382 pstrcpy(net_name, lp_servicename(snum));
383 pstrcpy(remark, lp_comment(snum));
384 standard_sub_conn(p->conn, remark,sizeof(remark));
385 pstrcpy(path, "C:");
386 pstrcat(path, lp_pathname(snum));
389 * Change / to \\ so that win2k will see it as a valid path. This was added to
390 * enable use of browsing in win2k add share dialog.
393 string_replace(path, '/', '\\');
395 pstrcpy(passwd, "");
396 len_net_name = strlen(net_name);
398 sd = get_share_security(ctx, snum, &sd_size);
400 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
401 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
404 /***************************************************************************
405 Fill in a share info level 1004 structure.
406 ***************************************************************************/
408 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
410 pstring remark;
412 pstrcpy(remark, lp_comment(snum));
413 standard_sub_conn(p->conn, remark, sizeof(remark));
415 ZERO_STRUCTP(sh1004);
417 init_srv_share_info1004(&sh1004->info_1004, remark);
418 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
421 /***************************************************************************
422 Fill in a share info level 1005 structure.
423 ***************************************************************************/
425 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
427 sh1005->dfs_root_flag = 0;
429 if(lp_host_msdfs() && lp_msdfs_root(snum))
430 sh1005->dfs_root_flag = 3;
432 /***************************************************************************
433 Fill in a share info level 1006 structure.
434 ***************************************************************************/
436 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
438 sh1006->max_uses = -1;
441 /***************************************************************************
442 Fill in a share info level 1007 structure.
443 ***************************************************************************/
445 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
447 pstring alternate_directory_name = "";
448 uint32 flags = 0;
450 ZERO_STRUCTP(sh1007);
452 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
453 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
456 /*******************************************************************
457 Fill in a share info level 1501 structure.
458 ********************************************************************/
460 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
462 SEC_DESC *sd;
463 size_t sd_size;
464 TALLOC_CTX *ctx = p->mem_ctx;
466 ZERO_STRUCTP(sh1501);
468 sd = get_share_security(ctx, snum, &sd_size);
470 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
473 /*******************************************************************
474 True if it ends in '$'.
475 ********************************************************************/
477 static BOOL is_hidden_share(int snum)
479 pstring net_name;
481 pstrcpy(net_name, lp_servicename(snum));
482 return (net_name[strlen(net_name)] == '$') ? True : False;
485 /*******************************************************************
486 Fill in a share info structure.
487 ********************************************************************/
489 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
490 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
492 int num_entries = 0;
493 int num_services = lp_numservices();
494 int snum;
495 TALLOC_CTX *ctx = p->mem_ctx;
497 DEBUG(5,("init_srv_share_info_ctr\n"));
499 ZERO_STRUCTPN(ctr);
501 ctr->info_level = ctr->switch_value = info_level;
502 *resume_hnd = 0;
504 /* Count the number of entries. */
505 for (snum = 0; snum < num_services; snum++) {
506 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
507 num_entries++;
510 *total_entries = num_entries;
511 ctr->num_entries2 = ctr->num_entries = num_entries;
512 ctr->ptr_share_info = ctr->ptr_entries = 1;
514 if (!num_entries)
515 return True;
517 switch (info_level) {
518 case 0:
520 SRV_SHARE_INFO_0 *info0;
521 int i = 0;
523 info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
525 for (snum = *resume_hnd; snum < num_services; snum++) {
526 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
527 init_srv_share_info_0(p, &info0[i++], snum);
531 ctr->share.info0 = info0;
532 break;
536 case 1:
538 SRV_SHARE_INFO_1 *info1;
539 int i = 0;
541 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
543 for (snum = *resume_hnd; snum < num_services; snum++) {
544 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
545 init_srv_share_info_1(p, &info1[i++], snum);
549 ctr->share.info1 = info1;
550 break;
553 case 2:
555 SRV_SHARE_INFO_2 *info2;
556 int i = 0;
558 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
560 for (snum = *resume_hnd; snum < num_services; snum++) {
561 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
562 init_srv_share_info_2(p, &info2[i++], snum);
566 ctr->share.info2 = info2;
567 break;
570 case 501:
572 SRV_SHARE_INFO_501 *info501;
573 int i = 0;
575 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
577 for (snum = *resume_hnd; snum < num_services; snum++) {
578 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
579 init_srv_share_info_501(p, &info501[i++], snum);
583 ctr->share.info501 = info501;
584 break;
587 case 502:
589 SRV_SHARE_INFO_502 *info502;
590 int i = 0;
592 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
594 for (snum = *resume_hnd; snum < num_services; snum++) {
595 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
596 init_srv_share_info_502(p, &info502[i++], snum);
600 ctr->share.info502 = info502;
601 break;
604 /* here for completeness but not currently used with enum (1004 - 1501)*/
606 case 1004:
608 SRV_SHARE_INFO_1004 *info1004;
609 int i = 0;
611 info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
613 for (snum = *resume_hnd; snum < num_services; snum++) {
614 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
615 init_srv_share_info_1004(p, &info1004[i++], snum);
619 ctr->share.info1004 = info1004;
620 break;
623 case 1005:
625 SRV_SHARE_INFO_1005 *info1005;
626 int i = 0;
628 info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
630 for (snum = *resume_hnd; snum < num_services; snum++) {
631 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
632 init_srv_share_info_1005(p, &info1005[i++], snum);
636 ctr->share.info1005 = info1005;
637 break;
640 case 1006:
642 SRV_SHARE_INFO_1006 *info1006;
643 int i = 0;
645 info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
647 for (snum = *resume_hnd; snum < num_services; snum++) {
648 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
649 init_srv_share_info_1006(p, &info1006[i++], snum);
653 ctr->share.info1006 = info1006;
654 break;
657 case 1007:
659 SRV_SHARE_INFO_1007 *info1007;
660 int i = 0;
662 info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
664 for (snum = *resume_hnd; snum < num_services; snum++) {
665 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
666 init_srv_share_info_1007(p, &info1007[i++], snum);
670 ctr->share.info1007 = info1007;
671 break;
674 case 1501:
676 SRV_SHARE_INFO_1501 *info1501;
677 int i = 0;
679 info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
681 for (snum = *resume_hnd; snum < num_services; snum++) {
682 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
683 init_srv_share_info_1501(p, &info1501[i++], snum);
687 ctr->share.info1501 = info1501;
688 break;
690 default:
691 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
692 return False;
695 return True;
698 /*******************************************************************
699 Inits a SRV_R_NET_SHARE_ENUM structure.
700 ********************************************************************/
702 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
703 uint32 info_level, uint32 resume_hnd, BOOL all)
705 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
707 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
708 &resume_hnd, &r_n->total_entries, all)) {
709 r_n->status = WERR_OK;
710 } else {
711 r_n->status = WERR_UNKNOWN_LEVEL;
714 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
717 /*******************************************************************
718 Inits a SRV_R_NET_SHARE_GET_INFO structure.
719 ********************************************************************/
721 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
722 char *share_name, uint32 info_level)
724 WERROR status = WERR_OK;
725 int snum;
727 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
729 r_n->info.switch_value = info_level;
731 snum = find_service(share_name);
733 if (snum >= 0) {
734 switch (info_level) {
735 case 0:
736 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
737 break;
738 case 1:
739 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
740 break;
741 case 2:
742 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
743 break;
744 case 501:
745 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
746 break;
747 case 502:
748 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
749 break;
751 /* here for completeness */
752 case 1004:
753 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
754 break;
755 case 1005:
756 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
757 break;
759 /* here for completeness 1006 - 1501 */
760 case 1006:
761 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
762 break;
763 case 1007:
764 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
765 break;
766 case 1501:
767 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
768 break;
769 default:
770 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
771 status = WERR_UNKNOWN_LEVEL;
772 break;
774 } else {
775 status = WERR_INVALID_NAME;
778 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
779 r_n->status = status;
782 /*******************************************************************
783 fill in a sess info level 1 structure.
784 ********************************************************************/
786 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
788 init_srv_sess_info0(se0, name);
789 init_srv_sess_info0_str(str0, name);
792 /*******************************************************************
793 fill in a sess info level 0 structure.
794 ********************************************************************/
796 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
798 struct sessionid *session_list;
799 uint32 num_entries = 0;
800 (*stot) = list_sessions(&session_list);
802 if (ss0 == NULL) {
803 (*snum) = 0;
804 SAFE_FREE(session_list);
805 return;
808 DEBUG(5,("init_srv_sess_0_ss0\n"));
810 if (snum) {
811 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
812 init_srv_sess_0_info(&ss0->info_0[num_entries],
813 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
815 /* move on to creating next session */
816 /* move on to creating next sess */
817 num_entries++;
820 ss0->num_entries_read = num_entries;
821 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
822 ss0->num_entries_read2 = num_entries;
824 if ((*snum) >= (*stot)) {
825 (*snum) = 0;
828 } else {
829 ss0->num_entries_read = 0;
830 ss0->ptr_sess_info = 0;
831 ss0->num_entries_read2 = 0;
833 SAFE_FREE(session_list);
836 /*******************************************************************
837 fill in a sess info level 1 structure.
838 ********************************************************************/
840 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
841 char *name, char *user,
842 uint32 num_opens,
843 uint32 open_time, uint32 idle_time,
844 uint32 usr_flgs)
846 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
847 init_srv_sess_info1_str(str1, name, user);
850 /*******************************************************************
851 fill in a sess info level 1 structure.
852 ********************************************************************/
854 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
856 struct sessionid *session_list;
857 uint32 num_entries = 0;
858 (*stot) = list_sessions(&session_list);
860 if (ss1 == NULL) {
861 (*snum) = 0;
862 SAFE_FREE(session_list);
863 return;
866 DEBUG(5,("init_srv_sess_1_ss1\n"));
868 if (snum) {
869 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
870 init_srv_sess_1_info(&ss1->info_1[num_entries],
871 &ss1->info_1_str[num_entries],
872 session_list[*snum].remote_machine,
873 session_list[*snum].username,
874 1, 10, 5, 0);
876 /* move on to creating next session */
877 /* move on to creating next sess */
878 num_entries++;
881 ss1->num_entries_read = num_entries;
882 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
883 ss1->num_entries_read2 = num_entries;
885 if ((*snum) >= (*stot)) {
886 (*snum) = 0;
889 } else {
890 ss1->num_entries_read = 0;
891 ss1->ptr_sess_info = 0;
892 ss1->num_entries_read2 = 0;
894 (*stot) = 0;
898 /*******************************************************************
899 makes a SRV_R_NET_SESS_ENUM structure.
900 ********************************************************************/
902 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
903 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
905 WERROR status = WERR_OK;
906 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
908 ctr->switch_value = switch_value;
910 switch (switch_value) {
911 case 0:
912 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
913 ctr->ptr_sess_ctr = 1;
914 break;
915 case 1:
916 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
917 ctr->ptr_sess_ctr = 1;
918 break;
919 default:
920 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
921 (*resume_hnd) = 0;
922 (*total_entries) = 0;
923 ctr->ptr_sess_ctr = 0;
924 status = WERR_UNKNOWN_LEVEL;
925 break;
928 return status;
931 /*******************************************************************
932 makes a SRV_R_NET_SESS_ENUM structure.
933 ********************************************************************/
935 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
936 uint32 resume_hnd, int sess_level, int switch_value)
938 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
940 r_n->sess_level = sess_level;
942 if (sess_level == -1)
943 r_n->status = WERR_UNKNOWN_LEVEL;
944 else
945 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
947 if (!W_ERROR_IS_OK(r_n->status))
948 resume_hnd = 0;
950 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
953 /*******************************************************************
954 fill in a conn info level 0 structure.
955 ********************************************************************/
957 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
959 uint32 num_entries = 0;
960 (*stot) = 1;
962 if (ss0 == NULL) {
963 (*snum) = 0;
964 return;
967 DEBUG(5,("init_srv_conn_0_ss0\n"));
969 if (snum) {
970 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
972 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
974 /* move on to creating next connection */
975 /* move on to creating next conn */
976 num_entries++;
979 ss0->num_entries_read = num_entries;
980 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
981 ss0->num_entries_read2 = num_entries;
983 if ((*snum) >= (*stot)) {
984 (*snum) = 0;
987 } else {
988 ss0->num_entries_read = 0;
989 ss0->ptr_conn_info = 0;
990 ss0->num_entries_read2 = 0;
992 (*stot) = 0;
996 /*******************************************************************
997 fill in a conn info level 1 structure.
998 ********************************************************************/
1000 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1001 uint32 id, uint32 type,
1002 uint32 num_opens, uint32 num_users, uint32 open_time,
1003 const char *usr_name, const char *net_name)
1005 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1006 init_srv_conn_info1_str(str1, usr_name, net_name);
1009 /*******************************************************************
1010 fill in a conn info level 1 structure.
1011 ********************************************************************/
1013 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1015 uint32 num_entries = 0;
1016 (*stot) = 1;
1018 if (ss1 == NULL) {
1019 (*snum) = 0;
1020 return;
1023 DEBUG(5,("init_srv_conn_1_ss1\n"));
1025 if (snum) {
1026 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1027 init_srv_conn_1_info(&ss1->info_1[num_entries],
1028 &ss1->info_1_str[num_entries],
1029 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1031 /* move on to creating next connection */
1032 /* move on to creating next conn */
1033 num_entries++;
1036 ss1->num_entries_read = num_entries;
1037 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1038 ss1->num_entries_read2 = num_entries;
1041 if ((*snum) >= (*stot)) {
1042 (*snum) = 0;
1045 } else {
1046 ss1->num_entries_read = 0;
1047 ss1->ptr_conn_info = 0;
1048 ss1->num_entries_read2 = 0;
1050 (*stot) = 0;
1054 /*******************************************************************
1055 makes a SRV_R_NET_CONN_ENUM structure.
1056 ********************************************************************/
1058 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1059 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1061 WERROR status = WERR_OK;
1062 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1064 ctr->switch_value = switch_value;
1066 switch (switch_value) {
1067 case 0:
1068 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1069 ctr->ptr_conn_ctr = 1;
1070 break;
1071 case 1:
1072 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1073 ctr->ptr_conn_ctr = 1;
1074 break;
1075 default:
1076 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1077 (*resume_hnd = 0);
1078 (*total_entries) = 0;
1079 ctr->ptr_conn_ctr = 0;
1080 status = WERR_UNKNOWN_LEVEL;
1081 break;
1084 return status;
1087 /*******************************************************************
1088 makes a SRV_R_NET_CONN_ENUM structure.
1089 ********************************************************************/
1091 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1092 uint32 resume_hnd, int conn_level, int switch_value)
1094 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1096 r_n->conn_level = conn_level;
1097 if (conn_level == -1)
1098 r_n->status = WERR_UNKNOWN_LEVEL;
1099 else
1100 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1102 if (!W_ERROR_IS_OK(r_n->status))
1103 resume_hnd = 0;
1105 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1108 /*******************************************************************
1109 makes a SRV_R_NET_FILE_ENUM structure.
1110 ********************************************************************/
1112 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1113 int switch_value, uint32 *resume_hnd,
1114 uint32 *total_entries)
1116 WERROR status = WERR_OK;
1117 TALLOC_CTX *ctx = p->mem_ctx;
1118 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1119 *total_entries = 1; /* dummy entries only, for */
1121 ctr->switch_value = switch_value;
1122 ctr->num_entries = *total_entries - *resume_hnd;
1123 ctr->num_entries2 = ctr->num_entries;
1125 switch (switch_value) {
1126 case 3: {
1127 int i;
1128 if (*total_entries > 0) {
1129 ctr->ptr_entries = 1;
1130 ctr->file.info3 = talloc(ctx, ctr->num_entries *
1131 sizeof(SRV_FILE_INFO_3));
1133 for (i=0 ;i<ctr->num_entries;i++) {
1134 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1135 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1138 ctr->ptr_file_info = 1;
1139 *resume_hnd = 0;
1140 break;
1142 default:
1143 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1144 (*resume_hnd = 0);
1145 (*total_entries) = 0;
1146 ctr->ptr_entries = 0;
1147 status = WERR_UNKNOWN_LEVEL;
1148 break;
1151 return status;
1154 /*******************************************************************
1155 makes a SRV_R_NET_FILE_ENUM structure.
1156 ********************************************************************/
1158 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1159 uint32 resume_hnd, int file_level, int switch_value)
1161 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1163 r_n->file_level = file_level;
1164 if (file_level == 0)
1165 r_n->status = WERR_UNKNOWN_LEVEL;
1166 else
1167 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1169 if (!W_ERROR_IS_OK(r_n->status))
1170 resume_hnd = 0;
1172 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1175 /*******************************************************************
1176 net server get info
1177 ********************************************************************/
1179 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)
1181 WERROR status = WERR_OK;
1182 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1184 if (!ctr)
1185 return WERR_NOMEM;
1187 ZERO_STRUCTP(ctr);
1189 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1191 if (!pipe_access_check(p)) {
1192 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1193 return WERR_ACCESS_DENIED;
1196 switch (q_u->switch_value) {
1198 /* Technically level 102 should only be available to
1199 Administrators but there isn't anything super-secret
1200 here, as most of it is made up. */
1202 case 102:
1203 init_srv_info_102(&ctr->srv.sv102,
1204 500, lp_netbios_name(),
1205 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1206 lp_major_announce_version(), lp_minor_announce_version(),
1207 lp_default_server_announce(),
1208 0xffffffff, /* users */
1209 0xf, /* disc */
1210 0, /* hidden */
1211 240, /* announce */
1212 3000, /* announce delta */
1213 100000, /* licenses */
1214 "c:\\"); /* user path */
1215 break;
1216 case 101:
1217 init_srv_info_101(&ctr->srv.sv101,
1218 500, lp_netbios_name(),
1219 lp_major_announce_version(), lp_minor_announce_version(),
1220 lp_default_server_announce(),
1221 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1222 break;
1223 case 100:
1224 init_srv_info_100(&ctr->srv.sv100, 500, lp_netbios_name());
1225 break;
1226 default:
1227 status = WERR_UNKNOWN_LEVEL;
1228 break;
1231 /* set up the net server get info structure */
1232 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1234 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1236 return r_u->status;
1239 /*******************************************************************
1240 net server set info
1241 ********************************************************************/
1243 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)
1245 WERROR status = WERR_OK;
1247 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1249 /* Set up the net server set info structure. */
1251 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1253 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1255 return r_u->status;
1258 /*******************************************************************
1259 net file enum
1260 ********************************************************************/
1262 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1264 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1266 /* set up the */
1267 init_srv_r_net_file_enum(p, r_u,
1268 get_enum_hnd(&q_u->enum_hnd),
1269 q_u->file_level,
1270 q_u->ctr.switch_value);
1272 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1274 return r_u->status;
1277 /*******************************************************************
1278 net conn enum
1279 ********************************************************************/
1281 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1283 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1285 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1286 if (!r_u->ctr)
1287 return WERR_NOMEM;
1289 ZERO_STRUCTP(r_u->ctr);
1291 /* set up the */
1292 init_srv_r_net_conn_enum(r_u,
1293 get_enum_hnd(&q_u->enum_hnd),
1294 q_u->conn_level,
1295 q_u->ctr->switch_value);
1297 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1299 return r_u->status;
1302 /*******************************************************************
1303 net sess enum
1304 ********************************************************************/
1306 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1308 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1310 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1311 if (!r_u->ctr)
1312 return WERR_NOMEM;
1314 ZERO_STRUCTP(r_u->ctr);
1316 /* set up the */
1317 init_srv_r_net_sess_enum(r_u,
1318 get_enum_hnd(&q_u->enum_hnd),
1319 q_u->sess_level,
1320 q_u->ctr->switch_value);
1322 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1324 return r_u->status;
1327 /*******************************************************************
1328 Net share enum all.
1329 ********************************************************************/
1331 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1333 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1335 if (!pipe_access_check(p)) {
1336 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1337 return WERR_ACCESS_DENIED;
1340 /* Create the list of shares for the response. */
1341 init_srv_r_net_share_enum(p, r_u,
1342 q_u->ctr.info_level,
1343 get_enum_hnd(&q_u->enum_hnd), True);
1345 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1347 return r_u->status;
1350 /*******************************************************************
1351 Net share enum.
1352 ********************************************************************/
1354 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1356 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1358 if (!pipe_access_check(p)) {
1359 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1360 return WERR_ACCESS_DENIED;
1363 /* Create the list of shares for the response. */
1364 init_srv_r_net_share_enum(p, r_u,
1365 q_u->ctr.info_level,
1366 get_enum_hnd(&q_u->enum_hnd), False);
1368 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1370 return r_u->status;
1373 /*******************************************************************
1374 Net share get info.
1375 ********************************************************************/
1377 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)
1379 fstring share_name;
1381 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1383 /* Create the list of shares for the response. */
1384 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1385 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1387 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1389 return r_u->status;
1392 /*******************************************************************
1393 Check a given DOS pathname is valid for a share.
1394 ********************************************************************/
1396 static char *valid_share_pathname(char *dos_pathname)
1398 pstring saved_pathname;
1399 pstring unix_pathname;
1400 char *ptr;
1401 int ret;
1403 /* Convert any '\' paths to '/' */
1404 unix_format(dos_pathname);
1405 unix_clean_name(dos_pathname);
1407 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1408 ptr = dos_pathname;
1409 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1410 ptr += 2;
1412 /* Only abolute paths allowed. */
1413 if (*ptr != '/')
1414 return NULL;
1416 /* Can we cd to it ? */
1418 /* First save our current directory. */
1419 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1420 return False;
1422 pstrcpy(unix_pathname, ptr);
1424 ret = chdir(unix_pathname);
1426 /* We *MUST* be able to chdir back. Abort if we can't. */
1427 if (chdir(saved_pathname) == -1)
1428 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1430 return (ret != -1) ? ptr : NULL;
1433 /*******************************************************************
1434 Net share set info. Modify share details.
1435 ********************************************************************/
1437 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)
1439 struct current_user user;
1440 pstring command;
1441 fstring share_name;
1442 fstring comment;
1443 pstring pathname;
1444 int type;
1445 int snum;
1446 int ret;
1447 char *ptr;
1448 SEC_DESC *psd = NULL;
1450 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1452 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1454 r_u->parm_error = 0;
1456 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1457 return WERR_ACCESS_DENIED;
1459 snum = find_service(share_name);
1461 /* Does this share exist ? */
1462 if (snum < 0)
1463 return WERR_INVALID_NAME;
1465 /* No change to printer shares. */
1466 if (lp_print_ok(snum))
1467 return WERR_ACCESS_DENIED;
1469 get_current_user(&user,p);
1471 if (user.uid != sec_initial_uid())
1472 return WERR_ACCESS_DENIED;
1474 switch (q_u->info_level) {
1475 case 1:
1476 pstrcpy(pathname, lp_pathname(snum));
1477 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1478 type = q_u->info.share.info2.info_2.type;
1479 psd = NULL;
1480 break;
1481 case 2:
1482 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1483 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1484 type = q_u->info.share.info2.info_2.type;
1485 psd = NULL;
1486 break;
1487 #if 0
1488 /* not supported on set but here for completeness */
1489 case 501:
1490 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1491 type = q_u->info.share.info501.info_501.type;
1492 psd = NULL;
1493 break;
1494 #endif
1495 case 502:
1496 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1497 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1498 type = q_u->info.share.info502.info_502.type;
1499 psd = q_u->info.share.info502.info_502_str.sd;
1500 map_generic_share_sd_bits(psd);
1501 break;
1502 case 1004:
1503 pstrcpy(pathname, lp_pathname(snum));
1504 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1505 type = STYPE_DISKTREE;
1506 break;
1507 case 1005:
1508 case 1006:
1509 case 1007:
1510 return WERR_ACCESS_DENIED;
1511 break;
1512 case 1501:
1513 pstrcpy(pathname, lp_pathname(snum));
1514 fstrcpy(comment, lp_comment(snum));
1515 psd = q_u->info.share.info1501.sdb->sec;
1516 map_generic_share_sd_bits(psd);
1517 type = STYPE_DISKTREE;
1518 break;
1519 default:
1520 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1521 return WERR_UNKNOWN_LEVEL;
1524 /* We can only modify disk shares. */
1525 if (type != STYPE_DISKTREE)
1526 return WERR_ACCESS_DENIED;
1528 /* Check if the pathname is valid. */
1529 if (!(ptr = valid_share_pathname( pathname )))
1530 return WERR_OBJECT_PATH_INVALID;
1532 /* Ensure share name, pathname and comment don't contain '"' characters. */
1533 string_replace(share_name, '"', ' ');
1534 string_replace(ptr, '"', ' ');
1535 string_replace(comment, '"', ' ');
1537 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1538 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1540 /* Only call modify function if something changed. */
1542 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1543 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1544 return WERR_ACCESS_DENIED;
1546 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1547 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1549 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1550 if ((ret = smbrun(command, NULL)) != 0) {
1551 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1552 return WERR_ACCESS_DENIED;
1555 /* Tell everyone we updated smb.conf. */
1556 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1558 } else {
1559 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1562 /* Replace SD if changed. */
1563 if (psd) {
1564 SEC_DESC *old_sd;
1565 size_t sd_size;
1567 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1569 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1570 if (!set_share_security(p->mem_ctx, share_name, psd))
1571 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1572 share_name ));
1576 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1578 return WERR_OK;
1581 /*******************************************************************
1582 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1583 ********************************************************************/
1585 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1587 struct current_user user;
1588 pstring command;
1589 fstring share_name;
1590 fstring comment;
1591 pstring pathname;
1592 int type;
1593 int snum;
1594 int ret;
1595 char *ptr;
1596 SEC_DESC *psd = NULL;
1598 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1600 r_u->parm_error = 0;
1602 get_current_user(&user,p);
1604 if (user.uid != sec_initial_uid()) {
1605 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1606 return WERR_ACCESS_DENIED;
1609 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1610 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1611 return WERR_ACCESS_DENIED;
1614 switch (q_u->info_level) {
1615 case 0:
1616 /* No path. Not enough info in a level 0 to do anything. */
1617 return WERR_ACCESS_DENIED;
1618 case 1:
1619 /* Not enough info in a level 1 to do anything. */
1620 return WERR_ACCESS_DENIED;
1621 case 2:
1622 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1623 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1624 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1625 type = q_u->info.share.info2.info_2.type;
1626 break;
1627 case 501:
1628 /* No path. Not enough info in a level 501 to do anything. */
1629 return WERR_ACCESS_DENIED;
1630 case 502:
1631 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1632 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1633 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1634 type = q_u->info.share.info502.info_502.type;
1635 psd = q_u->info.share.info502.info_502_str.sd;
1636 map_generic_share_sd_bits(psd);
1637 break;
1639 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1641 case 1004:
1642 case 1005:
1643 case 1006:
1644 case 1007:
1645 return WERR_ACCESS_DENIED;
1646 break;
1647 case 1501:
1648 /* DFS only level. */
1649 return WERR_ACCESS_DENIED;
1650 default:
1651 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1652 return WERR_UNKNOWN_LEVEL;
1655 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1656 return WERR_ACCESS_DENIED;
1658 snum = find_service(share_name);
1660 /* Share already exists. */
1661 if (snum >= 0)
1662 return WERR_ALREADY_EXISTS;
1664 /* We can only add disk shares. */
1665 if (type != STYPE_DISKTREE)
1666 return WERR_ACCESS_DENIED;
1668 /* Check if the pathname is valid. */
1669 if (!(ptr = valid_share_pathname( pathname )))
1670 return WERR_OBJECT_PATH_INVALID;
1672 /* Ensure share name, pathname and comment don't contain '"' characters. */
1673 string_replace(share_name, '"', ' ');
1674 string_replace(ptr, '"', ' ');
1675 string_replace(comment, '"', ' ');
1677 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1678 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1680 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1681 if ((ret = smbrun(command, NULL)) != 0) {
1682 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1683 return WERR_ACCESS_DENIED;
1686 if (psd) {
1687 if (!set_share_security(p->mem_ctx, share_name, psd))
1688 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1689 share_name ));
1692 /* Tell everyone we updated smb.conf. */
1693 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1696 * We don't call reload_services() here, the message will
1697 * cause this to be done before the next packet is read
1698 * from the client. JRA.
1701 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1703 return WERR_OK;
1706 /*******************************************************************
1707 Net share delete. Call "delete share command" with the share name as
1708 a parameter.
1709 ********************************************************************/
1711 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1713 struct current_user user;
1714 pstring command;
1715 fstring share_name;
1716 int ret;
1717 int snum;
1719 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1721 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1723 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1724 return WERR_ACCESS_DENIED;
1726 snum = find_service(share_name);
1728 if (snum < 0)
1729 return WERR_NO_SUCH_SHARE;
1731 /* No change to printer shares. */
1732 if (lp_print_ok(snum))
1733 return WERR_ACCESS_DENIED;
1735 get_current_user(&user,p);
1737 if (user.uid != sec_initial_uid())
1738 return WERR_ACCESS_DENIED;
1740 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1741 return WERR_ACCESS_DENIED;
1743 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1744 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1746 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1747 if ((ret = smbrun(command, NULL)) != 0) {
1748 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1749 return WERR_ACCESS_DENIED;
1752 /* Delete the SD in the database. */
1753 delete_share_security(snum);
1755 /* Tell everyone we updated smb.conf. */
1756 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1758 lp_killservice(snum);
1760 return WERR_OK;
1763 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1765 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1767 return _srv_net_share_del(p, q_u, r_u);
1770 /*******************************************************************
1771 time of day
1772 ********************************************************************/
1774 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1776 TIME_OF_DAY_INFO *tod;
1777 struct tm *t;
1778 time_t unixdate = time(NULL);
1780 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1781 if (!tod)
1782 return WERR_NOMEM;
1784 ZERO_STRUCTP(tod);
1786 r_u->tod = tod;
1787 r_u->ptr_srv_tod = 0x1;
1788 r_u->status = WERR_OK;
1790 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1792 t = gmtime(&unixdate);
1794 /* set up the */
1795 init_time_of_day_info(tod,
1796 unixdate,
1798 t->tm_hour,
1799 t->tm_min,
1800 t->tm_sec,
1802 TimeDiff(unixdate)/60,
1803 10000,
1804 t->tm_mday,
1805 t->tm_mon + 1,
1806 1900+t->tm_year,
1807 t->tm_wday);
1809 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1811 return r_u->status;
1814 /***********************************************************************************
1815 Win9x NT tools get security descriptor.
1816 ***********************************************************************************/
1818 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1819 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1821 SEC_DESC *psd = NULL;
1822 size_t sd_size;
1823 DATA_BLOB null_pw;
1824 pstring filename;
1825 pstring qualname;
1826 files_struct *fsp = NULL;
1827 SMB_STRUCT_STAT st;
1828 BOOL bad_path;
1829 int access_mode;
1830 int action;
1831 NTSTATUS nt_status;
1832 struct current_user user;
1833 struct tcon_context *conn = NULL;
1834 BOOL became_user = False;
1836 ZERO_STRUCT(st);
1838 r_u->status = WERR_OK;
1840 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1842 /* Null password is ok - we are already an authenticated user... */
1843 null_pw = data_blob(NULL, 0);
1845 get_current_user(&user, p);
1847 become_root();
1848 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1849 unbecome_root();
1851 if (conn == NULL) {
1852 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1853 r_u->status = ntstatus_to_werror(nt_status);
1854 goto error_exit;
1857 if (!become_user(conn, conn->vuid)) {
1858 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1859 r_u->status = WERR_ACCESS_DENIED;
1860 goto error_exit;
1862 became_user = True;
1864 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1865 unix_convert(filename, conn, NULL, &bad_path, &st);
1866 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1867 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1869 if (!fsp) {
1870 /* Perhaps it is a directory */
1871 if (errno == EISDIR)
1872 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1873 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1875 if (!fsp) {
1876 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1877 r_u->status = WERR_ACCESS_DENIED;
1878 goto error_exit;
1882 sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1884 if (sd_size == 0) {
1885 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1886 r_u->status = WERR_ACCESS_DENIED;
1887 goto error_exit;
1890 r_u->ptr_response = 1;
1891 r_u->size_response = sd_size;
1892 r_u->ptr_secdesc = 1;
1893 r_u->size_secdesc = sd_size;
1894 r_u->sec_desc = psd;
1896 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1898 close_file(fsp, True);
1899 unbecome_user();
1900 close_cnum(conn, user.vuid);
1901 return r_u->status;
1903 error_exit:
1905 if(fsp) {
1906 close_file(fsp, True);
1909 if (became_user)
1910 unbecome_user();
1912 if (conn)
1913 close_cnum(conn, user.vuid);
1915 return r_u->status;
1918 /***********************************************************************************
1919 Win9x NT tools set security descriptor.
1920 ***********************************************************************************/
1922 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1923 SRV_R_NET_FILE_SET_SECDESC *r_u)
1925 BOOL ret;
1926 pstring filename;
1927 pstring qualname;
1928 DATA_BLOB null_pw;
1929 files_struct *fsp = NULL;
1930 SMB_STRUCT_STAT st;
1931 BOOL bad_path;
1932 int access_mode;
1933 int action;
1934 NTSTATUS nt_status;
1935 struct current_user user;
1936 struct tcon_context *conn = NULL;
1937 BOOL became_user = False;
1939 ZERO_STRUCT(st);
1941 r_u->status = WERR_OK;
1943 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1945 /* Null password is ok - we are already an authenticated user... */
1946 null_pw = data_blob(NULL, 0);
1948 get_current_user(&user, p);
1950 become_root();
1951 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1952 unbecome_root();
1954 if (conn == NULL) {
1955 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1956 r_u->status = ntstatus_to_werror(nt_status);
1957 goto error_exit;
1960 if (!become_user(conn, conn->vuid)) {
1961 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1962 r_u->status = WERR_ACCESS_DENIED;
1963 goto error_exit;
1965 became_user = True;
1967 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1968 unix_convert(filename, conn, NULL, &bad_path, &st);
1970 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1971 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1973 if (!fsp) {
1974 /* Perhaps it is a directory */
1975 if (errno == EISDIR)
1976 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1977 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1979 if (!fsp) {
1980 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1981 r_u->status = WERR_ACCESS_DENIED;
1982 goto error_exit;
1986 ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1988 if (ret == False) {
1989 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1990 r_u->status = WERR_ACCESS_DENIED;
1991 goto error_exit;
1994 close_file(fsp, True);
1995 unbecome_user();
1996 close_cnum(conn, user.vuid);
1997 return r_u->status;
1999 error_exit:
2001 if(fsp) {
2002 close_file(fsp, True);
2005 if (became_user)
2006 unbecome_user();
2008 if (conn)
2009 close_cnum(conn, user.vuid);
2011 return r_u->status;
2014 /***********************************************************************************
2015 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2016 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2017 These disks would the disks listed by this function.
2018 Users could then create shares relative to these disks. Watch out for moving these disks around.
2019 "Nigel Williams" <nigel@veritas.com>.
2020 ***********************************************************************************/
2022 static const char *server_disks[] = {"C:"};
2024 static uint32 get_server_disk_count(void)
2026 return sizeof(server_disks)/sizeof(server_disks[0]);
2029 static uint32 init_server_disk_enum(uint32 *resume)
2031 uint32 server_disk_count = get_server_disk_count();
2033 /*resume can be an offset into the list for now*/
2035 if(*resume & 0x80000000)
2036 *resume = 0;
2038 if(*resume > server_disk_count)
2039 *resume = server_disk_count;
2041 return server_disk_count - *resume;
2044 static const char *next_server_disk_enum(uint32 *resume)
2046 const char *disk;
2048 if(init_server_disk_enum(resume) == 0)
2049 return NULL;
2051 disk = server_disks[*resume];
2053 (*resume)++;
2055 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2057 return disk;
2060 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2062 uint32 i;
2063 const char *disk_name;
2064 TALLOC_CTX *ctx = p->mem_ctx;
2065 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2067 r_u->status=WERR_OK;
2069 r_u->total_entries = init_server_disk_enum(&resume);
2071 r_u->disk_enum_ctr.unknown = 0;
2074 DISK_INFO *dinfo;
2076 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2078 if(!(dinfo = talloc(ctx, dinfo_size))) {
2079 return WERR_NOMEM;
2082 r_u->disk_enum_ctr.disk_info = dinfo;
2085 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2087 /*allow one DISK_INFO for null terminator*/
2089 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2091 r_u->disk_enum_ctr.entries_read++;
2093 /*copy disk name into a unicode string*/
2095 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2098 /* add a terminating null string. Is this there if there is more data to come? */
2100 r_u->disk_enum_ctr.entries_read++;
2102 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2104 init_enum_hnd(&r_u->enum_hnd, resume);
2106 return r_u->status;
2109 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2111 int snum;
2112 fstring share_name;
2114 r_u->status=WERR_OK;
2116 switch(q_u->type) {
2118 case 0x9:
2120 /*check if share name is ok*/
2121 /*also check if we already have a share with this name*/
2123 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2124 snum = find_service(share_name);
2126 /* Share already exists. */
2127 if (snum >= 0)
2128 r_u->status = WERR_ALREADY_EXISTS;
2129 break;
2131 default:
2132 /*unsupported type*/
2133 r_u->status = WERR_UNKNOWN_LEVEL;
2134 break;
2137 return r_u->status;