r13082: revert an accidentally commited patch (still in progress)
[Samba/nascimento.git] / source3 / rpc_server / srv_srvsvc_nt.c
blob230f0626628e4e45fa3647ee86820510ca59f45d
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;
1543 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1545 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1547 r_u->parm_error = 0;
1549 if ( strequal(share_name,"IPC$")
1550 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1551 || strequal(share_name,"global") )
1553 return WERR_ACCESS_DENIED;
1556 snum = find_service(share_name);
1558 /* Does this share exist ? */
1559 if (snum < 0)
1560 return WERR_NET_NAME_NOT_FOUND;
1562 /* No change to printer shares. */
1563 if (lp_print_ok(snum))
1564 return WERR_ACCESS_DENIED;
1566 get_current_user(&user,p);
1568 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1570 /* fail out now if you are not root and not a disk op */
1572 if ( user.uid != sec_initial_uid() && !is_disk_op )
1573 return WERR_ACCESS_DENIED;
1575 switch (q_u->info_level) {
1576 case 1:
1577 pstrcpy(pathname, lp_pathname(snum));
1578 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1579 type = q_u->info.share.info2.info_2.type;
1580 psd = NULL;
1581 break;
1582 case 2:
1583 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1584 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1585 type = q_u->info.share.info2.info_2.type;
1586 psd = NULL;
1587 break;
1588 #if 0
1589 /* not supported on set but here for completeness */
1590 case 501:
1591 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1592 type = q_u->info.share.info501.info_501.type;
1593 psd = NULL;
1594 break;
1595 #endif
1596 case 502:
1597 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1598 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1599 type = q_u->info.share.info502.info_502.type;
1600 psd = q_u->info.share.info502.info_502_str.sd;
1601 map_generic_share_sd_bits(psd);
1602 break;
1603 case 1004:
1604 pstrcpy(pathname, lp_pathname(snum));
1605 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1606 type = STYPE_DISKTREE;
1607 break;
1608 case 1005:
1609 /* XP re-sets the csc policy even if it wasn't changed by the
1610 user, so we must compare it to see if it's what is set in
1611 smb.conf, so that we can contine other ops like setting
1612 ACLs on a share */
1613 if (((q_u->info.share.info1005.share_info_flags &
1614 SHARE_1005_CSC_POLICY_MASK) >>
1615 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1616 return WERR_OK;
1617 else {
1618 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1619 return WERR_ACCESS_DENIED;
1621 case 1006:
1622 case 1007:
1623 return WERR_ACCESS_DENIED;
1624 case 1501:
1625 pstrcpy(pathname, lp_pathname(snum));
1626 fstrcpy(comment, lp_comment(snum));
1627 psd = q_u->info.share.info1501.sdb->sec;
1628 map_generic_share_sd_bits(psd);
1629 type = STYPE_DISKTREE;
1630 break;
1631 default:
1632 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1633 return WERR_UNKNOWN_LEVEL;
1636 /* We can only modify disk shares. */
1637 if (type != STYPE_DISKTREE)
1638 return WERR_ACCESS_DENIED;
1640 /* Check if the pathname is valid. */
1641 if (!(path = valid_share_pathname( pathname )))
1642 return WERR_OBJECT_PATH_INVALID;
1644 /* Ensure share name, pathname and comment don't contain '"' characters. */
1645 string_replace(share_name, '"', ' ');
1646 string_replace(path, '"', ' ');
1647 string_replace(comment, '"', ' ');
1649 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1650 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1652 /* Only call modify function if something changed. */
1654 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) )
1656 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1657 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1658 return WERR_ACCESS_DENIED;
1661 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1662 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1664 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1666 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1668 if ( is_disk_op )
1669 become_root();
1671 if ( (ret = smbrun(command, NULL)) == 0 ) {
1672 /* Tell everyone we updated smb.conf. */
1673 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1676 if ( is_disk_op )
1677 unbecome_root();
1679 /********* END SeDiskOperatorPrivilege BLOCK *********/
1681 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1683 if ( ret != 0 )
1684 return WERR_ACCESS_DENIED;
1685 } else {
1686 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1689 /* Replace SD if changed. */
1690 if (psd) {
1691 SEC_DESC *old_sd;
1692 size_t sd_size;
1694 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1696 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1697 if (!set_share_security(p->mem_ctx, share_name, psd))
1698 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1699 share_name ));
1703 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1705 return WERR_OK;
1708 /*******************************************************************
1709 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1710 ********************************************************************/
1712 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1714 struct current_user user;
1715 pstring command;
1716 fstring share_name;
1717 fstring comment;
1718 pstring pathname;
1719 int type;
1720 int snum;
1721 int ret;
1722 char *path;
1723 SEC_DESC *psd = NULL;
1724 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1725 BOOL is_disk_op;
1727 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1729 r_u->parm_error = 0;
1731 get_current_user(&user,p);
1733 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1735 if (user.uid != sec_initial_uid() && !is_disk_op )
1736 return WERR_ACCESS_DENIED;
1738 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1739 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1740 return WERR_ACCESS_DENIED;
1743 switch (q_u->info_level) {
1744 case 0:
1745 /* No path. Not enough info in a level 0 to do anything. */
1746 return WERR_ACCESS_DENIED;
1747 case 1:
1748 /* Not enough info in a level 1 to do anything. */
1749 return WERR_ACCESS_DENIED;
1750 case 2:
1751 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1752 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1753 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1754 type = q_u->info.share.info2.info_2.type;
1755 break;
1756 case 501:
1757 /* No path. Not enough info in a level 501 to do anything. */
1758 return WERR_ACCESS_DENIED;
1759 case 502:
1760 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1761 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1762 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1763 type = q_u->info.share.info502.info_502.type;
1764 psd = q_u->info.share.info502.info_502_str.sd;
1765 map_generic_share_sd_bits(psd);
1766 break;
1768 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1770 case 1004:
1771 case 1005:
1772 case 1006:
1773 case 1007:
1774 return WERR_ACCESS_DENIED;
1775 case 1501:
1776 /* DFS only level. */
1777 return WERR_ACCESS_DENIED;
1778 default:
1779 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1780 return WERR_UNKNOWN_LEVEL;
1783 /* check for invalid share names */
1785 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1786 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1787 return WERR_INVALID_NAME;
1790 if ( strequal(share_name,"IPC$")
1791 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1792 || strequal(share_name,"global") )
1794 return WERR_ACCESS_DENIED;
1797 snum = find_service(share_name);
1799 /* Share already exists. */
1800 if (snum >= 0)
1801 return WERR_ALREADY_EXISTS;
1803 /* We can only add disk shares. */
1804 if (type != STYPE_DISKTREE)
1805 return WERR_ACCESS_DENIED;
1807 /* Check if the pathname is valid. */
1808 if (!(path = valid_share_pathname( pathname )))
1809 return WERR_OBJECT_PATH_INVALID;
1811 /* Ensure share name, pathname and comment don't contain '"' characters. */
1812 string_replace(share_name, '"', ' ');
1813 string_replace(path, '"', ' ');
1814 string_replace(comment, '"', ' ');
1816 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1817 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1819 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1821 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1823 if ( is_disk_op )
1824 become_root();
1826 if ( (ret = smbrun(command, NULL)) == 0 ) {
1827 /* Tell everyone we updated smb.conf. */
1828 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1831 if ( is_disk_op )
1832 unbecome_root();
1834 /********* END SeDiskOperatorPrivilege BLOCK *********/
1836 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1838 if ( ret != 0 )
1839 return WERR_ACCESS_DENIED;
1841 if (psd) {
1842 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1843 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1848 * We don't call reload_services() here, the message will
1849 * cause this to be done before the next packet is read
1850 * from the client. JRA.
1853 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1855 return WERR_OK;
1858 /*******************************************************************
1859 Net share delete. Call "delete share command" with the share name as
1860 a parameter.
1861 ********************************************************************/
1863 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1865 struct current_user user;
1866 pstring command;
1867 fstring share_name;
1868 int ret;
1869 int snum;
1870 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1871 BOOL is_disk_op;
1873 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1875 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1877 if ( strequal(share_name,"IPC$")
1878 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1879 || strequal(share_name,"global") )
1881 return WERR_ACCESS_DENIED;
1884 snum = find_service(share_name);
1886 if (snum < 0)
1887 return WERR_NO_SUCH_SHARE;
1889 /* No change to printer shares. */
1890 if (lp_print_ok(snum))
1891 return WERR_ACCESS_DENIED;
1893 get_current_user(&user,p);
1895 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1897 if (user.uid != sec_initial_uid() && !is_disk_op )
1898 return WERR_ACCESS_DENIED;
1900 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1901 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1902 return WERR_ACCESS_DENIED;
1905 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1906 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1908 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1910 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1912 if ( is_disk_op )
1913 become_root();
1915 if ( (ret = smbrun(command, NULL)) == 0 ) {
1916 /* Tell everyone we updated smb.conf. */
1917 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1920 if ( is_disk_op )
1921 unbecome_root();
1923 /********* END SeDiskOperatorPrivilege BLOCK *********/
1925 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1927 if ( ret != 0 )
1928 return WERR_ACCESS_DENIED;
1930 /* Delete the SD in the database. */
1931 delete_share_security(snum);
1933 lp_killservice(snum);
1935 return WERR_OK;
1938 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1940 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1942 return _srv_net_share_del(p, q_u, r_u);
1945 /*******************************************************************
1946 time of day
1947 ********************************************************************/
1949 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1951 TIME_OF_DAY_INFO *tod;
1952 struct tm *t;
1953 time_t unixdate = time(NULL);
1954 /* We do this call first as if we do it *after* the gmtime call
1955 it overwrites the pointed-to values. JRA */
1956 uint32 zone = get_time_zone(unixdate)/60;
1958 tod = TALLOC_P(p->mem_ctx, TIME_OF_DAY_INFO);
1959 if (!tod)
1960 return WERR_NOMEM;
1962 ZERO_STRUCTP(tod);
1964 r_u->tod = tod;
1965 r_u->ptr_srv_tod = 0x1;
1966 r_u->status = WERR_OK;
1968 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1970 t = gmtime(&unixdate);
1972 /* set up the */
1973 init_time_of_day_info(tod,
1974 unixdate,
1976 t->tm_hour,
1977 t->tm_min,
1978 t->tm_sec,
1980 zone,
1981 10000,
1982 t->tm_mday,
1983 t->tm_mon + 1,
1984 1900+t->tm_year,
1985 t->tm_wday);
1987 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1989 return r_u->status;
1992 /***********************************************************************************
1993 Win9x NT tools get security descriptor.
1994 ***********************************************************************************/
1996 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1997 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1999 SEC_DESC *psd = NULL;
2000 size_t sd_size;
2001 DATA_BLOB null_pw;
2002 pstring filename;
2003 pstring qualname;
2004 files_struct *fsp = NULL;
2005 SMB_STRUCT_STAT st;
2006 BOOL bad_path;
2007 NTSTATUS nt_status;
2008 struct current_user user;
2009 connection_struct *conn = NULL;
2010 BOOL became_user = False;
2012 ZERO_STRUCT(st);
2014 r_u->status = WERR_OK;
2016 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2018 /* Null password is ok - we are already an authenticated user... */
2019 null_pw = data_blob(NULL, 0);
2021 get_current_user(&user, p);
2023 become_root();
2024 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2025 unbecome_root();
2027 if (conn == NULL) {
2028 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
2029 r_u->status = ntstatus_to_werror(nt_status);
2030 goto error_exit;
2033 if (!become_user(conn, conn->vuid)) {
2034 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2035 r_u->status = WERR_ACCESS_DENIED;
2036 goto error_exit;
2038 became_user = True;
2040 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2041 unix_convert(filename, conn, NULL, &bad_path, &st);
2042 if (bad_path) {
2043 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2044 r_u->status = WERR_ACCESS_DENIED;
2045 goto error_exit;
2048 if (!check_name(filename,conn)) {
2049 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2050 r_u->status = WERR_ACCESS_DENIED;
2051 goto error_exit;
2054 fsp = open_file_stat(conn, filename, &st);
2055 if (!fsp) {
2056 /* Perhaps it is a directory */
2057 if (errno == EISDIR)
2058 fsp = open_directory(conn, filename, &st,
2059 READ_CONTROL_ACCESS,
2060 FILE_SHARE_READ|FILE_SHARE_WRITE,
2061 FILE_OPEN,
2063 NULL);
2065 if (!fsp) {
2066 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2067 r_u->status = WERR_ACCESS_DENIED;
2068 goto error_exit;
2072 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2074 if (sd_size == 0) {
2075 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2076 r_u->status = WERR_ACCESS_DENIED;
2077 goto error_exit;
2080 r_u->ptr_response = 1;
2081 r_u->size_response = sd_size;
2082 r_u->ptr_secdesc = 1;
2083 r_u->size_secdesc = sd_size;
2084 r_u->sec_desc = psd;
2086 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2088 close_file(fsp, True);
2089 unbecome_user();
2090 close_cnum(conn, user.vuid);
2091 return r_u->status;
2093 error_exit:
2095 if(fsp) {
2096 close_file(fsp, True);
2099 if (became_user)
2100 unbecome_user();
2102 if (conn)
2103 close_cnum(conn, user.vuid);
2105 return r_u->status;
2108 /***********************************************************************************
2109 Win9x NT tools set security descriptor.
2110 ***********************************************************************************/
2112 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2113 SRV_R_NET_FILE_SET_SECDESC *r_u)
2115 BOOL ret;
2116 pstring filename;
2117 pstring qualname;
2118 DATA_BLOB null_pw;
2119 files_struct *fsp = NULL;
2120 SMB_STRUCT_STAT st;
2121 BOOL bad_path;
2122 NTSTATUS nt_status;
2123 struct current_user user;
2124 connection_struct *conn = NULL;
2125 BOOL became_user = False;
2127 ZERO_STRUCT(st);
2129 r_u->status = WERR_OK;
2131 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2133 /* Null password is ok - we are already an authenticated user... */
2134 null_pw = data_blob(NULL, 0);
2136 get_current_user(&user, p);
2138 become_root();
2139 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2140 unbecome_root();
2142 if (conn == NULL) {
2143 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2144 r_u->status = ntstatus_to_werror(nt_status);
2145 goto error_exit;
2148 if (!become_user(conn, conn->vuid)) {
2149 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2150 r_u->status = WERR_ACCESS_DENIED;
2151 goto error_exit;
2153 became_user = True;
2155 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2156 unix_convert(filename, conn, NULL, &bad_path, &st);
2157 if (bad_path) {
2158 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2159 r_u->status = WERR_ACCESS_DENIED;
2160 goto error_exit;
2163 if (!check_name(filename,conn)) {
2164 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2165 r_u->status = WERR_ACCESS_DENIED;
2166 goto error_exit;
2170 fsp = open_file_stat(conn, filename, &st);
2172 if (!fsp) {
2173 /* Perhaps it is a directory */
2174 if (errno == EISDIR)
2175 fsp = open_directory(conn, filename, &st,
2176 FILE_READ_ATTRIBUTES,
2177 FILE_SHARE_READ|FILE_SHARE_WRITE,
2178 FILE_OPEN,
2180 NULL);
2182 if (!fsp) {
2183 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2184 r_u->status = WERR_ACCESS_DENIED;
2185 goto error_exit;
2189 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2191 if (ret == False) {
2192 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2193 r_u->status = WERR_ACCESS_DENIED;
2194 goto error_exit;
2197 close_file(fsp, True);
2198 unbecome_user();
2199 close_cnum(conn, user.vuid);
2200 return r_u->status;
2202 error_exit:
2204 if(fsp) {
2205 close_file(fsp, True);
2208 if (became_user) {
2209 unbecome_user();
2212 if (conn) {
2213 close_cnum(conn, user.vuid);
2216 return r_u->status;
2219 /***********************************************************************************
2220 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2221 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2222 These disks would the disks listed by this function.
2223 Users could then create shares relative to these disks. Watch out for moving these disks around.
2224 "Nigel Williams" <nigel@veritas.com>.
2225 ***********************************************************************************/
2227 static const char *server_disks[] = {"C:"};
2229 static uint32 get_server_disk_count(void)
2231 return sizeof(server_disks)/sizeof(server_disks[0]);
2234 static uint32 init_server_disk_enum(uint32 *resume)
2236 uint32 server_disk_count = get_server_disk_count();
2238 /*resume can be an offset into the list for now*/
2240 if(*resume & 0x80000000)
2241 *resume = 0;
2243 if(*resume > server_disk_count)
2244 *resume = server_disk_count;
2246 return server_disk_count - *resume;
2249 static const char *next_server_disk_enum(uint32 *resume)
2251 const char *disk;
2253 if(init_server_disk_enum(resume) == 0)
2254 return NULL;
2256 disk = server_disks[*resume];
2258 (*resume)++;
2260 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2262 return disk;
2265 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2267 uint32 i;
2268 const char *disk_name;
2269 TALLOC_CTX *ctx = p->mem_ctx;
2270 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2272 r_u->status=WERR_OK;
2274 r_u->total_entries = init_server_disk_enum(&resume);
2276 r_u->disk_enum_ctr.unknown = 0;
2278 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2279 return WERR_NOMEM;
2282 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2284 /*allow one DISK_INFO for null terminator*/
2286 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2288 r_u->disk_enum_ctr.entries_read++;
2290 /*copy disk name into a unicode string*/
2292 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2295 /* add a terminating null string. Is this there if there is more data to come? */
2297 r_u->disk_enum_ctr.entries_read++;
2299 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2301 init_enum_hnd(&r_u->enum_hnd, resume);
2303 return r_u->status;
2306 /********************************************************************
2307 ********************************************************************/
2309 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2311 fstring sharename;
2313 switch ( q_u->type ) {
2314 case 0x9:
2315 rpcstr_pull(sharename, q_u->uni_name.buffer, sizeof(sharename), q_u->uni_name.uni_str_len*2, 0);
2316 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2317 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2318 return WERR_INVALID_NAME;
2320 break;
2322 default:
2323 return WERR_UNKNOWN_LEVEL;
2326 return WERR_OK;