r13081: correct fix for the segv in nmbd caused by a double free on namerec.
[Samba/gbeck.git] / source3 / rpc_server / srv_srvsvc_nt.c
blobb0e8111f62acd37628e85f3472567f1125aec9b5
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 extern struct generic_mapping file_generic_mapping;
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_RPC_SRV
32 #define INVALID_SHARENAME_CHARS "<>*?|/\\+=;:\","
34 /********************************************************************
35 Check a string for any occurrences of a specified list of invalid
36 characters.
37 ********************************************************************/
39 static BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
41 int i;
43 for ( i=0; i<max_len && name[i]; i++ ) {
44 /* fail if strchr_m() finds one of the invalid characters */
45 if ( name[i] && strchr_m( invalid_chars, name[i] ) )
46 return False;
49 return True;
52 /*******************************************************************
53 Utility function to get the 'type' of a share from an snum.
54 ********************************************************************/
55 static uint32 get_share_type(int snum)
57 char *net_name = lp_servicename(snum);
58 int len_net_name = strlen(net_name);
60 /* work out the share type */
61 uint32 type = STYPE_DISKTREE;
63 if (lp_print_ok(snum))
64 type = STYPE_PRINTQ;
65 if (strequal(lp_fstype(snum), "IPC"))
66 type = STYPE_IPC;
67 if (net_name[len_net_name] == '$')
68 type |= STYPE_HIDDEN;
70 return type;
73 /*******************************************************************
74 Fill in a share info level 0 structure.
75 ********************************************************************/
77 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
79 pstring net_name;
81 pstrcpy(net_name, lp_servicename(snum));
83 init_srv_share_info0(&sh0->info_0, net_name);
84 init_srv_share_info0_str(&sh0->info_0_str, net_name);
87 /*******************************************************************
88 Fill in a share info level 1 structure.
89 ********************************************************************/
91 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
93 pstring remark;
95 char *net_name = lp_servicename(snum);
96 pstrcpy(remark, lp_comment(snum));
97 standard_sub_conn(p->conn, remark,sizeof(remark));
99 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
100 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
103 /*******************************************************************
104 Fill in a share info level 2 structure.
105 ********************************************************************/
107 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
109 pstring remark;
110 pstring path;
111 pstring passwd;
113 char *net_name = lp_servicename(snum);
114 pstrcpy(remark, lp_comment(snum));
115 standard_sub_conn(p->conn, remark,sizeof(remark));
116 pstrcpy(path, "C:");
117 pstrcat(path, lp_pathname(snum));
120 * Change / to \\ so that win2k will see it as a valid path. This was added to
121 * enable use of browsing in win2k add share dialog.
124 string_replace(path, '/', '\\');
126 pstrcpy(passwd, "");
128 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
129 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
132 /*******************************************************************
133 What to do when smb.conf is updated.
134 ********************************************************************/
136 static void smb_conf_updated(int msg_type, struct process_id src,
137 void *buf, size_t len)
139 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
140 reload_services(False);
143 /*******************************************************************
144 Create the share security tdb.
145 ********************************************************************/
147 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
148 #define SHARE_DATABASE_VERSION_V1 1
149 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
151 BOOL share_info_db_init(void)
153 static pid_t local_pid;
154 const char *vstring = "INFO/version";
155 int32 vers_id;
157 if (share_tdb && local_pid == sys_getpid())
158 return True;
159 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
160 if (!share_tdb) {
161 DEBUG(0,("Failed to open share info database %s (%s)\n",
162 lock_path("share_info.tdb"), strerror(errno) ));
163 return False;
166 local_pid = sys_getpid();
168 /* handle a Samba upgrade */
169 tdb_lock_bystring(share_tdb, vstring, 0);
171 /* Cope with byte-reversed older versions of the db. */
172 vers_id = tdb_fetch_int32(share_tdb, vstring);
173 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
174 /* Written on a bigendian machine with old fetch_int code. Save as le. */
175 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
176 vers_id = SHARE_DATABASE_VERSION_V2;
179 if (vers_id != SHARE_DATABASE_VERSION_V2) {
180 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
181 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
183 tdb_unlock_bystring(share_tdb, vstring);
185 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
187 return True;
190 /*******************************************************************
191 Fake up a Everyone, full access as a default.
192 ********************************************************************/
194 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
196 SEC_ACCESS sa;
197 SEC_ACE ace;
198 SEC_ACL *psa = NULL;
199 SEC_DESC *psd = NULL;
200 uint32 def_access = GENERIC_ALL_ACCESS;
202 se_map_generic(&def_access, &file_generic_mapping);
204 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
205 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
207 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
208 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, psize);
211 if (!psd) {
212 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
213 return NULL;
216 return psd;
219 /*******************************************************************
220 Pull a security descriptor from the share tdb.
221 ********************************************************************/
223 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
225 prs_struct ps;
226 fstring key;
227 SEC_DESC *psd = NULL;
229 *psize = 0;
231 /* Fetch security descriptor from tdb */
233 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
235 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
236 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
238 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
240 return get_share_security_default(ctx, snum, psize);
243 if (psd)
244 *psize = sec_desc_size(psd);
246 prs_mem_free(&ps);
247 return psd;
250 /*******************************************************************
251 Store a security descriptor in the share db.
252 ********************************************************************/
254 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
256 prs_struct ps;
257 TALLOC_CTX *mem_ctx = NULL;
258 fstring key;
259 BOOL ret = False;
261 mem_ctx = talloc_init("set_share_security");
262 if (mem_ctx == NULL)
263 return False;
265 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
267 if (!sec_io_desc("share_security", &psd, &ps, 1))
268 goto out;
270 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
272 if (tdb_prs_store(share_tdb, key, &ps)==0) {
273 ret = True;
274 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
275 } else {
276 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
279 /* Free malloc'ed memory */
281 out:
283 prs_mem_free(&ps);
284 if (mem_ctx)
285 talloc_destroy(mem_ctx);
286 return ret;
289 /*******************************************************************
290 Delete a security descriptor.
291 ********************************************************************/
293 static BOOL delete_share_security(int snum)
295 TDB_DATA kbuf;
296 fstring key;
298 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
299 kbuf.dptr = key;
300 kbuf.dsize = strlen(key)+1;
302 if (tdb_delete(share_tdb, kbuf) != 0) {
303 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
304 lp_servicename(snum) ));
305 return False;
308 return True;
311 /*******************************************************************
312 Map any generic bits to file specific bits.
313 ********************************************************************/
315 void map_generic_share_sd_bits(SEC_DESC *psd)
317 int i;
318 SEC_ACL *ps_dacl = NULL;
320 if (!psd)
321 return;
323 ps_dacl = psd->dacl;
324 if (!ps_dacl)
325 return;
327 for (i = 0; i < ps_dacl->num_aces; i++) {
328 SEC_ACE *psa = &ps_dacl->ace[i];
329 uint32 orig_mask = psa->info.mask;
331 se_map_generic(&psa->info.mask, &file_generic_mapping);
332 psa->info.mask |= orig_mask;
336 /*******************************************************************
337 Can this user access with share with the required permissions ?
338 ********************************************************************/
340 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
342 uint32 granted;
343 NTSTATUS status;
344 TALLOC_CTX *mem_ctx = NULL;
345 SEC_DESC *psd = NULL;
346 size_t sd_size;
347 NT_USER_TOKEN *token = NULL;
348 BOOL ret = True;
350 mem_ctx = talloc_init("share_access_check");
351 if (mem_ctx == NULL)
352 return False;
354 psd = get_share_security(mem_ctx, snum, &sd_size);
356 if (!psd)
357 goto out;
359 if (conn->nt_user_token)
360 token = conn->nt_user_token;
361 else
362 token = vuser->nt_user_token;
364 ret = se_access_check(psd, token, desired_access, &granted, &status);
366 out:
368 talloc_destroy(mem_ctx);
370 return ret;
373 /*******************************************************************
374 Fill in a share info level 501 structure.
375 ********************************************************************/
377 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
379 pstring remark;
381 const char *net_name = lp_servicename(snum);
382 pstrcpy(remark, lp_comment(snum));
383 standard_sub_conn(p->conn, remark, sizeof(remark));
385 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
386 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
389 /*******************************************************************
390 Fill in a share info level 502 structure.
391 ********************************************************************/
393 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
395 pstring net_name;
396 pstring remark;
397 pstring path;
398 pstring passwd;
399 SEC_DESC *sd;
400 size_t sd_size;
401 TALLOC_CTX *ctx = p->mem_ctx;
404 ZERO_STRUCTP(sh502);
406 pstrcpy(net_name, lp_servicename(snum));
407 pstrcpy(remark, lp_comment(snum));
408 standard_sub_conn(p->conn, remark,sizeof(remark));
409 pstrcpy(path, "C:");
410 pstrcat(path, lp_pathname(snum));
413 * Change / to \\ so that win2k will see it as a valid path. This was added to
414 * enable use of browsing in win2k add share dialog.
417 string_replace(path, '/', '\\');
419 pstrcpy(passwd, "");
421 sd = get_share_security(ctx, snum, &sd_size);
423 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
424 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
427 /***************************************************************************
428 Fill in a share info level 1004 structure.
429 ***************************************************************************/
431 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
433 pstring remark;
435 pstrcpy(remark, lp_comment(snum));
436 standard_sub_conn(p->conn, remark, sizeof(remark));
438 ZERO_STRUCTP(sh1004);
440 init_srv_share_info1004(&sh1004->info_1004, remark);
441 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
444 /***************************************************************************
445 Fill in a share info level 1005 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
450 sh1005->share_info_flags = 0;
452 if(lp_host_msdfs() && lp_msdfs_root(snum))
453 sh1005->share_info_flags |=
454 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
455 sh1005->share_info_flags |=
456 lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
458 /***************************************************************************
459 Fill in a share info level 1006 structure.
460 ***************************************************************************/
462 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
464 sh1006->max_uses = -1;
467 /***************************************************************************
468 Fill in a share info level 1007 structure.
469 ***************************************************************************/
471 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
473 pstring alternate_directory_name = "";
474 uint32 flags = 0;
476 ZERO_STRUCTP(sh1007);
478 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
479 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
482 /*******************************************************************
483 Fill in a share info level 1501 structure.
484 ********************************************************************/
486 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
488 SEC_DESC *sd;
489 size_t sd_size;
490 TALLOC_CTX *ctx = p->mem_ctx;
492 ZERO_STRUCTP(sh1501);
494 sd = get_share_security(ctx, snum, &sd_size);
496 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
499 /*******************************************************************
500 True if it ends in '$'.
501 ********************************************************************/
503 static BOOL is_hidden_share(int snum)
505 const char *net_name = lp_servicename(snum);
507 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
510 /*******************************************************************
511 Fill in a share info structure.
512 ********************************************************************/
514 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
515 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
517 int num_entries = 0;
518 int num_services = lp_numservices();
519 int snum;
520 TALLOC_CTX *ctx = p->mem_ctx;
522 DEBUG(5,("init_srv_share_info_ctr\n"));
524 ZERO_STRUCTPN(ctr);
526 ctr->info_level = ctr->switch_value = info_level;
527 *resume_hnd = 0;
529 /* Count the number of entries. */
530 for (snum = 0; snum < num_services; snum++) {
531 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
532 num_entries++;
535 *total_entries = num_entries;
536 ctr->num_entries2 = ctr->num_entries = num_entries;
537 ctr->ptr_share_info = ctr->ptr_entries = 1;
539 if (!num_entries)
540 return True;
542 switch (info_level) {
543 case 0:
545 SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
546 int i = 0;
548 if (!info0) {
549 return False;
552 for (snum = *resume_hnd; snum < num_services; snum++) {
553 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
554 init_srv_share_info_0(p, &info0[i++], snum);
558 ctr->share.info0 = info0;
559 break;
563 case 1:
565 SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
566 int i = 0;
568 if (!info1) {
569 return False;
572 for (snum = *resume_hnd; snum < num_services; snum++) {
573 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
574 init_srv_share_info_1(p, &info1[i++], snum);
578 ctr->share.info1 = info1;
579 break;
582 case 2:
584 SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
585 int i = 0;
587 if (!info2) {
588 return False;
591 for (snum = *resume_hnd; snum < num_services; snum++) {
592 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
593 init_srv_share_info_2(p, &info2[i++], snum);
597 ctr->share.info2 = info2;
598 break;
601 case 501:
603 SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
604 int i = 0;
606 if (!info501) {
607 return False;
610 for (snum = *resume_hnd; snum < num_services; snum++) {
611 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
612 init_srv_share_info_501(p, &info501[i++], snum);
616 ctr->share.info501 = info501;
617 break;
620 case 502:
622 SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
623 int i = 0;
625 if (!info502) {
626 return False;
629 for (snum = *resume_hnd; snum < num_services; snum++) {
630 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
631 init_srv_share_info_502(p, &info502[i++], snum);
635 ctr->share.info502 = info502;
636 break;
639 /* here for completeness but not currently used with enum (1004 - 1501)*/
641 case 1004:
643 SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
644 int i = 0;
646 if (!info1004) {
647 return False;
650 for (snum = *resume_hnd; snum < num_services; snum++) {
651 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
652 init_srv_share_info_1004(p, &info1004[i++], snum);
656 ctr->share.info1004 = info1004;
657 break;
660 case 1005:
662 SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
663 int i = 0;
665 if (!info1005) {
666 return False;
669 for (snum = *resume_hnd; snum < num_services; snum++) {
670 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
671 init_srv_share_info_1005(p, &info1005[i++], snum);
675 ctr->share.info1005 = info1005;
676 break;
679 case 1006:
681 SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
682 int i = 0;
684 if (!info1006) {
685 return False;
688 for (snum = *resume_hnd; snum < num_services; snum++) {
689 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
690 init_srv_share_info_1006(p, &info1006[i++], snum);
694 ctr->share.info1006 = info1006;
695 break;
698 case 1007:
700 SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
701 int i = 0;
703 if (!info1007) {
704 return False;
707 for (snum = *resume_hnd; snum < num_services; snum++) {
708 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
709 init_srv_share_info_1007(p, &info1007[i++], snum);
713 ctr->share.info1007 = info1007;
714 break;
717 case 1501:
719 SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
720 int i = 0;
722 if (!info1501) {
723 return False;
726 for (snum = *resume_hnd; snum < num_services; snum++) {
727 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
728 init_srv_share_info_1501(p, &info1501[i++], snum);
732 ctr->share.info1501 = info1501;
733 break;
735 default:
736 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
737 return False;
740 return True;
743 /*******************************************************************
744 Inits a SRV_R_NET_SHARE_ENUM structure.
745 ********************************************************************/
747 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
748 uint32 info_level, uint32 resume_hnd, BOOL all)
750 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
752 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
753 &resume_hnd, &r_n->total_entries, all)) {
754 r_n->status = WERR_OK;
755 } else {
756 r_n->status = WERR_UNKNOWN_LEVEL;
759 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
762 /*******************************************************************
763 Inits a SRV_R_NET_SHARE_GET_INFO structure.
764 ********************************************************************/
766 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
767 char *share_name, uint32 info_level)
769 WERROR status = WERR_OK;
770 int snum;
772 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
774 r_n->info.switch_value = info_level;
776 snum = find_service(share_name);
778 if (snum >= 0) {
779 switch (info_level) {
780 case 0:
781 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
782 break;
783 case 1:
784 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
785 break;
786 case 2:
787 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
788 break;
789 case 501:
790 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
791 break;
792 case 502:
793 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
794 break;
796 /* here for completeness */
797 case 1004:
798 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
799 break;
800 case 1005:
801 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
802 break;
804 /* here for completeness 1006 - 1501 */
805 case 1006:
806 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
807 break;
808 case 1007:
809 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
810 break;
811 case 1501:
812 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
813 break;
814 default:
815 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
816 status = WERR_UNKNOWN_LEVEL;
817 break;
819 } else {
820 status = WERR_INVALID_NAME;
823 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
824 r_n->status = status;
827 /*******************************************************************
828 fill in a sess info level 1 structure.
829 ********************************************************************/
831 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
833 init_srv_sess_info0(se0, name);
834 init_srv_sess_info0_str(str0, name);
837 /*******************************************************************
838 fill in a sess info level 0 structure.
839 ********************************************************************/
841 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
843 struct sessionid *session_list;
844 uint32 num_entries = 0;
845 (*stot) = list_sessions(&session_list);
847 if (ss0 == NULL) {
848 (*snum) = 0;
849 SAFE_FREE(session_list);
850 return;
853 DEBUG(5,("init_srv_sess_0_ss0\n"));
855 if (snum) {
856 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
857 init_srv_sess_0_info(&ss0->info_0[num_entries],
858 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
860 /* move on to creating next session */
861 /* move on to creating next sess */
862 num_entries++;
865 ss0->num_entries_read = num_entries;
866 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
867 ss0->num_entries_read2 = num_entries;
869 if ((*snum) >= (*stot)) {
870 (*snum) = 0;
873 } else {
874 ss0->num_entries_read = 0;
875 ss0->ptr_sess_info = 0;
876 ss0->num_entries_read2 = 0;
878 SAFE_FREE(session_list);
881 /*******************************************************************
882 fill in a sess info level 1 structure.
883 ********************************************************************/
885 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
886 char *name, char *user,
887 uint32 num_opens,
888 uint32 open_time, uint32 idle_time,
889 uint32 usr_flgs)
891 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
892 init_srv_sess_info1_str(str1, name, user);
895 /*******************************************************************
896 fill in a sess info level 1 structure.
897 ********************************************************************/
899 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
901 struct sessionid *session_list;
902 uint32 num_entries = 0;
903 (*stot) = list_sessions(&session_list);
905 if (ss1 == NULL) {
906 (*snum) = 0;
907 SAFE_FREE(session_list);
908 return;
911 DEBUG(5,("init_srv_sess_1_ss1\n"));
913 if (snum) {
914 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
915 init_srv_sess_1_info(&ss1->info_1[num_entries],
916 &ss1->info_1_str[num_entries],
917 session_list[*snum].remote_machine,
918 session_list[*snum].username,
919 1, 10, 5, 0);
921 /* move on to creating next session */
922 /* move on to creating next sess */
923 num_entries++;
926 ss1->num_entries_read = num_entries;
927 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
928 ss1->num_entries_read2 = num_entries;
930 if ((*snum) >= (*stot)) {
931 (*snum) = 0;
934 } else {
935 ss1->num_entries_read = 0;
936 ss1->ptr_sess_info = 0;
937 ss1->num_entries_read2 = 0;
939 (*stot) = 0;
943 /*******************************************************************
944 makes a SRV_R_NET_SESS_ENUM structure.
945 ********************************************************************/
947 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
948 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
950 WERROR status = WERR_OK;
951 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
953 ctr->switch_value = switch_value;
955 switch (switch_value) {
956 case 0:
957 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
958 ctr->ptr_sess_ctr = 1;
959 break;
960 case 1:
961 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
962 ctr->ptr_sess_ctr = 1;
963 break;
964 default:
965 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
966 (*resume_hnd) = 0;
967 (*total_entries) = 0;
968 ctr->ptr_sess_ctr = 0;
969 status = WERR_UNKNOWN_LEVEL;
970 break;
973 return status;
976 /*******************************************************************
977 makes a SRV_R_NET_SESS_ENUM structure.
978 ********************************************************************/
980 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
981 uint32 resume_hnd, int sess_level, int switch_value)
983 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
985 r_n->sess_level = sess_level;
987 if (sess_level == -1)
988 r_n->status = WERR_UNKNOWN_LEVEL;
989 else
990 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
992 if (!W_ERROR_IS_OK(r_n->status))
993 resume_hnd = 0;
995 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
998 /*******************************************************************
999 fill in a conn info level 0 structure.
1000 ********************************************************************/
1002 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
1004 uint32 num_entries = 0;
1005 (*stot) = 1;
1007 if (ss0 == NULL) {
1008 (*snum) = 0;
1009 return;
1012 DEBUG(5,("init_srv_conn_0_ss0\n"));
1014 if (snum) {
1015 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1017 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
1019 /* move on to creating next connection */
1020 /* move on to creating next conn */
1021 num_entries++;
1024 ss0->num_entries_read = num_entries;
1025 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
1026 ss0->num_entries_read2 = num_entries;
1028 if ((*snum) >= (*stot)) {
1029 (*snum) = 0;
1032 } else {
1033 ss0->num_entries_read = 0;
1034 ss0->ptr_conn_info = 0;
1035 ss0->num_entries_read2 = 0;
1037 (*stot) = 0;
1041 /*******************************************************************
1042 fill in a conn info level 1 structure.
1043 ********************************************************************/
1045 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1046 uint32 id, uint32 type,
1047 uint32 num_opens, uint32 num_users, uint32 open_time,
1048 const char *usr_name, const char *net_name)
1050 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1051 init_srv_conn_info1_str(str1, usr_name, net_name);
1054 /*******************************************************************
1055 fill in a conn info level 1 structure.
1056 ********************************************************************/
1058 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1060 uint32 num_entries = 0;
1061 (*stot) = 1;
1063 if (ss1 == NULL) {
1064 (*snum) = 0;
1065 return;
1068 DEBUG(5,("init_srv_conn_1_ss1\n"));
1070 if (snum) {
1071 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1072 init_srv_conn_1_info(&ss1->info_1[num_entries],
1073 &ss1->info_1_str[num_entries],
1074 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1076 /* move on to creating next connection */
1077 /* move on to creating next conn */
1078 num_entries++;
1081 ss1->num_entries_read = num_entries;
1082 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1083 ss1->num_entries_read2 = num_entries;
1086 if ((*snum) >= (*stot)) {
1087 (*snum) = 0;
1090 } else {
1091 ss1->num_entries_read = 0;
1092 ss1->ptr_conn_info = 0;
1093 ss1->num_entries_read2 = 0;
1095 (*stot) = 0;
1099 /*******************************************************************
1100 makes a SRV_R_NET_CONN_ENUM structure.
1101 ********************************************************************/
1103 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1104 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1106 WERROR status = WERR_OK;
1107 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1109 ctr->switch_value = switch_value;
1111 switch (switch_value) {
1112 case 0:
1113 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1114 ctr->ptr_conn_ctr = 1;
1115 break;
1116 case 1:
1117 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1118 ctr->ptr_conn_ctr = 1;
1119 break;
1120 default:
1121 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1122 (*resume_hnd = 0);
1123 (*total_entries) = 0;
1124 ctr->ptr_conn_ctr = 0;
1125 status = WERR_UNKNOWN_LEVEL;
1126 break;
1129 return status;
1132 /*******************************************************************
1133 makes a SRV_R_NET_CONN_ENUM structure.
1134 ********************************************************************/
1136 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1137 uint32 resume_hnd, int conn_level, int switch_value)
1139 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1141 r_n->conn_level = conn_level;
1142 if (conn_level == -1)
1143 r_n->status = WERR_UNKNOWN_LEVEL;
1144 else
1145 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1147 if (!W_ERROR_IS_OK(r_n->status))
1148 resume_hnd = 0;
1150 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1153 /*******************************************************************
1154 makes a SRV_R_NET_FILE_ENUM structure.
1155 ********************************************************************/
1157 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1158 int switch_value, uint32 *resume_hnd,
1159 uint32 *total_entries)
1161 WERROR status = WERR_OK;
1162 TALLOC_CTX *ctx = p->mem_ctx;
1163 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1164 *total_entries = 1; /* dummy entries only, for */
1166 ctr->switch_value = switch_value;
1167 ctr->num_entries = *total_entries - *resume_hnd;
1168 ctr->num_entries2 = ctr->num_entries;
1170 switch (switch_value) {
1171 case 3: {
1172 int i;
1173 if (*total_entries > 0) {
1174 ctr->ptr_entries = 1;
1175 ctr->file.info3 = TALLOC_ARRAY(ctx, SRV_FILE_INFO_3, ctr->num_entries);
1177 for (i=0 ;i<ctr->num_entries;i++) {
1178 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1179 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1182 ctr->ptr_file_info = 1;
1183 *resume_hnd = 0;
1184 break;
1186 default:
1187 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1188 (*resume_hnd = 0);
1189 (*total_entries) = 0;
1190 ctr->ptr_entries = 0;
1191 status = WERR_UNKNOWN_LEVEL;
1192 break;
1195 return status;
1198 /*******************************************************************
1199 makes a SRV_R_NET_FILE_ENUM structure.
1200 ********************************************************************/
1202 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1203 uint32 resume_hnd, int file_level, int switch_value)
1205 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1207 r_n->file_level = file_level;
1208 if (file_level == 0)
1209 r_n->status = WERR_UNKNOWN_LEVEL;
1210 else
1211 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1213 if (!W_ERROR_IS_OK(r_n->status))
1214 resume_hnd = 0;
1216 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1219 /*******************************************************************
1220 net server get info
1221 ********************************************************************/
1223 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)
1225 WERROR status = WERR_OK;
1226 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1228 if (!ctr)
1229 return WERR_NOMEM;
1231 ZERO_STRUCTP(ctr);
1233 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1235 if (!pipe_access_check(p)) {
1236 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1237 return WERR_ACCESS_DENIED;
1240 switch (q_u->switch_value) {
1242 /* Technically level 102 should only be available to
1243 Administrators but there isn't anything super-secret
1244 here, as most of it is made up. */
1246 case 102:
1247 init_srv_info_102(&ctr->srv.sv102,
1248 500, global_myname(),
1249 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1250 lp_major_announce_version(), lp_minor_announce_version(),
1251 lp_default_server_announce(),
1252 0xffffffff, /* users */
1253 0xf, /* disc */
1254 0, /* hidden */
1255 240, /* announce */
1256 3000, /* announce delta */
1257 100000, /* licenses */
1258 "c:\\"); /* user path */
1259 break;
1260 case 101:
1261 init_srv_info_101(&ctr->srv.sv101,
1262 500, global_myname(),
1263 lp_major_announce_version(), lp_minor_announce_version(),
1264 lp_default_server_announce(),
1265 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1266 break;
1267 case 100:
1268 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1269 break;
1270 default:
1271 status = WERR_UNKNOWN_LEVEL;
1272 break;
1275 /* set up the net server get info structure */
1276 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1278 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1280 return r_u->status;
1283 /*******************************************************************
1284 net server set info
1285 ********************************************************************/
1287 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)
1289 WERROR status = WERR_OK;
1291 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1293 /* Set up the net server set info structure. */
1295 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1297 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1299 return r_u->status;
1302 /*******************************************************************
1303 net file enum
1304 ********************************************************************/
1306 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1308 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1310 /* set up the */
1311 init_srv_r_net_file_enum(p, r_u,
1312 get_enum_hnd(&q_u->enum_hnd),
1313 q_u->file_level,
1314 q_u->ctr.switch_value);
1316 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1318 return r_u->status;
1321 /*******************************************************************
1322 net conn enum
1323 ********************************************************************/
1325 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1327 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1329 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1330 if (!r_u->ctr)
1331 return WERR_NOMEM;
1333 ZERO_STRUCTP(r_u->ctr);
1335 /* set up the */
1336 init_srv_r_net_conn_enum(r_u,
1337 get_enum_hnd(&q_u->enum_hnd),
1338 q_u->conn_level,
1339 q_u->ctr->switch_value);
1341 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1343 return r_u->status;
1346 /*******************************************************************
1347 net sess enum
1348 ********************************************************************/
1350 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1352 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1354 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1355 if (!r_u->ctr)
1356 return WERR_NOMEM;
1358 ZERO_STRUCTP(r_u->ctr);
1360 /* set up the */
1361 init_srv_r_net_sess_enum(r_u,
1362 get_enum_hnd(&q_u->enum_hnd),
1363 q_u->sess_level,
1364 q_u->ctr->switch_value);
1366 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1368 return r_u->status;
1371 /*******************************************************************
1372 net sess del
1373 ********************************************************************/
1375 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1377 struct sessionid *session_list;
1378 struct current_user user;
1379 int num_sessions, snum;
1380 fstring username;
1381 fstring machine;
1382 BOOL not_root = False;
1384 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1385 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1387 /* strip leading backslashes if any */
1388 while (machine[0] == '\\') {
1389 memmove(machine, &machine[1], strlen(machine));
1392 num_sessions = list_sessions(&session_list);
1394 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1396 r_u->status = WERR_ACCESS_DENIED;
1398 get_current_user(&user, p);
1400 /* fail out now if you are not root or not a domain admin */
1402 if ((user.uid != sec_initial_uid()) &&
1403 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1405 goto done;
1408 for (snum = 0; snum < num_sessions; snum++) {
1410 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1411 strequal(session_list[snum].remote_machine, machine)) {
1413 if (user.uid != sec_initial_uid()) {
1414 not_root = True;
1415 become_root();
1418 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1419 r_u->status = WERR_OK;
1421 if (not_root)
1422 unbecome_root();
1426 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1429 done:
1430 SAFE_FREE(session_list);
1432 return r_u->status;
1435 /*******************************************************************
1436 Net share enum all.
1437 ********************************************************************/
1439 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1441 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1443 if (!pipe_access_check(p)) {
1444 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1445 return WERR_ACCESS_DENIED;
1448 /* Create the list of shares for the response. */
1449 init_srv_r_net_share_enum(p, r_u,
1450 q_u->ctr.info_level,
1451 get_enum_hnd(&q_u->enum_hnd), True);
1453 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1455 return r_u->status;
1458 /*******************************************************************
1459 Net share enum.
1460 ********************************************************************/
1462 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1464 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1466 if (!pipe_access_check(p)) {
1467 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1468 return WERR_ACCESS_DENIED;
1471 /* Create the list of shares for the response. */
1472 init_srv_r_net_share_enum(p, r_u,
1473 q_u->ctr.info_level,
1474 get_enum_hnd(&q_u->enum_hnd), False);
1476 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1478 return r_u->status;
1481 /*******************************************************************
1482 Net share get info.
1483 ********************************************************************/
1485 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)
1487 fstring share_name;
1489 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1491 /* Create the list of shares for the response. */
1492 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1493 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1495 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1497 return r_u->status;
1500 /*******************************************************************
1501 Check a given DOS pathname is valid for a share.
1502 ********************************************************************/
1504 char *valid_share_pathname(char *dos_pathname)
1506 char *ptr;
1508 /* Convert any '\' paths to '/' */
1509 unix_format(dos_pathname);
1510 unix_clean_name(dos_pathname);
1512 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1513 ptr = dos_pathname;
1514 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1515 ptr += 2;
1517 /* Only absolute paths allowed. */
1518 if (*ptr != '/')
1519 return NULL;
1521 return ptr;
1524 /*******************************************************************
1525 Net share set info. Modify share details.
1526 ********************************************************************/
1528 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)
1530 struct current_user user;
1531 pstring command;
1532 fstring share_name;
1533 fstring comment;
1534 pstring pathname;
1535 int type;
1536 int snum;
1537 int ret;
1538 char *path;
1539 SEC_DESC *psd = NULL;
1540 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1541 BOOL is_disk_op = False;
1542 int max_connections = 0;
1544 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1546 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1548 r_u->parm_error = 0;
1550 if ( strequal(share_name,"IPC$")
1551 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1552 || strequal(share_name,"global") )
1554 return WERR_ACCESS_DENIED;
1557 snum = find_service(share_name);
1559 /* Does this share exist ? */
1560 if (snum < 0)
1561 return WERR_NET_NAME_NOT_FOUND;
1563 /* No change to printer shares. */
1564 if (lp_print_ok(snum))
1565 return WERR_ACCESS_DENIED;
1567 get_current_user(&user,p);
1569 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1571 /* fail out now if you are not root and not a disk op */
1573 if ( user.uid != sec_initial_uid() && !is_disk_op )
1574 return WERR_ACCESS_DENIED;
1576 switch (q_u->info_level) {
1577 case 1:
1578 pstrcpy(pathname, lp_pathname(snum));
1579 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1580 type = q_u->info.share.info2.info_2.type;
1581 psd = NULL;
1582 break;
1583 case 2:
1584 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1585 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1586 type = q_u->info.share.info2.info_2.type;
1587 max_connections = (q_u->info.share.info2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.max_uses;
1588 psd = NULL;
1589 break;
1590 #if 0
1591 /* not supported on set but here for completeness */
1592 case 501:
1593 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1594 type = q_u->info.share.info501.info_501.type;
1595 psd = NULL;
1596 break;
1597 #endif
1598 case 502:
1599 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1600 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1601 type = q_u->info.share.info502.info_502.type;
1602 psd = q_u->info.share.info502.info_502_str.sd;
1603 map_generic_share_sd_bits(psd);
1604 break;
1605 case 1004:
1606 pstrcpy(pathname, lp_pathname(snum));
1607 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1608 type = STYPE_DISKTREE;
1609 break;
1610 case 1005:
1611 /* XP re-sets the csc policy even if it wasn't changed by the
1612 user, so we must compare it to see if it's what is set in
1613 smb.conf, so that we can contine other ops like setting
1614 ACLs on a share */
1615 if (((q_u->info.share.info1005.share_info_flags &
1616 SHARE_1005_CSC_POLICY_MASK) >>
1617 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1618 return WERR_OK;
1619 else {
1620 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1621 return WERR_ACCESS_DENIED;
1623 case 1006:
1624 case 1007:
1625 return WERR_ACCESS_DENIED;
1626 case 1501:
1627 pstrcpy(pathname, lp_pathname(snum));
1628 fstrcpy(comment, lp_comment(snum));
1629 psd = q_u->info.share.info1501.sdb->sec;
1630 map_generic_share_sd_bits(psd);
1631 type = STYPE_DISKTREE;
1632 break;
1633 default:
1634 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1635 return WERR_UNKNOWN_LEVEL;
1638 /* We can only modify disk shares. */
1639 if (type != STYPE_DISKTREE)
1640 return WERR_ACCESS_DENIED;
1642 /* Check if the pathname is valid. */
1643 if (!(path = valid_share_pathname( pathname )))
1644 return WERR_OBJECT_PATH_INVALID;
1646 /* Ensure share name, pathname and comment don't contain '"' characters. */
1647 string_replace(share_name, '"', ' ');
1648 string_replace(path, '"', ' ');
1649 string_replace(comment, '"', ' ');
1651 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1652 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1654 /* Only call modify function if something changed. */
1656 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) )
1658 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1659 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1660 return WERR_ACCESS_DENIED;
1663 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1664 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1666 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1668 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1670 if ( is_disk_op )
1671 become_root();
1673 if ( (ret = smbrun(command, NULL)) == 0 ) {
1674 /* Tell everyone we updated smb.conf. */
1675 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1678 if ( is_disk_op )
1679 unbecome_root();
1681 /********* END SeDiskOperatorPrivilege BLOCK *********/
1683 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1685 if ( ret != 0 )
1686 return WERR_ACCESS_DENIED;
1687 } else {
1688 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1691 /* Replace SD if changed. */
1692 if (psd) {
1693 SEC_DESC *old_sd;
1694 size_t sd_size;
1696 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1698 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1699 if (!set_share_security(p->mem_ctx, share_name, psd))
1700 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1701 share_name ));
1705 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1707 return WERR_OK;
1710 /*******************************************************************
1711 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1712 ********************************************************************/
1714 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1716 struct current_user user;
1717 pstring command;
1718 fstring share_name;
1719 fstring comment;
1720 pstring pathname;
1721 int type;
1722 int snum;
1723 int ret;
1724 char *path;
1725 SEC_DESC *psd = NULL;
1726 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1727 BOOL is_disk_op;
1729 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1731 r_u->parm_error = 0;
1733 get_current_user(&user,p);
1735 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1737 if (user.uid != sec_initial_uid() && !is_disk_op )
1738 return WERR_ACCESS_DENIED;
1740 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1741 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1742 return WERR_ACCESS_DENIED;
1745 switch (q_u->info_level) {
1746 case 0:
1747 /* No path. Not enough info in a level 0 to do anything. */
1748 return WERR_ACCESS_DENIED;
1749 case 1:
1750 /* Not enough info in a level 1 to do anything. */
1751 return WERR_ACCESS_DENIED;
1752 case 2:
1753 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1754 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1755 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1756 type = q_u->info.share.info2.info_2.type;
1757 break;
1758 case 501:
1759 /* No path. Not enough info in a level 501 to do anything. */
1760 return WERR_ACCESS_DENIED;
1761 case 502:
1762 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1763 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1764 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1765 type = q_u->info.share.info502.info_502.type;
1766 psd = q_u->info.share.info502.info_502_str.sd;
1767 map_generic_share_sd_bits(psd);
1768 break;
1770 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1772 case 1004:
1773 case 1005:
1774 case 1006:
1775 case 1007:
1776 return WERR_ACCESS_DENIED;
1777 case 1501:
1778 /* DFS only level. */
1779 return WERR_ACCESS_DENIED;
1780 default:
1781 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1782 return WERR_UNKNOWN_LEVEL;
1785 /* check for invalid share names */
1787 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1788 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1789 return WERR_INVALID_NAME;
1792 if ( strequal(share_name,"IPC$")
1793 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1794 || strequal(share_name,"global") )
1796 return WERR_ACCESS_DENIED;
1799 snum = find_service(share_name);
1801 /* Share already exists. */
1802 if (snum >= 0)
1803 return WERR_ALREADY_EXISTS;
1805 /* We can only add disk shares. */
1806 if (type != STYPE_DISKTREE)
1807 return WERR_ACCESS_DENIED;
1809 /* Check if the pathname is valid. */
1810 if (!(path = valid_share_pathname( pathname )))
1811 return WERR_OBJECT_PATH_INVALID;
1813 /* Ensure share name, pathname and comment don't contain '"' characters. */
1814 string_replace(share_name, '"', ' ');
1815 string_replace(path, '"', ' ');
1816 string_replace(comment, '"', ' ');
1818 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1819 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1821 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1823 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1825 if ( is_disk_op )
1826 become_root();
1828 if ( (ret = smbrun(command, NULL)) == 0 ) {
1829 /* Tell everyone we updated smb.conf. */
1830 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1833 if ( is_disk_op )
1834 unbecome_root();
1836 /********* END SeDiskOperatorPrivilege BLOCK *********/
1838 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1840 if ( ret != 0 )
1841 return WERR_ACCESS_DENIED;
1843 if (psd) {
1844 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1845 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1850 * We don't call reload_services() here, the message will
1851 * cause this to be done before the next packet is read
1852 * from the client. JRA.
1855 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1857 return WERR_OK;
1860 /*******************************************************************
1861 Net share delete. Call "delete share command" with the share name as
1862 a parameter.
1863 ********************************************************************/
1865 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1867 struct current_user user;
1868 pstring command;
1869 fstring share_name;
1870 int ret;
1871 int snum;
1872 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1873 BOOL is_disk_op;
1875 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1877 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1879 if ( strequal(share_name,"IPC$")
1880 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1881 || strequal(share_name,"global") )
1883 return WERR_ACCESS_DENIED;
1886 snum = find_service(share_name);
1888 if (snum < 0)
1889 return WERR_NO_SUCH_SHARE;
1891 /* No change to printer shares. */
1892 if (lp_print_ok(snum))
1893 return WERR_ACCESS_DENIED;
1895 get_current_user(&user,p);
1897 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1899 if (user.uid != sec_initial_uid() && !is_disk_op )
1900 return WERR_ACCESS_DENIED;
1902 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1903 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1904 return WERR_ACCESS_DENIED;
1907 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1908 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1910 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1912 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1914 if ( is_disk_op )
1915 become_root();
1917 if ( (ret = smbrun(command, NULL)) == 0 ) {
1918 /* Tell everyone we updated smb.conf. */
1919 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1922 if ( is_disk_op )
1923 unbecome_root();
1925 /********* END SeDiskOperatorPrivilege BLOCK *********/
1927 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1929 if ( ret != 0 )
1930 return WERR_ACCESS_DENIED;
1932 /* Delete the SD in the database. */
1933 delete_share_security(snum);
1935 lp_killservice(snum);
1937 return WERR_OK;
1940 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1942 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1944 return _srv_net_share_del(p, q_u, r_u);
1947 /*******************************************************************
1948 time of day
1949 ********************************************************************/
1951 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1953 TIME_OF_DAY_INFO *tod;
1954 struct tm *t;
1955 time_t unixdate = time(NULL);
1957 /* We do this call first as if we do it *after* the gmtime call
1958 it overwrites the pointed-to values. JRA */
1960 uint32 zone = get_time_zone(unixdate)/60;
1962 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1964 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1965 return WERR_NOMEM;
1967 r_u->tod = tod;
1968 r_u->ptr_srv_tod = 0x1;
1969 r_u->status = WERR_OK;
1971 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1973 t = gmtime(&unixdate);
1975 /* set up the */
1976 init_time_of_day_info(tod,
1977 unixdate,
1979 t->tm_hour,
1980 t->tm_min,
1981 t->tm_sec,
1983 zone,
1984 10000,
1985 t->tm_mday,
1986 t->tm_mon + 1,
1987 1900+t->tm_year,
1988 t->tm_wday);
1990 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1992 return r_u->status;
1995 /***********************************************************************************
1996 Win9x NT tools get security descriptor.
1997 ***********************************************************************************/
1999 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
2000 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
2002 SEC_DESC *psd = NULL;
2003 size_t sd_size;
2004 DATA_BLOB null_pw;
2005 pstring filename;
2006 pstring qualname;
2007 files_struct *fsp = NULL;
2008 SMB_STRUCT_STAT st;
2009 BOOL bad_path;
2010 NTSTATUS nt_status;
2011 struct current_user user;
2012 connection_struct *conn = NULL;
2013 BOOL became_user = False;
2015 ZERO_STRUCT(st);
2017 r_u->status = WERR_OK;
2019 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2021 /* Null password is ok - we are already an authenticated user... */
2022 null_pw = data_blob(NULL, 0);
2024 get_current_user(&user, p);
2026 become_root();
2027 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2028 unbecome_root();
2030 if (conn == NULL) {
2031 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
2032 r_u->status = ntstatus_to_werror(nt_status);
2033 goto error_exit;
2036 if (!become_user(conn, conn->vuid)) {
2037 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2038 r_u->status = WERR_ACCESS_DENIED;
2039 goto error_exit;
2041 became_user = True;
2043 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2044 unix_convert(filename, conn, NULL, &bad_path, &st);
2045 if (bad_path) {
2046 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2047 r_u->status = WERR_ACCESS_DENIED;
2048 goto error_exit;
2051 if (!check_name(filename,conn)) {
2052 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2053 r_u->status = WERR_ACCESS_DENIED;
2054 goto error_exit;
2057 fsp = open_file_stat(conn, filename, &st);
2058 if (!fsp) {
2059 /* Perhaps it is a directory */
2060 if (errno == EISDIR)
2061 fsp = open_directory(conn, filename, &st,
2062 READ_CONTROL_ACCESS,
2063 FILE_SHARE_READ|FILE_SHARE_WRITE,
2064 FILE_OPEN,
2066 NULL);
2068 if (!fsp) {
2069 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2070 r_u->status = WERR_ACCESS_DENIED;
2071 goto error_exit;
2075 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2077 if (sd_size == 0) {
2078 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2079 r_u->status = WERR_ACCESS_DENIED;
2080 goto error_exit;
2083 r_u->ptr_response = 1;
2084 r_u->size_response = sd_size;
2085 r_u->ptr_secdesc = 1;
2086 r_u->size_secdesc = sd_size;
2087 r_u->sec_desc = psd;
2089 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2091 close_file(fsp, True);
2092 unbecome_user();
2093 close_cnum(conn, user.vuid);
2094 return r_u->status;
2096 error_exit:
2098 if(fsp) {
2099 close_file(fsp, True);
2102 if (became_user)
2103 unbecome_user();
2105 if (conn)
2106 close_cnum(conn, user.vuid);
2108 return r_u->status;
2111 /***********************************************************************************
2112 Win9x NT tools set security descriptor.
2113 ***********************************************************************************/
2115 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2116 SRV_R_NET_FILE_SET_SECDESC *r_u)
2118 BOOL ret;
2119 pstring filename;
2120 pstring qualname;
2121 DATA_BLOB null_pw;
2122 files_struct *fsp = NULL;
2123 SMB_STRUCT_STAT st;
2124 BOOL bad_path;
2125 NTSTATUS nt_status;
2126 struct current_user user;
2127 connection_struct *conn = NULL;
2128 BOOL became_user = False;
2130 ZERO_STRUCT(st);
2132 r_u->status = WERR_OK;
2134 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2136 /* Null password is ok - we are already an authenticated user... */
2137 null_pw = data_blob(NULL, 0);
2139 get_current_user(&user, p);
2141 become_root();
2142 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2143 unbecome_root();
2145 if (conn == NULL) {
2146 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2147 r_u->status = ntstatus_to_werror(nt_status);
2148 goto error_exit;
2151 if (!become_user(conn, conn->vuid)) {
2152 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2153 r_u->status = WERR_ACCESS_DENIED;
2154 goto error_exit;
2156 became_user = True;
2158 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2159 unix_convert(filename, conn, NULL, &bad_path, &st);
2160 if (bad_path) {
2161 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2162 r_u->status = WERR_ACCESS_DENIED;
2163 goto error_exit;
2166 if (!check_name(filename,conn)) {
2167 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2168 r_u->status = WERR_ACCESS_DENIED;
2169 goto error_exit;
2173 fsp = open_file_stat(conn, filename, &st);
2175 if (!fsp) {
2176 /* Perhaps it is a directory */
2177 if (errno == EISDIR)
2178 fsp = open_directory(conn, filename, &st,
2179 FILE_READ_ATTRIBUTES,
2180 FILE_SHARE_READ|FILE_SHARE_WRITE,
2181 FILE_OPEN,
2183 NULL);
2185 if (!fsp) {
2186 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2187 r_u->status = WERR_ACCESS_DENIED;
2188 goto error_exit;
2192 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2194 if (ret == False) {
2195 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2196 r_u->status = WERR_ACCESS_DENIED;
2197 goto error_exit;
2200 close_file(fsp, True);
2201 unbecome_user();
2202 close_cnum(conn, user.vuid);
2203 return r_u->status;
2205 error_exit:
2207 if(fsp) {
2208 close_file(fsp, True);
2211 if (became_user) {
2212 unbecome_user();
2215 if (conn) {
2216 close_cnum(conn, user.vuid);
2219 return r_u->status;
2222 /***********************************************************************************
2223 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2224 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2225 These disks would the disks listed by this function.
2226 Users could then create shares relative to these disks. Watch out for moving these disks around.
2227 "Nigel Williams" <nigel@veritas.com>.
2228 ***********************************************************************************/
2230 static const char *server_disks[] = {"C:"};
2232 static uint32 get_server_disk_count(void)
2234 return sizeof(server_disks)/sizeof(server_disks[0]);
2237 static uint32 init_server_disk_enum(uint32 *resume)
2239 uint32 server_disk_count = get_server_disk_count();
2241 /*resume can be an offset into the list for now*/
2243 if(*resume & 0x80000000)
2244 *resume = 0;
2246 if(*resume > server_disk_count)
2247 *resume = server_disk_count;
2249 return server_disk_count - *resume;
2252 static const char *next_server_disk_enum(uint32 *resume)
2254 const char *disk;
2256 if(init_server_disk_enum(resume) == 0)
2257 return NULL;
2259 disk = server_disks[*resume];
2261 (*resume)++;
2263 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2265 return disk;
2268 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2270 uint32 i;
2271 const char *disk_name;
2272 TALLOC_CTX *ctx = p->mem_ctx;
2273 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2275 r_u->status=WERR_OK;
2277 r_u->total_entries = init_server_disk_enum(&resume);
2279 r_u->disk_enum_ctr.unknown = 0;
2281 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2282 return WERR_NOMEM;
2285 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2287 /*allow one DISK_INFO for null terminator*/
2289 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2291 r_u->disk_enum_ctr.entries_read++;
2293 /*copy disk name into a unicode string*/
2295 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2298 /* add a terminating null string. Is this there if there is more data to come? */
2300 r_u->disk_enum_ctr.entries_read++;
2302 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2304 init_enum_hnd(&r_u->enum_hnd, resume);
2306 return r_u->status;
2309 /********************************************************************
2310 ********************************************************************/
2312 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2314 fstring sharename;
2316 switch ( q_u->type ) {
2317 case 0x9:
2318 rpcstr_pull(sharename, q_u->uni_name.buffer, sizeof(sharename), q_u->uni_name.uni_str_len*2, 0);
2319 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2320 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2321 return WERR_INVALID_NAME;
2323 break;
2325 default:
2326 return WERR_UNKNOWN_LEVEL;
2329 return WERR_OK;