Ok here it is my latest work on privileges
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob7487e106bcfdbebd5ae6f8e0097c35c217c87a2c
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* This is the implementation of the srvsvc pipe. */
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_SRV
30 /*******************************************************************
31 Utility function to get the 'type' of a share from an snum.
32 ********************************************************************/
33 static uint32 get_share_type(int snum)
35 char *net_name = lp_servicename(snum);
36 int len_net_name = strlen(net_name);
38 /* work out the share type */
39 uint32 type = STYPE_DISKTREE;
41 if (lp_print_ok(snum))
42 type = STYPE_PRINTQ;
43 if (strequal(lp_fstype(snum), "IPC"))
44 type = STYPE_IPC;
45 if (net_name[len_net_name] == '$')
46 type |= STYPE_HIDDEN;
48 return type;
51 /*******************************************************************
52 Fill in a share info level 0 structure.
53 ********************************************************************/
55 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
57 pstring net_name;
59 pstrcpy(net_name, lp_servicename(snum));
61 init_srv_share_info0(&sh0->info_0, net_name);
62 init_srv_share_info0_str(&sh0->info_0_str, net_name);
65 /*******************************************************************
66 Fill in a share info level 1 structure.
67 ********************************************************************/
69 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
71 pstring remark;
73 char *net_name = lp_servicename(snum);
74 pstrcpy(remark, lp_comment(snum));
75 standard_sub_conn(p->conn, remark,sizeof(remark));
77 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
78 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
81 /*******************************************************************
82 Fill in a share info level 2 structure.
83 ********************************************************************/
85 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
87 pstring remark;
88 pstring path;
89 pstring passwd;
91 char *net_name = lp_servicename(snum);
92 pstrcpy(remark, lp_comment(snum));
93 standard_sub_conn(p->conn, remark,sizeof(remark));
94 pstrcpy(path, "C:");
95 pstrcat(path, lp_pathname(snum));
98 * Change / to \\ so that win2k will see it as a valid path. This was added to
99 * enable use of browsing in win2k add share dialog.
102 string_replace(path, '/', '\\');
104 pstrcpy(passwd, "");
106 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
107 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
110 /*******************************************************************
111 What to do when smb.conf is updated.
112 ********************************************************************/
114 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
116 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
117 reload_services(False);
120 /*******************************************************************
121 Create the share security tdb.
122 ********************************************************************/
124 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
125 #define SHARE_DATABASE_VERSION_V1 1
126 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
128 BOOL share_info_db_init(void)
130 static pid_t local_pid;
131 const char *vstring = "INFO/version";
132 int32 vers_id;
134 if (share_tdb && local_pid == sys_getpid())
135 return True;
136 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
137 if (!share_tdb) {
138 DEBUG(0,("Failed to open share info database %s (%s)\n",
139 lock_path("share_info.tdb"), strerror(errno) ));
140 return False;
143 local_pid = sys_getpid();
145 /* handle a Samba upgrade */
146 tdb_lock_bystring(share_tdb, vstring, 0);
148 /* Cope with byte-reversed older versions of the db. */
149 vers_id = tdb_fetch_int32(share_tdb, vstring);
150 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
151 /* Written on a bigendian machine with old fetch_int code. Save as le. */
152 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
153 vers_id = SHARE_DATABASE_VERSION_V2;
156 if (vers_id != SHARE_DATABASE_VERSION_V2) {
157 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
158 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
160 tdb_unlock_bystring(share_tdb, vstring);
162 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
164 return True;
167 /*******************************************************************
168 Fake up a Everyone, full access as a default.
169 ********************************************************************/
171 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
173 extern DOM_SID global_sid_World;
174 extern struct generic_mapping file_generic_mapping;
175 SEC_ACCESS sa;
176 SEC_ACE ace;
177 SEC_ACL *psa = NULL;
178 SEC_DESC *psd = NULL;
179 uint32 def_access = GENERIC_ALL_ACCESS;
181 se_map_generic(&def_access, &file_generic_mapping);
183 init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
184 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
186 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
187 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, psize);
190 if (!psd) {
191 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
192 return NULL;
195 return psd;
198 /*******************************************************************
199 Pull a security descriptor from the share tdb.
200 ********************************************************************/
202 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
204 prs_struct ps;
205 fstring key;
206 SEC_DESC *psd = NULL;
208 *psize = 0;
210 /* Fetch security descriptor from tdb */
212 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
214 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
215 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
217 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
219 return get_share_security_default(ctx, snum, psize);
222 if (psd)
223 *psize = sec_desc_size(psd);
225 prs_mem_free(&ps);
226 return psd;
229 /*******************************************************************
230 Store a security descriptor in the share db.
231 ********************************************************************/
233 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
235 prs_struct ps;
236 TALLOC_CTX *mem_ctx = NULL;
237 fstring key;
238 BOOL ret = False;
240 mem_ctx = talloc_init("set_share_security");
241 if (mem_ctx == NULL)
242 return False;
244 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
246 if (!sec_io_desc("share_security", &psd, &ps, 1))
247 goto out;
249 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
251 if (tdb_prs_store(share_tdb, key, &ps)==0) {
252 ret = True;
253 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
254 } else {
255 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
258 /* Free malloc'ed memory */
260 out:
262 prs_mem_free(&ps);
263 if (mem_ctx)
264 talloc_destroy(mem_ctx);
265 return ret;
268 /*******************************************************************
269 Delete a security descriptor.
270 ********************************************************************/
272 static BOOL delete_share_security(int snum)
274 TDB_DATA kbuf;
275 fstring key;
277 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
278 kbuf.dptr = key;
279 kbuf.dsize = strlen(key)+1;
281 if (tdb_delete(share_tdb, kbuf) != 0) {
282 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
283 lp_servicename(snum) ));
284 return False;
287 return True;
290 /*******************************************************************
291 Map any generic bits to file specific bits.
292 ********************************************************************/
294 void map_generic_share_sd_bits(SEC_DESC *psd)
296 extern struct generic_mapping file_generic_mapping;
297 int i;
298 SEC_ACL *ps_dacl = NULL;
300 if (!psd)
301 return;
303 ps_dacl = psd->dacl;
304 if (!ps_dacl)
305 return;
307 for (i = 0; i < ps_dacl->num_aces; i++) {
308 SEC_ACE *psa = &ps_dacl->ace[i];
309 uint32 orig_mask = psa->info.mask;
311 se_map_generic(&psa->info.mask, &file_generic_mapping);
312 psa->info.mask |= orig_mask;
316 /*******************************************************************
317 Can this user access with share with the required permissions ?
318 ********************************************************************/
320 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
322 uint32 granted;
323 NTSTATUS status;
324 TALLOC_CTX *mem_ctx = NULL;
325 SEC_DESC *psd = NULL;
326 size_t sd_size;
327 NT_USER_TOKEN *token = NULL;
328 BOOL ret = True;
330 mem_ctx = talloc_init("share_access_check");
331 if (mem_ctx == NULL)
332 return False;
334 psd = get_share_security(mem_ctx, snum, &sd_size);
336 if (!psd)
337 goto out;
339 if (conn->nt_user_token)
340 token = conn->nt_user_token;
341 else
342 token = vuser->nt_user_token;
344 ret = se_access_check(psd, token, desired_access, &granted, &status);
346 out:
348 talloc_destroy(mem_ctx);
350 return ret;
353 /*******************************************************************
354 Fill in a share info level 501 structure.
355 ********************************************************************/
357 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
359 int len_net_name;
360 pstring remark;
362 char *net_name = lp_servicename(snum);
363 pstrcpy(remark, lp_comment(snum));
364 standard_sub_conn(p->conn, remark, sizeof(remark));
366 len_net_name = strlen(net_name);
368 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
369 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
372 /*******************************************************************
373 Fill in a share info level 502 structure.
374 ********************************************************************/
376 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
378 int len_net_name;
379 pstring net_name;
380 pstring remark;
381 pstring path;
382 pstring passwd;
383 SEC_DESC *sd;
384 size_t sd_size;
385 TALLOC_CTX *ctx = p->mem_ctx;
388 ZERO_STRUCTP(sh502);
390 pstrcpy(net_name, lp_servicename(snum));
391 pstrcpy(remark, lp_comment(snum));
392 standard_sub_conn(p->conn, remark,sizeof(remark));
393 pstrcpy(path, "C:");
394 pstrcat(path, lp_pathname(snum));
397 * Change / to \\ so that win2k will see it as a valid path. This was added to
398 * enable use of browsing in win2k add share dialog.
401 string_replace(path, '/', '\\');
403 pstrcpy(passwd, "");
404 len_net_name = strlen(net_name);
406 sd = get_share_security(ctx, snum, &sd_size);
408 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
409 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
412 /***************************************************************************
413 Fill in a share info level 1004 structure.
414 ***************************************************************************/
416 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
418 pstring remark;
420 pstrcpy(remark, lp_comment(snum));
421 standard_sub_conn(p->conn, remark, sizeof(remark));
423 ZERO_STRUCTP(sh1004);
425 init_srv_share_info1004(&sh1004->info_1004, remark);
426 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
429 /***************************************************************************
430 Fill in a share info level 1005 structure.
431 ***************************************************************************/
433 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
435 sh1005->share_info_flags = 0;
437 if(lp_host_msdfs() && lp_msdfs_root(snum))
438 sh1005->share_info_flags |=
439 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
440 sh1005->share_info_flags |=
441 lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
443 /***************************************************************************
444 Fill in a share info level 1006 structure.
445 ***************************************************************************/
447 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
449 sh1006->max_uses = -1;
452 /***************************************************************************
453 Fill in a share info level 1007 structure.
454 ***************************************************************************/
456 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
458 pstring alternate_directory_name = "";
459 uint32 flags = 0;
461 ZERO_STRUCTP(sh1007);
463 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
464 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
467 /*******************************************************************
468 Fill in a share info level 1501 structure.
469 ********************************************************************/
471 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
473 SEC_DESC *sd;
474 size_t sd_size;
475 TALLOC_CTX *ctx = p->mem_ctx;
477 ZERO_STRUCTP(sh1501);
479 sd = get_share_security(ctx, snum, &sd_size);
481 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
484 /*******************************************************************
485 True if it ends in '$'.
486 ********************************************************************/
488 static BOOL is_hidden_share(int snum)
490 const char *net_name = lp_servicename(snum);
492 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
495 /*******************************************************************
496 Fill in a share info structure.
497 ********************************************************************/
499 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
500 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
502 int num_entries = 0;
503 int num_services = lp_numservices();
504 int snum;
505 TALLOC_CTX *ctx = p->mem_ctx;
507 DEBUG(5,("init_srv_share_info_ctr\n"));
509 ZERO_STRUCTPN(ctr);
511 ctr->info_level = ctr->switch_value = info_level;
512 *resume_hnd = 0;
514 /* Count the number of entries. */
515 for (snum = 0; snum < num_services; snum++) {
516 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
517 num_entries++;
520 *total_entries = num_entries;
521 ctr->num_entries2 = ctr->num_entries = num_entries;
522 ctr->ptr_share_info = ctr->ptr_entries = 1;
524 if (!num_entries)
525 return True;
527 switch (info_level) {
528 case 0:
530 SRV_SHARE_INFO_0 *info0;
531 int i = 0;
533 info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
535 for (snum = *resume_hnd; snum < num_services; snum++) {
536 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
537 init_srv_share_info_0(p, &info0[i++], snum);
541 ctr->share.info0 = info0;
542 break;
546 case 1:
548 SRV_SHARE_INFO_1 *info1;
549 int i = 0;
551 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
553 for (snum = *resume_hnd; snum < num_services; snum++) {
554 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
555 init_srv_share_info_1(p, &info1[i++], snum);
559 ctr->share.info1 = info1;
560 break;
563 case 2:
565 SRV_SHARE_INFO_2 *info2;
566 int i = 0;
568 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
570 for (snum = *resume_hnd; snum < num_services; snum++) {
571 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
572 init_srv_share_info_2(p, &info2[i++], snum);
576 ctr->share.info2 = info2;
577 break;
580 case 501:
582 SRV_SHARE_INFO_501 *info501;
583 int i = 0;
585 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
587 for (snum = *resume_hnd; snum < num_services; snum++) {
588 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
589 init_srv_share_info_501(p, &info501[i++], snum);
593 ctr->share.info501 = info501;
594 break;
597 case 502:
599 SRV_SHARE_INFO_502 *info502;
600 int i = 0;
602 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
604 for (snum = *resume_hnd; snum < num_services; snum++) {
605 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
606 init_srv_share_info_502(p, &info502[i++], snum);
610 ctr->share.info502 = info502;
611 break;
614 /* here for completeness but not currently used with enum (1004 - 1501)*/
616 case 1004:
618 SRV_SHARE_INFO_1004 *info1004;
619 int i = 0;
621 info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
623 for (snum = *resume_hnd; snum < num_services; snum++) {
624 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
625 init_srv_share_info_1004(p, &info1004[i++], snum);
629 ctr->share.info1004 = info1004;
630 break;
633 case 1005:
635 SRV_SHARE_INFO_1005 *info1005;
636 int i = 0;
638 info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
640 for (snum = *resume_hnd; snum < num_services; snum++) {
641 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
642 init_srv_share_info_1005(p, &info1005[i++], snum);
646 ctr->share.info1005 = info1005;
647 break;
650 case 1006:
652 SRV_SHARE_INFO_1006 *info1006;
653 int i = 0;
655 info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
657 for (snum = *resume_hnd; snum < num_services; snum++) {
658 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
659 init_srv_share_info_1006(p, &info1006[i++], snum);
663 ctr->share.info1006 = info1006;
664 break;
667 case 1007:
669 SRV_SHARE_INFO_1007 *info1007;
670 int i = 0;
672 info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
674 for (snum = *resume_hnd; snum < num_services; snum++) {
675 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
676 init_srv_share_info_1007(p, &info1007[i++], snum);
680 ctr->share.info1007 = info1007;
681 break;
684 case 1501:
686 SRV_SHARE_INFO_1501 *info1501;
687 int i = 0;
689 info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
691 for (snum = *resume_hnd; snum < num_services; snum++) {
692 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
693 init_srv_share_info_1501(p, &info1501[i++], snum);
697 ctr->share.info1501 = info1501;
698 break;
700 default:
701 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
702 return False;
705 return True;
708 /*******************************************************************
709 Inits a SRV_R_NET_SHARE_ENUM structure.
710 ********************************************************************/
712 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
713 uint32 info_level, uint32 resume_hnd, BOOL all)
715 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
717 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
718 &resume_hnd, &r_n->total_entries, all)) {
719 r_n->status = WERR_OK;
720 } else {
721 r_n->status = WERR_UNKNOWN_LEVEL;
724 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
727 /*******************************************************************
728 Inits a SRV_R_NET_SHARE_GET_INFO structure.
729 ********************************************************************/
731 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
732 char *share_name, uint32 info_level)
734 WERROR status = WERR_OK;
735 int snum;
737 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
739 r_n->info.switch_value = info_level;
741 snum = find_service(share_name);
743 if (snum >= 0) {
744 switch (info_level) {
745 case 0:
746 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
747 break;
748 case 1:
749 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
750 break;
751 case 2:
752 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
753 break;
754 case 501:
755 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
756 break;
757 case 502:
758 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
759 break;
761 /* here for completeness */
762 case 1004:
763 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
764 break;
765 case 1005:
766 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
767 break;
769 /* here for completeness 1006 - 1501 */
770 case 1006:
771 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
772 break;
773 case 1007:
774 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
775 break;
776 case 1501:
777 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
778 break;
779 default:
780 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
781 status = WERR_UNKNOWN_LEVEL;
782 break;
784 } else {
785 status = WERR_INVALID_NAME;
788 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
789 r_n->status = status;
792 /*******************************************************************
793 fill in a sess info level 1 structure.
794 ********************************************************************/
796 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
798 init_srv_sess_info0(se0, name);
799 init_srv_sess_info0_str(str0, name);
802 /*******************************************************************
803 fill in a sess info level 0 structure.
804 ********************************************************************/
806 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
808 struct sessionid *session_list;
809 uint32 num_entries = 0;
810 (*stot) = list_sessions(&session_list);
812 if (ss0 == NULL) {
813 (*snum) = 0;
814 SAFE_FREE(session_list);
815 return;
818 DEBUG(5,("init_srv_sess_0_ss0\n"));
820 if (snum) {
821 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
822 init_srv_sess_0_info(&ss0->info_0[num_entries],
823 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
825 /* move on to creating next session */
826 /* move on to creating next sess */
827 num_entries++;
830 ss0->num_entries_read = num_entries;
831 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
832 ss0->num_entries_read2 = num_entries;
834 if ((*snum) >= (*stot)) {
835 (*snum) = 0;
838 } else {
839 ss0->num_entries_read = 0;
840 ss0->ptr_sess_info = 0;
841 ss0->num_entries_read2 = 0;
843 SAFE_FREE(session_list);
846 /*******************************************************************
847 fill in a sess info level 1 structure.
848 ********************************************************************/
850 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
851 char *name, char *user,
852 uint32 num_opens,
853 uint32 open_time, uint32 idle_time,
854 uint32 usr_flgs)
856 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
857 init_srv_sess_info1_str(str1, name, user);
860 /*******************************************************************
861 fill in a sess info level 1 structure.
862 ********************************************************************/
864 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
866 struct sessionid *session_list;
867 uint32 num_entries = 0;
868 (*stot) = list_sessions(&session_list);
870 if (ss1 == NULL) {
871 (*snum) = 0;
872 SAFE_FREE(session_list);
873 return;
876 DEBUG(5,("init_srv_sess_1_ss1\n"));
878 if (snum) {
879 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
880 init_srv_sess_1_info(&ss1->info_1[num_entries],
881 &ss1->info_1_str[num_entries],
882 session_list[*snum].remote_machine,
883 session_list[*snum].username,
884 1, 10, 5, 0);
886 /* move on to creating next session */
887 /* move on to creating next sess */
888 num_entries++;
891 ss1->num_entries_read = num_entries;
892 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
893 ss1->num_entries_read2 = num_entries;
895 if ((*snum) >= (*stot)) {
896 (*snum) = 0;
899 } else {
900 ss1->num_entries_read = 0;
901 ss1->ptr_sess_info = 0;
902 ss1->num_entries_read2 = 0;
904 (*stot) = 0;
908 /*******************************************************************
909 makes a SRV_R_NET_SESS_ENUM structure.
910 ********************************************************************/
912 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
913 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
915 WERROR status = WERR_OK;
916 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
918 ctr->switch_value = switch_value;
920 switch (switch_value) {
921 case 0:
922 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
923 ctr->ptr_sess_ctr = 1;
924 break;
925 case 1:
926 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
927 ctr->ptr_sess_ctr = 1;
928 break;
929 default:
930 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
931 (*resume_hnd) = 0;
932 (*total_entries) = 0;
933 ctr->ptr_sess_ctr = 0;
934 status = WERR_UNKNOWN_LEVEL;
935 break;
938 return status;
941 /*******************************************************************
942 makes a SRV_R_NET_SESS_ENUM structure.
943 ********************************************************************/
945 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
946 uint32 resume_hnd, int sess_level, int switch_value)
948 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
950 r_n->sess_level = sess_level;
952 if (sess_level == -1)
953 r_n->status = WERR_UNKNOWN_LEVEL;
954 else
955 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
957 if (!W_ERROR_IS_OK(r_n->status))
958 resume_hnd = 0;
960 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
963 /*******************************************************************
964 fill in a conn info level 0 structure.
965 ********************************************************************/
967 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
969 uint32 num_entries = 0;
970 (*stot) = 1;
972 if (ss0 == NULL) {
973 (*snum) = 0;
974 return;
977 DEBUG(5,("init_srv_conn_0_ss0\n"));
979 if (snum) {
980 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
982 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
984 /* move on to creating next connection */
985 /* move on to creating next conn */
986 num_entries++;
989 ss0->num_entries_read = num_entries;
990 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
991 ss0->num_entries_read2 = num_entries;
993 if ((*snum) >= (*stot)) {
994 (*snum) = 0;
997 } else {
998 ss0->num_entries_read = 0;
999 ss0->ptr_conn_info = 0;
1000 ss0->num_entries_read2 = 0;
1002 (*stot) = 0;
1006 /*******************************************************************
1007 fill in a conn info level 1 structure.
1008 ********************************************************************/
1010 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1011 uint32 id, uint32 type,
1012 uint32 num_opens, uint32 num_users, uint32 open_time,
1013 const char *usr_name, const char *net_name)
1015 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1016 init_srv_conn_info1_str(str1, usr_name, net_name);
1019 /*******************************************************************
1020 fill in a conn info level 1 structure.
1021 ********************************************************************/
1023 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1025 uint32 num_entries = 0;
1026 (*stot) = 1;
1028 if (ss1 == NULL) {
1029 (*snum) = 0;
1030 return;
1033 DEBUG(5,("init_srv_conn_1_ss1\n"));
1035 if (snum) {
1036 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1037 init_srv_conn_1_info(&ss1->info_1[num_entries],
1038 &ss1->info_1_str[num_entries],
1039 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1041 /* move on to creating next connection */
1042 /* move on to creating next conn */
1043 num_entries++;
1046 ss1->num_entries_read = num_entries;
1047 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1048 ss1->num_entries_read2 = num_entries;
1051 if ((*snum) >= (*stot)) {
1052 (*snum) = 0;
1055 } else {
1056 ss1->num_entries_read = 0;
1057 ss1->ptr_conn_info = 0;
1058 ss1->num_entries_read2 = 0;
1060 (*stot) = 0;
1064 /*******************************************************************
1065 makes a SRV_R_NET_CONN_ENUM structure.
1066 ********************************************************************/
1068 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1069 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1071 WERROR status = WERR_OK;
1072 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1074 ctr->switch_value = switch_value;
1076 switch (switch_value) {
1077 case 0:
1078 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1079 ctr->ptr_conn_ctr = 1;
1080 break;
1081 case 1:
1082 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1083 ctr->ptr_conn_ctr = 1;
1084 break;
1085 default:
1086 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1087 (*resume_hnd = 0);
1088 (*total_entries) = 0;
1089 ctr->ptr_conn_ctr = 0;
1090 status = WERR_UNKNOWN_LEVEL;
1091 break;
1094 return status;
1097 /*******************************************************************
1098 makes a SRV_R_NET_CONN_ENUM structure.
1099 ********************************************************************/
1101 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1102 uint32 resume_hnd, int conn_level, int switch_value)
1104 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1106 r_n->conn_level = conn_level;
1107 if (conn_level == -1)
1108 r_n->status = WERR_UNKNOWN_LEVEL;
1109 else
1110 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1112 if (!W_ERROR_IS_OK(r_n->status))
1113 resume_hnd = 0;
1115 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1118 /*******************************************************************
1119 makes a SRV_R_NET_FILE_ENUM structure.
1120 ********************************************************************/
1122 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1123 int switch_value, uint32 *resume_hnd,
1124 uint32 *total_entries)
1126 WERROR status = WERR_OK;
1127 TALLOC_CTX *ctx = p->mem_ctx;
1128 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1129 *total_entries = 1; /* dummy entries only, for */
1131 ctr->switch_value = switch_value;
1132 ctr->num_entries = *total_entries - *resume_hnd;
1133 ctr->num_entries2 = ctr->num_entries;
1135 switch (switch_value) {
1136 case 3: {
1137 int i;
1138 if (*total_entries > 0) {
1139 ctr->ptr_entries = 1;
1140 ctr->file.info3 = talloc(ctx, ctr->num_entries *
1141 sizeof(SRV_FILE_INFO_3));
1143 for (i=0 ;i<ctr->num_entries;i++) {
1144 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1145 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1148 ctr->ptr_file_info = 1;
1149 *resume_hnd = 0;
1150 break;
1152 default:
1153 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1154 (*resume_hnd = 0);
1155 (*total_entries) = 0;
1156 ctr->ptr_entries = 0;
1157 status = WERR_UNKNOWN_LEVEL;
1158 break;
1161 return status;
1164 /*******************************************************************
1165 makes a SRV_R_NET_FILE_ENUM structure.
1166 ********************************************************************/
1168 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1169 uint32 resume_hnd, int file_level, int switch_value)
1171 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1173 r_n->file_level = file_level;
1174 if (file_level == 0)
1175 r_n->status = WERR_UNKNOWN_LEVEL;
1176 else
1177 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1179 if (!W_ERROR_IS_OK(r_n->status))
1180 resume_hnd = 0;
1182 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1185 /*******************************************************************
1186 net server get info
1187 ********************************************************************/
1189 WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
1191 WERROR status = WERR_OK;
1192 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1194 if (!ctr)
1195 return WERR_NOMEM;
1197 ZERO_STRUCTP(ctr);
1199 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1201 if (!pipe_access_check(p)) {
1202 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1203 return WERR_ACCESS_DENIED;
1206 switch (q_u->switch_value) {
1208 /* Technically level 102 should only be available to
1209 Administrators but there isn't anything super-secret
1210 here, as most of it is made up. */
1212 case 102:
1213 init_srv_info_102(&ctr->srv.sv102,
1214 500, global_myname(),
1215 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1216 lp_major_announce_version(), lp_minor_announce_version(),
1217 lp_default_server_announce(),
1218 0xffffffff, /* users */
1219 0xf, /* disc */
1220 0, /* hidden */
1221 240, /* announce */
1222 3000, /* announce delta */
1223 100000, /* licenses */
1224 "c:\\"); /* user path */
1225 break;
1226 case 101:
1227 init_srv_info_101(&ctr->srv.sv101,
1228 500, global_myname(),
1229 lp_major_announce_version(), lp_minor_announce_version(),
1230 lp_default_server_announce(),
1231 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1232 break;
1233 case 100:
1234 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1235 break;
1236 default:
1237 status = WERR_UNKNOWN_LEVEL;
1238 break;
1241 /* set up the net server get info structure */
1242 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1244 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1246 return r_u->status;
1249 /*******************************************************************
1250 net server set info
1251 ********************************************************************/
1253 WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1255 WERROR status = WERR_OK;
1257 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1259 /* Set up the net server set info structure. */
1261 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1263 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1265 return r_u->status;
1268 /*******************************************************************
1269 net file enum
1270 ********************************************************************/
1272 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1274 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1276 /* set up the */
1277 init_srv_r_net_file_enum(p, r_u,
1278 get_enum_hnd(&q_u->enum_hnd),
1279 q_u->file_level,
1280 q_u->ctr.switch_value);
1282 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1284 return r_u->status;
1287 /*******************************************************************
1288 net conn enum
1289 ********************************************************************/
1291 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1293 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1295 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1296 if (!r_u->ctr)
1297 return WERR_NOMEM;
1299 ZERO_STRUCTP(r_u->ctr);
1301 /* set up the */
1302 init_srv_r_net_conn_enum(r_u,
1303 get_enum_hnd(&q_u->enum_hnd),
1304 q_u->conn_level,
1305 q_u->ctr->switch_value);
1307 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1309 return r_u->status;
1312 /*******************************************************************
1313 net sess enum
1314 ********************************************************************/
1316 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1318 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1320 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1321 if (!r_u->ctr)
1322 return WERR_NOMEM;
1324 ZERO_STRUCTP(r_u->ctr);
1326 /* set up the */
1327 init_srv_r_net_sess_enum(r_u,
1328 get_enum_hnd(&q_u->enum_hnd),
1329 q_u->sess_level,
1330 q_u->ctr->switch_value);
1332 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1334 return r_u->status;
1337 /*******************************************************************
1338 Net share enum all.
1339 ********************************************************************/
1341 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1343 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1345 if (!pipe_access_check(p)) {
1346 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1347 return WERR_ACCESS_DENIED;
1350 /* Create the list of shares for the response. */
1351 init_srv_r_net_share_enum(p, r_u,
1352 q_u->ctr.info_level,
1353 get_enum_hnd(&q_u->enum_hnd), True);
1355 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1357 return r_u->status;
1360 /*******************************************************************
1361 Net share enum.
1362 ********************************************************************/
1364 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1366 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1368 if (!pipe_access_check(p)) {
1369 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1370 return WERR_ACCESS_DENIED;
1373 /* Create the list of shares for the response. */
1374 init_srv_r_net_share_enum(p, r_u,
1375 q_u->ctr.info_level,
1376 get_enum_hnd(&q_u->enum_hnd), False);
1378 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1380 return r_u->status;
1383 /*******************************************************************
1384 Net share get info.
1385 ********************************************************************/
1387 WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1389 fstring share_name;
1391 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1393 /* Create the list of shares for the response. */
1394 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1395 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1397 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1399 return r_u->status;
1402 /*******************************************************************
1403 Check a given DOS pathname is valid for a share.
1404 ********************************************************************/
1406 static char *valid_share_pathname(char *dos_pathname)
1408 char *ptr;
1410 /* Convert any '\' paths to '/' */
1411 unix_format(dos_pathname);
1412 unix_clean_name(dos_pathname);
1414 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1415 ptr = dos_pathname;
1416 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1417 ptr += 2;
1419 /* Only abolute paths allowed. */
1420 if (*ptr != '/')
1421 return NULL;
1423 return ptr;
1426 static BOOL exist_share_pathname(char *unix_pathname)
1428 pstring saved_pathname;
1429 int ret;
1431 /* Can we cd to it ? */
1433 /* First save our current directory. */
1434 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1435 return False;
1437 ret = chdir(unix_pathname);
1439 /* We *MUST* be able to chdir back. Abort if we can't. */
1440 if (chdir(saved_pathname) == -1)
1441 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1443 if (ret == -1) return False;
1445 return True;
1448 /*******************************************************************
1449 Net share set info. Modify share details.
1450 ********************************************************************/
1452 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)
1454 struct current_user user;
1455 pstring command;
1456 fstring share_name;
1457 fstring comment;
1458 pstring pathname;
1459 int type;
1460 int snum;
1461 int ret;
1462 char *path;
1463 SEC_DESC *psd = NULL;
1465 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1467 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1469 r_u->parm_error = 0;
1471 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1472 return WERR_ACCESS_DENIED;
1474 snum = find_service(share_name);
1476 /* Does this share exist ? */
1477 if (snum < 0)
1478 return WERR_INVALID_NAME;
1480 /* No change to printer shares. */
1481 if (lp_print_ok(snum))
1482 return WERR_ACCESS_DENIED;
1484 get_current_user(&user,p);
1486 if (user.uid != sec_initial_uid())
1487 return WERR_ACCESS_DENIED;
1489 switch (q_u->info_level) {
1490 case 1:
1491 pstrcpy(pathname, lp_pathname(snum));
1492 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1493 type = q_u->info.share.info2.info_2.type;
1494 psd = NULL;
1495 break;
1496 case 2:
1497 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1498 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1499 type = q_u->info.share.info2.info_2.type;
1500 psd = NULL;
1501 break;
1502 #if 0
1503 /* not supported on set but here for completeness */
1504 case 501:
1505 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1506 type = q_u->info.share.info501.info_501.type;
1507 psd = NULL;
1508 break;
1509 #endif
1510 case 502:
1511 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1512 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1513 type = q_u->info.share.info502.info_502.type;
1514 psd = q_u->info.share.info502.info_502_str.sd;
1515 map_generic_share_sd_bits(psd);
1516 break;
1517 case 1004:
1518 pstrcpy(pathname, lp_pathname(snum));
1519 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1520 type = STYPE_DISKTREE;
1521 break;
1522 case 1005:
1523 /* XP re-sets the csc policy even if it wasn't changed by the
1524 user, so we must compare it to see if it's what is set in
1525 smb.conf, so that we can contine other ops like setting
1526 ACLs on a share */
1527 if (((q_u->info.share.info1005.share_info_flags &
1528 SHARE_1005_CSC_POLICY_MASK) >>
1529 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1530 return WERR_OK;
1531 else {
1532 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1533 return WERR_ACCESS_DENIED;
1535 break;
1536 case 1006:
1537 case 1007:
1538 return WERR_ACCESS_DENIED;
1539 break;
1540 case 1501:
1541 pstrcpy(pathname, lp_pathname(snum));
1542 fstrcpy(comment, lp_comment(snum));
1543 psd = q_u->info.share.info1501.sdb->sec;
1544 map_generic_share_sd_bits(psd);
1545 type = STYPE_DISKTREE;
1546 break;
1547 default:
1548 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1549 return WERR_UNKNOWN_LEVEL;
1552 /* We can only modify disk shares. */
1553 if (type != STYPE_DISKTREE)
1554 return WERR_ACCESS_DENIED;
1556 /* Check if the pathname is valid. */
1557 if (!(path = valid_share_pathname( pathname )))
1558 return WERR_OBJECT_PATH_INVALID;
1560 /* Ensure share name, pathname and comment don't contain '"' characters. */
1561 string_replace(share_name, '"', ' ');
1562 string_replace(path, '"', ' ');
1563 string_replace(comment, '"', ' ');
1565 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1566 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1568 /* Only call modify function if something changed. */
1570 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1571 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1572 return WERR_ACCESS_DENIED;
1574 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1575 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1577 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1578 if ((ret = smbrun(command, NULL)) != 0) {
1579 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1580 return WERR_ACCESS_DENIED;
1583 /* Check if the new share pathname exist, if not return an error */
1584 if (!exist_share_pathname(path)) {
1585 DEBUG(1, ("_srv_net_share_set_info: change share command was ok but path (%s) has not been created!\n", path));
1586 return WERR_OBJECT_PATH_INVALID;
1589 /* Tell everyone we updated smb.conf. */
1590 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1592 } else {
1593 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1596 /* Replace SD if changed. */
1597 if (psd) {
1598 SEC_DESC *old_sd;
1599 size_t sd_size;
1601 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1603 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1604 if (!set_share_security(p->mem_ctx, share_name, psd))
1605 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1606 share_name ));
1610 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1612 return WERR_OK;
1615 /*******************************************************************
1616 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1617 ********************************************************************/
1619 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1621 struct current_user user;
1622 pstring command;
1623 fstring share_name;
1624 fstring comment;
1625 pstring pathname;
1626 int type;
1627 int snum;
1628 int ret;
1629 char *path;
1630 SEC_DESC *psd = NULL;
1632 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1634 r_u->parm_error = 0;
1636 get_current_user(&user,p);
1638 if (user.uid != sec_initial_uid()) {
1639 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1640 return WERR_ACCESS_DENIED;
1643 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1644 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1645 return WERR_ACCESS_DENIED;
1648 switch (q_u->info_level) {
1649 case 0:
1650 /* No path. Not enough info in a level 0 to do anything. */
1651 return WERR_ACCESS_DENIED;
1652 case 1:
1653 /* Not enough info in a level 1 to do anything. */
1654 return WERR_ACCESS_DENIED;
1655 case 2:
1656 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1657 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1658 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1659 type = q_u->info.share.info2.info_2.type;
1660 break;
1661 case 501:
1662 /* No path. Not enough info in a level 501 to do anything. */
1663 return WERR_ACCESS_DENIED;
1664 case 502:
1665 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1666 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1667 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1668 type = q_u->info.share.info502.info_502.type;
1669 psd = q_u->info.share.info502.info_502_str.sd;
1670 map_generic_share_sd_bits(psd);
1671 break;
1673 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1675 case 1004:
1676 case 1005:
1677 case 1006:
1678 case 1007:
1679 return WERR_ACCESS_DENIED;
1680 break;
1681 case 1501:
1682 /* DFS only level. */
1683 return WERR_ACCESS_DENIED;
1684 default:
1685 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1686 return WERR_UNKNOWN_LEVEL;
1689 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1690 return WERR_ACCESS_DENIED;
1692 snum = find_service(share_name);
1694 /* Share already exists. */
1695 if (snum >= 0)
1696 return WERR_ALREADY_EXISTS;
1698 /* We can only add disk shares. */
1699 if (type != STYPE_DISKTREE)
1700 return WERR_ACCESS_DENIED;
1702 /* Check if the pathname is valid. */
1703 if (!(path = valid_share_pathname( pathname )))
1704 return WERR_OBJECT_PATH_INVALID;
1706 /* Ensure share name, pathname and comment don't contain '"' characters. */
1707 string_replace(share_name, '"', ' ');
1708 string_replace(path, '"', ' ');
1709 string_replace(comment, '"', ' ');
1711 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1712 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1714 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1715 if ((ret = smbrun(command, NULL)) != 0) {
1716 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1717 return WERR_ACCESS_DENIED;
1720 /* Check if the new share pathname exist, if not try to delete the
1721 * share and return an error */
1722 if (!exist_share_pathname(path)) {
1723 DEBUG(1, ("_srv_net_share_add: add share command was ok but path (%s) has not been created!\n", path));
1724 DEBUG(1, ("_srv_net_share_add: trying to rollback and delete the share\n"));
1726 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1727 DEBUG(1, ("_srv_net_share_add: Error! delete share command is not defined! Please check share (%s) in the config file\n", share_name));
1728 return WERR_OBJECT_PATH_INVALID;
1731 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1732 lp_delete_share_cmd(), dyn_CONFIGFILE, share_name);
1734 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1735 if ((ret = smbrun(command, NULL)) != 0) {
1736 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1737 DEBUG(1, ("_srv_net_share_add: Error! delete share command failed! Please check share (%s) in the config file\n", share_name));
1740 return WERR_OBJECT_PATH_INVALID;
1743 if (psd) {
1744 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1745 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1749 /* Tell everyone we updated smb.conf. */
1750 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1753 * We don't call reload_services() here, the message will
1754 * cause this to be done before the next packet is read
1755 * from the client. JRA.
1758 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1760 return WERR_OK;
1763 /*******************************************************************
1764 Net share delete. Call "delete share command" with the share name as
1765 a parameter.
1766 ********************************************************************/
1768 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1770 struct current_user user;
1771 pstring command;
1772 fstring share_name;
1773 int ret;
1774 int snum;
1776 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1778 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1780 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1781 return WERR_ACCESS_DENIED;
1783 snum = find_service(share_name);
1785 if (snum < 0)
1786 return WERR_NO_SUCH_SHARE;
1788 /* No change to printer shares. */
1789 if (lp_print_ok(snum))
1790 return WERR_ACCESS_DENIED;
1792 get_current_user(&user,p);
1794 if (user.uid != sec_initial_uid())
1795 return WERR_ACCESS_DENIED;
1797 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1798 return WERR_ACCESS_DENIED;
1800 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1801 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1803 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1804 if ((ret = smbrun(command, NULL)) != 0) {
1805 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1806 return WERR_ACCESS_DENIED;
1809 /* Delete the SD in the database. */
1810 delete_share_security(snum);
1812 /* Tell everyone we updated smb.conf. */
1813 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1815 lp_killservice(snum);
1817 return WERR_OK;
1820 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1822 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1824 return _srv_net_share_del(p, q_u, r_u);
1827 /*******************************************************************
1828 time of day
1829 ********************************************************************/
1831 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1833 TIME_OF_DAY_INFO *tod;
1834 struct tm *t;
1835 time_t unixdate = time(NULL);
1837 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1838 if (!tod)
1839 return WERR_NOMEM;
1841 ZERO_STRUCTP(tod);
1843 r_u->tod = tod;
1844 r_u->ptr_srv_tod = 0x1;
1845 r_u->status = WERR_OK;
1847 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1849 t = gmtime(&unixdate);
1851 /* set up the */
1852 init_time_of_day_info(tod,
1853 unixdate,
1855 t->tm_hour,
1856 t->tm_min,
1857 t->tm_sec,
1859 TimeDiff(unixdate)/60,
1860 10000,
1861 t->tm_mday,
1862 t->tm_mon + 1,
1863 1900+t->tm_year,
1864 t->tm_wday);
1866 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1868 return r_u->status;
1871 /***********************************************************************************
1872 Win9x NT tools get security descriptor.
1873 ***********************************************************************************/
1875 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1876 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1878 SEC_DESC *psd = NULL;
1879 size_t sd_size;
1880 DATA_BLOB null_pw;
1881 pstring filename;
1882 pstring qualname;
1883 files_struct *fsp = NULL;
1884 SMB_STRUCT_STAT st;
1885 BOOL bad_path;
1886 int access_mode;
1887 int action;
1888 NTSTATUS nt_status;
1889 struct current_user user;
1890 connection_struct *conn = NULL;
1891 BOOL became_user = False;
1893 ZERO_STRUCT(st);
1895 r_u->status = WERR_OK;
1897 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1899 /* Null password is ok - we are already an authenticated user... */
1900 null_pw = data_blob(NULL, 0);
1902 get_current_user(&user, p);
1904 become_root();
1905 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1906 unbecome_root();
1908 if (conn == NULL) {
1909 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1910 r_u->status = ntstatus_to_werror(nt_status);
1911 goto error_exit;
1914 if (!become_user(conn, conn->vuid)) {
1915 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1916 r_u->status = WERR_ACCESS_DENIED;
1917 goto error_exit;
1919 became_user = True;
1921 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1922 unix_convert(filename, conn, NULL, &bad_path, &st);
1923 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1924 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1926 if (!fsp) {
1927 /* Perhaps it is a directory */
1928 if (errno == EISDIR)
1929 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1930 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1932 if (!fsp) {
1933 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1934 r_u->status = WERR_ACCESS_DENIED;
1935 goto error_exit;
1939 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1941 if (sd_size == 0) {
1942 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1943 r_u->status = WERR_ACCESS_DENIED;
1944 goto error_exit;
1947 r_u->ptr_response = 1;
1948 r_u->size_response = sd_size;
1949 r_u->ptr_secdesc = 1;
1950 r_u->size_secdesc = sd_size;
1951 r_u->sec_desc = psd;
1953 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1955 close_file(fsp, True);
1956 unbecome_user();
1957 close_cnum(conn, user.vuid);
1958 return r_u->status;
1960 error_exit:
1962 if(fsp) {
1963 close_file(fsp, True);
1966 if (became_user)
1967 unbecome_user();
1969 if (conn)
1970 close_cnum(conn, user.vuid);
1972 return r_u->status;
1975 /***********************************************************************************
1976 Win9x NT tools set security descriptor.
1977 ***********************************************************************************/
1979 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1980 SRV_R_NET_FILE_SET_SECDESC *r_u)
1982 BOOL ret;
1983 pstring filename;
1984 pstring qualname;
1985 DATA_BLOB null_pw;
1986 files_struct *fsp = NULL;
1987 SMB_STRUCT_STAT st;
1988 BOOL bad_path;
1989 int access_mode;
1990 int action;
1991 NTSTATUS nt_status;
1992 struct current_user user;
1993 connection_struct *conn = NULL;
1994 BOOL became_user = False;
1996 ZERO_STRUCT(st);
1998 r_u->status = WERR_OK;
2000 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2002 /* Null password is ok - we are already an authenticated user... */
2003 null_pw = data_blob(NULL, 0);
2005 get_current_user(&user, p);
2007 become_root();
2008 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2009 unbecome_root();
2011 if (conn == NULL) {
2012 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2013 r_u->status = ntstatus_to_werror(nt_status);
2014 goto error_exit;
2017 if (!become_user(conn, conn->vuid)) {
2018 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2019 r_u->status = WERR_ACCESS_DENIED;
2020 goto error_exit;
2022 became_user = True;
2024 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2025 unix_convert(filename, conn, NULL, &bad_path, &st);
2027 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
2028 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
2030 if (!fsp) {
2031 /* Perhaps it is a directory */
2032 if (errno == EISDIR)
2033 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2034 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
2036 if (!fsp) {
2037 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2038 r_u->status = WERR_ACCESS_DENIED;
2039 goto error_exit;
2043 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2045 if (ret == False) {
2046 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2047 r_u->status = WERR_ACCESS_DENIED;
2048 goto error_exit;
2051 close_file(fsp, True);
2052 unbecome_user();
2053 close_cnum(conn, user.vuid);
2054 return r_u->status;
2056 error_exit:
2058 if(fsp) {
2059 close_file(fsp, True);
2062 if (became_user)
2063 unbecome_user();
2065 if (conn)
2066 close_cnum(conn, user.vuid);
2068 return r_u->status;
2071 /***********************************************************************************
2072 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2073 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2074 These disks would the disks listed by this function.
2075 Users could then create shares relative to these disks. Watch out for moving these disks around.
2076 "Nigel Williams" <nigel@veritas.com>.
2077 ***********************************************************************************/
2079 static const char *server_disks[] = {"C:"};
2081 static uint32 get_server_disk_count(void)
2083 return sizeof(server_disks)/sizeof(server_disks[0]);
2086 static uint32 init_server_disk_enum(uint32 *resume)
2088 uint32 server_disk_count = get_server_disk_count();
2090 /*resume can be an offset into the list for now*/
2092 if(*resume & 0x80000000)
2093 *resume = 0;
2095 if(*resume > server_disk_count)
2096 *resume = server_disk_count;
2098 return server_disk_count - *resume;
2101 static const char *next_server_disk_enum(uint32 *resume)
2103 const char *disk;
2105 if(init_server_disk_enum(resume) == 0)
2106 return NULL;
2108 disk = server_disks[*resume];
2110 (*resume)++;
2112 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2114 return disk;
2117 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2119 uint32 i;
2120 const char *disk_name;
2121 TALLOC_CTX *ctx = p->mem_ctx;
2122 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2124 r_u->status=WERR_OK;
2126 r_u->total_entries = init_server_disk_enum(&resume);
2128 r_u->disk_enum_ctr.unknown = 0;
2131 DISK_INFO *dinfo;
2133 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2135 if(!(dinfo = talloc(ctx, dinfo_size))) {
2136 return WERR_NOMEM;
2139 r_u->disk_enum_ctr.disk_info = dinfo;
2142 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2144 /*allow one DISK_INFO for null terminator*/
2146 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2148 r_u->disk_enum_ctr.entries_read++;
2150 /*copy disk name into a unicode string*/
2152 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2155 /* add a terminating null string. Is this there if there is more data to come? */
2157 r_u->disk_enum_ctr.entries_read++;
2159 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2161 init_enum_hnd(&r_u->enum_hnd, resume);
2163 return r_u->status;
2166 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2168 int snum;
2169 fstring share_name;
2171 r_u->status=WERR_OK;
2173 switch(q_u->type) {
2175 case 0x9:
2177 /*check if share name is ok*/
2178 /*also check if we already have a share with this name*/
2180 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2181 snum = find_service(share_name);
2183 /* Share already exists. */
2184 if (snum >= 0)
2185 r_u->status = WERR_ALREADY_EXISTS;
2186 break;
2188 default:
2189 /*unsupported type*/
2190 r_u->status = WERR_UNKNOWN_LEVEL;
2191 break;
2194 return r_u->status;