r15: syncing for 3.0.3pre2
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob77b9be99660ba64f3d66ea6831398449e5b96fc2
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 pstring saved_pathname;
1409 pstring unix_pathname;
1410 char *ptr;
1411 int ret;
1413 /* Convert any '\' paths to '/' */
1414 unix_format(dos_pathname);
1415 unix_clean_name(dos_pathname);
1417 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1418 ptr = dos_pathname;
1419 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1420 ptr += 2;
1422 /* Only abolute paths allowed. */
1423 if (*ptr != '/')
1424 return NULL;
1426 /* Can we cd to it ? */
1428 /* First save our current directory. */
1429 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1430 return False;
1432 pstrcpy(unix_pathname, ptr);
1434 ret = chdir(unix_pathname);
1436 /* We *MUST* be able to chdir back. Abort if we can't. */
1437 if (chdir(saved_pathname) == -1)
1438 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1440 return (ret != -1) ? ptr : NULL;
1443 /*******************************************************************
1444 Net share set info. Modify share details.
1445 ********************************************************************/
1447 WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1449 struct current_user user;
1450 pstring command;
1451 fstring share_name;
1452 fstring comment;
1453 pstring pathname;
1454 int type;
1455 int snum;
1456 int ret;
1457 char *ptr;
1458 SEC_DESC *psd = NULL;
1460 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1462 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1464 r_u->parm_error = 0;
1466 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1467 return WERR_ACCESS_DENIED;
1469 snum = find_service(share_name);
1471 /* Does this share exist ? */
1472 if (snum < 0)
1473 return WERR_INVALID_NAME;
1475 /* No change to printer shares. */
1476 if (lp_print_ok(snum))
1477 return WERR_ACCESS_DENIED;
1479 get_current_user(&user,p);
1481 if (user.uid != sec_initial_uid())
1482 return WERR_ACCESS_DENIED;
1484 switch (q_u->info_level) {
1485 case 1:
1486 pstrcpy(pathname, lp_pathname(snum));
1487 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1488 type = q_u->info.share.info2.info_2.type;
1489 psd = NULL;
1490 break;
1491 case 2:
1492 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1493 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1494 type = q_u->info.share.info2.info_2.type;
1495 psd = NULL;
1496 break;
1497 #if 0
1498 /* not supported on set but here for completeness */
1499 case 501:
1500 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1501 type = q_u->info.share.info501.info_501.type;
1502 psd = NULL;
1503 break;
1504 #endif
1505 case 502:
1506 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1507 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1508 type = q_u->info.share.info502.info_502.type;
1509 psd = q_u->info.share.info502.info_502_str.sd;
1510 map_generic_share_sd_bits(psd);
1511 break;
1512 case 1004:
1513 pstrcpy(pathname, lp_pathname(snum));
1514 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1515 type = STYPE_DISKTREE;
1516 break;
1517 case 1005:
1518 /* XP re-sets the csc policy even if it wasn't changed by the
1519 user, so we must compare it to see if it's what is set in
1520 smb.conf, so that we can contine other ops like setting
1521 ACLs on a share */
1522 if (((q_u->info.share.info1005.share_info_flags &
1523 SHARE_1005_CSC_POLICY_MASK) >>
1524 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1525 return WERR_OK;
1526 else {
1527 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1528 return WERR_ACCESS_DENIED;
1530 break;
1531 case 1006:
1532 case 1007:
1533 return WERR_ACCESS_DENIED;
1534 break;
1535 case 1501:
1536 pstrcpy(pathname, lp_pathname(snum));
1537 fstrcpy(comment, lp_comment(snum));
1538 psd = q_u->info.share.info1501.sdb->sec;
1539 map_generic_share_sd_bits(psd);
1540 type = STYPE_DISKTREE;
1541 break;
1542 default:
1543 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1544 return WERR_UNKNOWN_LEVEL;
1547 /* We can only modify disk shares. */
1548 if (type != STYPE_DISKTREE)
1549 return WERR_ACCESS_DENIED;
1551 /* Check if the pathname is valid. */
1552 if (!(ptr = valid_share_pathname( pathname )))
1553 return WERR_OBJECT_PATH_INVALID;
1555 /* Ensure share name, pathname and comment don't contain '"' characters. */
1556 string_replace(share_name, '"', ' ');
1557 string_replace(ptr, '"', ' ');
1558 string_replace(comment, '"', ' ');
1560 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1561 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1563 /* Only call modify function if something changed. */
1565 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1566 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1567 return WERR_ACCESS_DENIED;
1569 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1570 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1572 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1573 if ((ret = smbrun(command, NULL)) != 0) {
1574 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1575 return WERR_ACCESS_DENIED;
1578 /* Tell everyone we updated smb.conf. */
1579 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1581 } else {
1582 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1585 /* Replace SD if changed. */
1586 if (psd) {
1587 SEC_DESC *old_sd;
1588 size_t sd_size;
1590 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1592 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1593 if (!set_share_security(p->mem_ctx, share_name, psd))
1594 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1595 share_name ));
1599 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1601 return WERR_OK;
1604 /*******************************************************************
1605 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1606 ********************************************************************/
1608 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1610 struct current_user user;
1611 pstring command;
1612 fstring share_name;
1613 fstring comment;
1614 pstring pathname;
1615 int type;
1616 int snum;
1617 int ret;
1618 char *ptr;
1619 SEC_DESC *psd = NULL;
1621 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1623 r_u->parm_error = 0;
1625 get_current_user(&user,p);
1627 if (user.uid != sec_initial_uid()) {
1628 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1629 return WERR_ACCESS_DENIED;
1632 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1633 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1634 return WERR_ACCESS_DENIED;
1637 switch (q_u->info_level) {
1638 case 0:
1639 /* No path. Not enough info in a level 0 to do anything. */
1640 return WERR_ACCESS_DENIED;
1641 case 1:
1642 /* Not enough info in a level 1 to do anything. */
1643 return WERR_ACCESS_DENIED;
1644 case 2:
1645 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1646 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1647 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1648 type = q_u->info.share.info2.info_2.type;
1649 break;
1650 case 501:
1651 /* No path. Not enough info in a level 501 to do anything. */
1652 return WERR_ACCESS_DENIED;
1653 case 502:
1654 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1655 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1656 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1657 type = q_u->info.share.info502.info_502.type;
1658 psd = q_u->info.share.info502.info_502_str.sd;
1659 map_generic_share_sd_bits(psd);
1660 break;
1662 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1664 case 1004:
1665 case 1005:
1666 case 1006:
1667 case 1007:
1668 return WERR_ACCESS_DENIED;
1669 break;
1670 case 1501:
1671 /* DFS only level. */
1672 return WERR_ACCESS_DENIED;
1673 default:
1674 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1675 return WERR_UNKNOWN_LEVEL;
1678 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1679 return WERR_ACCESS_DENIED;
1681 snum = find_service(share_name);
1683 /* Share already exists. */
1684 if (snum >= 0)
1685 return WERR_ALREADY_EXISTS;
1687 /* We can only add disk shares. */
1688 if (type != STYPE_DISKTREE)
1689 return WERR_ACCESS_DENIED;
1691 /* Check if the pathname is valid. */
1692 if (!(ptr = valid_share_pathname( pathname )))
1693 return WERR_OBJECT_PATH_INVALID;
1695 /* Ensure share name, pathname and comment don't contain '"' characters. */
1696 string_replace(share_name, '"', ' ');
1697 string_replace(ptr, '"', ' ');
1698 string_replace(comment, '"', ' ');
1700 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1701 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1703 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1704 if ((ret = smbrun(command, NULL)) != 0) {
1705 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1706 return WERR_ACCESS_DENIED;
1709 if (psd) {
1710 if (!set_share_security(p->mem_ctx, share_name, psd))
1711 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1712 share_name ));
1715 /* Tell everyone we updated smb.conf. */
1716 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1719 * We don't call reload_services() here, the message will
1720 * cause this to be done before the next packet is read
1721 * from the client. JRA.
1724 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1726 return WERR_OK;
1729 /*******************************************************************
1730 Net share delete. Call "delete share command" with the share name as
1731 a parameter.
1732 ********************************************************************/
1734 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1736 struct current_user user;
1737 pstring command;
1738 fstring share_name;
1739 int ret;
1740 int snum;
1742 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1744 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1746 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1747 return WERR_ACCESS_DENIED;
1749 snum = find_service(share_name);
1751 if (snum < 0)
1752 return WERR_NO_SUCH_SHARE;
1754 /* No change to printer shares. */
1755 if (lp_print_ok(snum))
1756 return WERR_ACCESS_DENIED;
1758 get_current_user(&user,p);
1760 if (user.uid != sec_initial_uid())
1761 return WERR_ACCESS_DENIED;
1763 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1764 return WERR_ACCESS_DENIED;
1766 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1767 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1769 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1770 if ((ret = smbrun(command, NULL)) != 0) {
1771 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1772 return WERR_ACCESS_DENIED;
1775 /* Delete the SD in the database. */
1776 delete_share_security(snum);
1778 /* Tell everyone we updated smb.conf. */
1779 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1781 lp_killservice(snum);
1783 return WERR_OK;
1786 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1788 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1790 return _srv_net_share_del(p, q_u, r_u);
1793 /*******************************************************************
1794 time of day
1795 ********************************************************************/
1797 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1799 TIME_OF_DAY_INFO *tod;
1800 struct tm *t;
1801 time_t unixdate = time(NULL);
1803 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1804 if (!tod)
1805 return WERR_NOMEM;
1807 ZERO_STRUCTP(tod);
1809 r_u->tod = tod;
1810 r_u->ptr_srv_tod = 0x1;
1811 r_u->status = WERR_OK;
1813 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1815 t = gmtime(&unixdate);
1817 /* set up the */
1818 init_time_of_day_info(tod,
1819 unixdate,
1821 t->tm_hour,
1822 t->tm_min,
1823 t->tm_sec,
1825 TimeDiff(unixdate)/60,
1826 10000,
1827 t->tm_mday,
1828 t->tm_mon + 1,
1829 1900+t->tm_year,
1830 t->tm_wday);
1832 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1834 return r_u->status;
1837 /***********************************************************************************
1838 Win9x NT tools get security descriptor.
1839 ***********************************************************************************/
1841 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1842 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1844 SEC_DESC *psd = NULL;
1845 size_t sd_size;
1846 DATA_BLOB null_pw;
1847 pstring filename;
1848 pstring qualname;
1849 files_struct *fsp = NULL;
1850 SMB_STRUCT_STAT st;
1851 BOOL bad_path;
1852 int access_mode;
1853 int action;
1854 NTSTATUS nt_status;
1855 struct current_user user;
1856 connection_struct *conn = NULL;
1857 BOOL became_user = False;
1859 ZERO_STRUCT(st);
1861 r_u->status = WERR_OK;
1863 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1865 /* Null password is ok - we are already an authenticated user... */
1866 null_pw = data_blob(NULL, 0);
1868 get_current_user(&user, p);
1870 become_root();
1871 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1872 unbecome_root();
1874 if (conn == NULL) {
1875 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1876 r_u->status = ntstatus_to_werror(nt_status);
1877 goto error_exit;
1880 if (!become_user(conn, conn->vuid)) {
1881 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1882 r_u->status = WERR_ACCESS_DENIED;
1883 goto error_exit;
1885 became_user = True;
1887 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1888 unix_convert(filename, conn, NULL, &bad_path, &st);
1889 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1890 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
1892 if (!fsp) {
1893 /* Perhaps it is a directory */
1894 if (errno == EISDIR)
1895 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1896 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
1898 if (!fsp) {
1899 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1900 r_u->status = WERR_ACCESS_DENIED;
1901 goto error_exit;
1905 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1907 if (sd_size == 0) {
1908 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1909 r_u->status = WERR_ACCESS_DENIED;
1910 goto error_exit;
1913 r_u->ptr_response = 1;
1914 r_u->size_response = sd_size;
1915 r_u->ptr_secdesc = 1;
1916 r_u->size_secdesc = sd_size;
1917 r_u->sec_desc = psd;
1919 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1921 close_file(fsp, True);
1922 unbecome_user();
1923 close_cnum(conn, user.vuid);
1924 return r_u->status;
1926 error_exit:
1928 if(fsp) {
1929 close_file(fsp, True);
1932 if (became_user)
1933 unbecome_user();
1935 if (conn)
1936 close_cnum(conn, user.vuid);
1938 return r_u->status;
1941 /***********************************************************************************
1942 Win9x NT tools set security descriptor.
1943 ***********************************************************************************/
1945 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1946 SRV_R_NET_FILE_SET_SECDESC *r_u)
1948 BOOL ret;
1949 pstring filename;
1950 pstring qualname;
1951 DATA_BLOB null_pw;
1952 files_struct *fsp = NULL;
1953 SMB_STRUCT_STAT st;
1954 BOOL bad_path;
1955 int access_mode;
1956 int action;
1957 NTSTATUS nt_status;
1958 struct current_user user;
1959 connection_struct *conn = NULL;
1960 BOOL became_user = False;
1962 ZERO_STRUCT(st);
1964 r_u->status = WERR_OK;
1966 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1968 /* Null password is ok - we are already an authenticated user... */
1969 null_pw = data_blob(NULL, 0);
1971 get_current_user(&user, p);
1973 become_root();
1974 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1975 unbecome_root();
1977 if (conn == NULL) {
1978 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1979 r_u->status = ntstatus_to_werror(nt_status);
1980 goto error_exit;
1983 if (!become_user(conn, conn->vuid)) {
1984 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1985 r_u->status = WERR_ACCESS_DENIED;
1986 goto error_exit;
1988 became_user = True;
1990 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1991 unix_convert(filename, conn, NULL, &bad_path, &st);
1993 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1994 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
1996 if (!fsp) {
1997 /* Perhaps it is a directory */
1998 if (errno == EISDIR)
1999 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2000 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2002 if (!fsp) {
2003 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2004 r_u->status = WERR_ACCESS_DENIED;
2005 goto error_exit;
2009 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2011 if (ret == False) {
2012 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2013 r_u->status = WERR_ACCESS_DENIED;
2014 goto error_exit;
2017 close_file(fsp, True);
2018 unbecome_user();
2019 close_cnum(conn, user.vuid);
2020 return r_u->status;
2022 error_exit:
2024 if(fsp) {
2025 close_file(fsp, True);
2028 if (became_user)
2029 unbecome_user();
2031 if (conn)
2032 close_cnum(conn, user.vuid);
2034 return r_u->status;
2037 /***********************************************************************************
2038 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2039 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2040 These disks would the disks listed by this function.
2041 Users could then create shares relative to these disks. Watch out for moving these disks around.
2042 "Nigel Williams" <nigel@veritas.com>.
2043 ***********************************************************************************/
2045 static const char *server_disks[] = {"C:"};
2047 static uint32 get_server_disk_count(void)
2049 return sizeof(server_disks)/sizeof(server_disks[0]);
2052 static uint32 init_server_disk_enum(uint32 *resume)
2054 uint32 server_disk_count = get_server_disk_count();
2056 /*resume can be an offset into the list for now*/
2058 if(*resume & 0x80000000)
2059 *resume = 0;
2061 if(*resume > server_disk_count)
2062 *resume = server_disk_count;
2064 return server_disk_count - *resume;
2067 static const char *next_server_disk_enum(uint32 *resume)
2069 const char *disk;
2071 if(init_server_disk_enum(resume) == 0)
2072 return NULL;
2074 disk = server_disks[*resume];
2076 (*resume)++;
2078 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2080 return disk;
2083 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2085 uint32 i;
2086 const char *disk_name;
2087 TALLOC_CTX *ctx = p->mem_ctx;
2088 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2090 r_u->status=WERR_OK;
2092 r_u->total_entries = init_server_disk_enum(&resume);
2094 r_u->disk_enum_ctr.unknown = 0;
2097 DISK_INFO *dinfo;
2099 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2101 if(!(dinfo = talloc(ctx, dinfo_size))) {
2102 return WERR_NOMEM;
2105 r_u->disk_enum_ctr.disk_info = dinfo;
2108 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2110 /*allow one DISK_INFO for null terminator*/
2112 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2114 r_u->disk_enum_ctr.entries_read++;
2116 /*copy disk name into a unicode string*/
2118 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2121 /* add a terminating null string. Is this there if there is more data to come? */
2123 r_u->disk_enum_ctr.entries_read++;
2125 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2127 init_enum_hnd(&r_u->enum_hnd, resume);
2129 return r_u->status;
2132 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2134 int snum;
2135 fstring share_name;
2137 r_u->status=WERR_OK;
2139 switch(q_u->type) {
2141 case 0x9:
2143 /*check if share name is ok*/
2144 /*also check if we already have a share with this name*/
2146 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2147 snum = find_service(share_name);
2149 /* Share already exists. */
2150 if (snum >= 0)
2151 r_u->status = WERR_ALREADY_EXISTS;
2152 break;
2154 default:
2155 /*unsupported type*/
2156 r_u->status = WERR_UNKNOWN_LEVEL;
2157 break;
2160 return r_u->status;