First round of merging various UUID structures.
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_srvsvc_nt.c
blob4d1cf9bddcb84cd268a1a96c15b8f380d8b4ae10
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 pstring net_name;
492 pstrcpy(net_name, lp_servicename(snum));
493 return (net_name[strlen(net_name)] == '$') ? True : False;
496 /*******************************************************************
497 Fill in a share info structure.
498 ********************************************************************/
500 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
501 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
503 int num_entries = 0;
504 int num_services = lp_numservices();
505 int snum;
506 TALLOC_CTX *ctx = p->mem_ctx;
508 DEBUG(5,("init_srv_share_info_ctr\n"));
510 ZERO_STRUCTPN(ctr);
512 ctr->info_level = ctr->switch_value = info_level;
513 *resume_hnd = 0;
515 /* Count the number of entries. */
516 for (snum = 0; snum < num_services; snum++) {
517 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
518 num_entries++;
521 *total_entries = num_entries;
522 ctr->num_entries2 = ctr->num_entries = num_entries;
523 ctr->ptr_share_info = ctr->ptr_entries = 1;
525 if (!num_entries)
526 return True;
528 switch (info_level) {
529 case 0:
531 SRV_SHARE_INFO_0 *info0;
532 int i = 0;
534 info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
536 for (snum = *resume_hnd; snum < num_services; snum++) {
537 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
538 init_srv_share_info_0(p, &info0[i++], snum);
542 ctr->share.info0 = info0;
543 break;
547 case 1:
549 SRV_SHARE_INFO_1 *info1;
550 int i = 0;
552 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
554 for (snum = *resume_hnd; snum < num_services; snum++) {
555 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
556 init_srv_share_info_1(p, &info1[i++], snum);
560 ctr->share.info1 = info1;
561 break;
564 case 2:
566 SRV_SHARE_INFO_2 *info2;
567 int i = 0;
569 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
571 for (snum = *resume_hnd; snum < num_services; snum++) {
572 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
573 init_srv_share_info_2(p, &info2[i++], snum);
577 ctr->share.info2 = info2;
578 break;
581 case 501:
583 SRV_SHARE_INFO_501 *info501;
584 int i = 0;
586 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
588 for (snum = *resume_hnd; snum < num_services; snum++) {
589 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
590 init_srv_share_info_501(p, &info501[i++], snum);
594 ctr->share.info501 = info501;
595 break;
598 case 502:
600 SRV_SHARE_INFO_502 *info502;
601 int i = 0;
603 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
605 for (snum = *resume_hnd; snum < num_services; snum++) {
606 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
607 init_srv_share_info_502(p, &info502[i++], snum);
611 ctr->share.info502 = info502;
612 break;
615 /* here for completeness but not currently used with enum (1004 - 1501)*/
617 case 1004:
619 SRV_SHARE_INFO_1004 *info1004;
620 int i = 0;
622 info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
624 for (snum = *resume_hnd; snum < num_services; snum++) {
625 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
626 init_srv_share_info_1004(p, &info1004[i++], snum);
630 ctr->share.info1004 = info1004;
631 break;
634 case 1005:
636 SRV_SHARE_INFO_1005 *info1005;
637 int i = 0;
639 info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
641 for (snum = *resume_hnd; snum < num_services; snum++) {
642 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
643 init_srv_share_info_1005(p, &info1005[i++], snum);
647 ctr->share.info1005 = info1005;
648 break;
651 case 1006:
653 SRV_SHARE_INFO_1006 *info1006;
654 int i = 0;
656 info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
658 for (snum = *resume_hnd; snum < num_services; snum++) {
659 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
660 init_srv_share_info_1006(p, &info1006[i++], snum);
664 ctr->share.info1006 = info1006;
665 break;
668 case 1007:
670 SRV_SHARE_INFO_1007 *info1007;
671 int i = 0;
673 info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
675 for (snum = *resume_hnd; snum < num_services; snum++) {
676 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
677 init_srv_share_info_1007(p, &info1007[i++], snum);
681 ctr->share.info1007 = info1007;
682 break;
685 case 1501:
687 SRV_SHARE_INFO_1501 *info1501;
688 int i = 0;
690 info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
692 for (snum = *resume_hnd; snum < num_services; snum++) {
693 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
694 init_srv_share_info_1501(p, &info1501[i++], snum);
698 ctr->share.info1501 = info1501;
699 break;
701 default:
702 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
703 return False;
706 return True;
709 /*******************************************************************
710 Inits a SRV_R_NET_SHARE_ENUM structure.
711 ********************************************************************/
713 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
714 uint32 info_level, uint32 resume_hnd, BOOL all)
716 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
718 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
719 &resume_hnd, &r_n->total_entries, all)) {
720 r_n->status = WERR_OK;
721 } else {
722 r_n->status = WERR_UNKNOWN_LEVEL;
725 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
728 /*******************************************************************
729 Inits a SRV_R_NET_SHARE_GET_INFO structure.
730 ********************************************************************/
732 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
733 char *share_name, uint32 info_level)
735 WERROR status = WERR_OK;
736 int snum;
738 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
740 r_n->info.switch_value = info_level;
742 snum = find_service(share_name);
744 if (snum >= 0) {
745 switch (info_level) {
746 case 0:
747 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
748 break;
749 case 1:
750 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
751 break;
752 case 2:
753 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
754 break;
755 case 501:
756 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
757 break;
758 case 502:
759 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
760 break;
762 /* here for completeness */
763 case 1004:
764 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
765 break;
766 case 1005:
767 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
768 break;
770 /* here for completeness 1006 - 1501 */
771 case 1006:
772 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
773 break;
774 case 1007:
775 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
776 break;
777 case 1501:
778 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
779 break;
780 default:
781 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
782 status = WERR_UNKNOWN_LEVEL;
783 break;
785 } else {
786 status = WERR_INVALID_NAME;
789 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
790 r_n->status = status;
793 /*******************************************************************
794 fill in a sess info level 1 structure.
795 ********************************************************************/
797 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
799 init_srv_sess_info0(se0, name);
800 init_srv_sess_info0_str(str0, name);
803 /*******************************************************************
804 fill in a sess info level 0 structure.
805 ********************************************************************/
807 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
809 struct sessionid *session_list;
810 uint32 num_entries = 0;
811 (*stot) = list_sessions(&session_list);
813 if (ss0 == NULL) {
814 (*snum) = 0;
815 SAFE_FREE(session_list);
816 return;
819 DEBUG(5,("init_srv_sess_0_ss0\n"));
821 if (snum) {
822 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
823 init_srv_sess_0_info(&ss0->info_0[num_entries],
824 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
826 /* move on to creating next session */
827 /* move on to creating next sess */
828 num_entries++;
831 ss0->num_entries_read = num_entries;
832 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
833 ss0->num_entries_read2 = num_entries;
835 if ((*snum) >= (*stot)) {
836 (*snum) = 0;
839 } else {
840 ss0->num_entries_read = 0;
841 ss0->ptr_sess_info = 0;
842 ss0->num_entries_read2 = 0;
844 SAFE_FREE(session_list);
847 /*******************************************************************
848 fill in a sess info level 1 structure.
849 ********************************************************************/
851 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
852 char *name, char *user,
853 uint32 num_opens,
854 uint32 open_time, uint32 idle_time,
855 uint32 usr_flgs)
857 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
858 init_srv_sess_info1_str(str1, name, user);
861 /*******************************************************************
862 fill in a sess info level 1 structure.
863 ********************************************************************/
865 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
867 struct sessionid *session_list;
868 uint32 num_entries = 0;
869 (*stot) = list_sessions(&session_list);
871 if (ss1 == NULL) {
872 (*snum) = 0;
873 SAFE_FREE(session_list);
874 return;
877 DEBUG(5,("init_srv_sess_1_ss1\n"));
879 if (snum) {
880 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
881 init_srv_sess_1_info(&ss1->info_1[num_entries],
882 &ss1->info_1_str[num_entries],
883 session_list[*snum].remote_machine,
884 session_list[*snum].username,
885 1, 10, 5, 0);
887 /* move on to creating next session */
888 /* move on to creating next sess */
889 num_entries++;
892 ss1->num_entries_read = num_entries;
893 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
894 ss1->num_entries_read2 = num_entries;
896 if ((*snum) >= (*stot)) {
897 (*snum) = 0;
900 } else {
901 ss1->num_entries_read = 0;
902 ss1->ptr_sess_info = 0;
903 ss1->num_entries_read2 = 0;
905 (*stot) = 0;
909 /*******************************************************************
910 makes a SRV_R_NET_SESS_ENUM structure.
911 ********************************************************************/
913 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
914 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
916 WERROR status = WERR_OK;
917 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
919 ctr->switch_value = switch_value;
921 switch (switch_value) {
922 case 0:
923 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
924 ctr->ptr_sess_ctr = 1;
925 break;
926 case 1:
927 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
928 ctr->ptr_sess_ctr = 1;
929 break;
930 default:
931 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
932 (*resume_hnd) = 0;
933 (*total_entries) = 0;
934 ctr->ptr_sess_ctr = 0;
935 status = WERR_UNKNOWN_LEVEL;
936 break;
939 return status;
942 /*******************************************************************
943 makes a SRV_R_NET_SESS_ENUM structure.
944 ********************************************************************/
946 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
947 uint32 resume_hnd, int sess_level, int switch_value)
949 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
951 r_n->sess_level = sess_level;
953 if (sess_level == -1)
954 r_n->status = WERR_UNKNOWN_LEVEL;
955 else
956 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
958 if (!W_ERROR_IS_OK(r_n->status))
959 resume_hnd = 0;
961 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
964 /*******************************************************************
965 fill in a conn info level 0 structure.
966 ********************************************************************/
968 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
970 uint32 num_entries = 0;
971 (*stot) = 1;
973 if (ss0 == NULL) {
974 (*snum) = 0;
975 return;
978 DEBUG(5,("init_srv_conn_0_ss0\n"));
980 if (snum) {
981 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
983 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
985 /* move on to creating next connection */
986 /* move on to creating next conn */
987 num_entries++;
990 ss0->num_entries_read = num_entries;
991 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
992 ss0->num_entries_read2 = num_entries;
994 if ((*snum) >= (*stot)) {
995 (*snum) = 0;
998 } else {
999 ss0->num_entries_read = 0;
1000 ss0->ptr_conn_info = 0;
1001 ss0->num_entries_read2 = 0;
1003 (*stot) = 0;
1007 /*******************************************************************
1008 fill in a conn info level 1 structure.
1009 ********************************************************************/
1011 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1012 uint32 id, uint32 type,
1013 uint32 num_opens, uint32 num_users, uint32 open_time,
1014 const char *usr_name, const char *net_name)
1016 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1017 init_srv_conn_info1_str(str1, usr_name, net_name);
1020 /*******************************************************************
1021 fill in a conn info level 1 structure.
1022 ********************************************************************/
1024 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1026 uint32 num_entries = 0;
1027 (*stot) = 1;
1029 if (ss1 == NULL) {
1030 (*snum) = 0;
1031 return;
1034 DEBUG(5,("init_srv_conn_1_ss1\n"));
1036 if (snum) {
1037 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1038 init_srv_conn_1_info(&ss1->info_1[num_entries],
1039 &ss1->info_1_str[num_entries],
1040 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1042 /* move on to creating next connection */
1043 /* move on to creating next conn */
1044 num_entries++;
1047 ss1->num_entries_read = num_entries;
1048 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1049 ss1->num_entries_read2 = num_entries;
1052 if ((*snum) >= (*stot)) {
1053 (*snum) = 0;
1056 } else {
1057 ss1->num_entries_read = 0;
1058 ss1->ptr_conn_info = 0;
1059 ss1->num_entries_read2 = 0;
1061 (*stot) = 0;
1065 /*******************************************************************
1066 makes a SRV_R_NET_CONN_ENUM structure.
1067 ********************************************************************/
1069 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1070 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1072 WERROR status = WERR_OK;
1073 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1075 ctr->switch_value = switch_value;
1077 switch (switch_value) {
1078 case 0:
1079 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1080 ctr->ptr_conn_ctr = 1;
1081 break;
1082 case 1:
1083 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1084 ctr->ptr_conn_ctr = 1;
1085 break;
1086 default:
1087 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1088 (*resume_hnd = 0);
1089 (*total_entries) = 0;
1090 ctr->ptr_conn_ctr = 0;
1091 status = WERR_UNKNOWN_LEVEL;
1092 break;
1095 return status;
1098 /*******************************************************************
1099 makes a SRV_R_NET_CONN_ENUM structure.
1100 ********************************************************************/
1102 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1103 uint32 resume_hnd, int conn_level, int switch_value)
1105 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1107 r_n->conn_level = conn_level;
1108 if (conn_level == -1)
1109 r_n->status = WERR_UNKNOWN_LEVEL;
1110 else
1111 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1113 if (!W_ERROR_IS_OK(r_n->status))
1114 resume_hnd = 0;
1116 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1119 /*******************************************************************
1120 makes a SRV_R_NET_FILE_ENUM structure.
1121 ********************************************************************/
1123 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1124 int switch_value, uint32 *resume_hnd,
1125 uint32 *total_entries)
1127 WERROR status = WERR_OK;
1128 TALLOC_CTX *ctx = p->mem_ctx;
1129 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1130 *total_entries = 1; /* dummy entries only, for */
1132 ctr->switch_value = switch_value;
1133 ctr->num_entries = *total_entries - *resume_hnd;
1134 ctr->num_entries2 = ctr->num_entries;
1136 switch (switch_value) {
1137 case 3: {
1138 int i;
1139 if (*total_entries > 0) {
1140 ctr->ptr_entries = 1;
1141 ctr->file.info3 = talloc(ctx, ctr->num_entries *
1142 sizeof(SRV_FILE_INFO_3));
1144 for (i=0 ;i<ctr->num_entries;i++) {
1145 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1146 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1149 ctr->ptr_file_info = 1;
1150 *resume_hnd = 0;
1151 break;
1153 default:
1154 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1155 (*resume_hnd = 0);
1156 (*total_entries) = 0;
1157 ctr->ptr_entries = 0;
1158 status = WERR_UNKNOWN_LEVEL;
1159 break;
1162 return status;
1165 /*******************************************************************
1166 makes a SRV_R_NET_FILE_ENUM structure.
1167 ********************************************************************/
1169 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1170 uint32 resume_hnd, int file_level, int switch_value)
1172 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1174 r_n->file_level = file_level;
1175 if (file_level == 0)
1176 r_n->status = WERR_UNKNOWN_LEVEL;
1177 else
1178 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1180 if (!W_ERROR_IS_OK(r_n->status))
1181 resume_hnd = 0;
1183 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1186 /*******************************************************************
1187 net server get info
1188 ********************************************************************/
1190 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)
1192 WERROR status = WERR_OK;
1193 SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1195 if (!ctr)
1196 return WERR_NOMEM;
1198 ZERO_STRUCTP(ctr);
1200 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1202 if (!pipe_access_check(p)) {
1203 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1204 return WERR_ACCESS_DENIED;
1207 switch (q_u->switch_value) {
1209 /* Technically level 102 should only be available to
1210 Administrators but there isn't anything super-secret
1211 here, as most of it is made up. */
1213 case 102:
1214 init_srv_info_102(&ctr->srv.sv102,
1215 500, global_myname(),
1216 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1217 lp_major_announce_version(), lp_minor_announce_version(),
1218 lp_default_server_announce(),
1219 0xffffffff, /* users */
1220 0xf, /* disc */
1221 0, /* hidden */
1222 240, /* announce */
1223 3000, /* announce delta */
1224 100000, /* licenses */
1225 "c:\\"); /* user path */
1226 break;
1227 case 101:
1228 init_srv_info_101(&ctr->srv.sv101,
1229 500, global_myname(),
1230 lp_major_announce_version(), lp_minor_announce_version(),
1231 lp_default_server_announce(),
1232 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1233 break;
1234 case 100:
1235 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1236 break;
1237 default:
1238 status = WERR_UNKNOWN_LEVEL;
1239 break;
1242 /* set up the net server get info structure */
1243 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1245 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1247 return r_u->status;
1250 /*******************************************************************
1251 net server set info
1252 ********************************************************************/
1254 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)
1256 WERROR status = WERR_OK;
1258 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1260 /* Set up the net server set info structure. */
1262 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1264 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1266 return r_u->status;
1269 /*******************************************************************
1270 net file enum
1271 ********************************************************************/
1273 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1275 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1277 /* set up the */
1278 init_srv_r_net_file_enum(p, r_u,
1279 get_enum_hnd(&q_u->enum_hnd),
1280 q_u->file_level,
1281 q_u->ctr.switch_value);
1283 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1285 return r_u->status;
1288 /*******************************************************************
1289 net conn enum
1290 ********************************************************************/
1292 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1294 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1296 r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1297 if (!r_u->ctr)
1298 return WERR_NOMEM;
1300 ZERO_STRUCTP(r_u->ctr);
1302 /* set up the */
1303 init_srv_r_net_conn_enum(r_u,
1304 get_enum_hnd(&q_u->enum_hnd),
1305 q_u->conn_level,
1306 q_u->ctr->switch_value);
1308 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1310 return r_u->status;
1313 /*******************************************************************
1314 net sess enum
1315 ********************************************************************/
1317 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1319 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1321 r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1322 if (!r_u->ctr)
1323 return WERR_NOMEM;
1325 ZERO_STRUCTP(r_u->ctr);
1327 /* set up the */
1328 init_srv_r_net_sess_enum(r_u,
1329 get_enum_hnd(&q_u->enum_hnd),
1330 q_u->sess_level,
1331 q_u->ctr->switch_value);
1333 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1335 return r_u->status;
1338 /*******************************************************************
1339 Net share enum all.
1340 ********************************************************************/
1342 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1344 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1346 if (!pipe_access_check(p)) {
1347 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1348 return WERR_ACCESS_DENIED;
1351 /* Create the list of shares for the response. */
1352 init_srv_r_net_share_enum(p, r_u,
1353 q_u->ctr.info_level,
1354 get_enum_hnd(&q_u->enum_hnd), True);
1356 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1358 return r_u->status;
1361 /*******************************************************************
1362 Net share enum.
1363 ********************************************************************/
1365 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1367 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1369 if (!pipe_access_check(p)) {
1370 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1371 return WERR_ACCESS_DENIED;
1374 /* Create the list of shares for the response. */
1375 init_srv_r_net_share_enum(p, r_u,
1376 q_u->ctr.info_level,
1377 get_enum_hnd(&q_u->enum_hnd), False);
1379 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1381 return r_u->status;
1384 /*******************************************************************
1385 Net share get info.
1386 ********************************************************************/
1388 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)
1390 fstring share_name;
1392 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1394 /* Create the list of shares for the response. */
1395 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1396 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1398 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1400 return r_u->status;
1403 /*******************************************************************
1404 Check a given DOS pathname is valid for a share.
1405 ********************************************************************/
1407 static char *valid_share_pathname(char *dos_pathname)
1409 pstring saved_pathname;
1410 pstring unix_pathname;
1411 char *ptr;
1412 int ret;
1414 /* Convert any '\' paths to '/' */
1415 unix_format(dos_pathname);
1416 unix_clean_name(dos_pathname);
1418 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1419 ptr = dos_pathname;
1420 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1421 ptr += 2;
1423 /* Only abolute paths allowed. */
1424 if (*ptr != '/')
1425 return NULL;
1427 /* Can we cd to it ? */
1429 /* First save our current directory. */
1430 if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1431 return False;
1433 pstrcpy(unix_pathname, ptr);
1435 ret = chdir(unix_pathname);
1437 /* We *MUST* be able to chdir back. Abort if we can't. */
1438 if (chdir(saved_pathname) == -1)
1439 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1441 return (ret != -1) ? ptr : NULL;
1444 /*******************************************************************
1445 Net share set info. Modify share details.
1446 ********************************************************************/
1448 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)
1450 struct current_user user;
1451 pstring command;
1452 fstring share_name;
1453 fstring comment;
1454 pstring pathname;
1455 int type;
1456 int snum;
1457 int ret;
1458 char *ptr;
1459 SEC_DESC *psd = NULL;
1461 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1463 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1465 r_u->parm_error = 0;
1467 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1468 return WERR_ACCESS_DENIED;
1470 snum = find_service(share_name);
1472 /* Does this share exist ? */
1473 if (snum < 0)
1474 return WERR_INVALID_NAME;
1476 /* No change to printer shares. */
1477 if (lp_print_ok(snum))
1478 return WERR_ACCESS_DENIED;
1480 get_current_user(&user,p);
1482 if (user.uid != sec_initial_uid())
1483 return WERR_ACCESS_DENIED;
1485 switch (q_u->info_level) {
1486 case 1:
1487 pstrcpy(pathname, lp_pathname(snum));
1488 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1489 type = q_u->info.share.info2.info_2.type;
1490 psd = NULL;
1491 break;
1492 case 2:
1493 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1494 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1495 type = q_u->info.share.info2.info_2.type;
1496 psd = NULL;
1497 break;
1498 #if 0
1499 /* not supported on set but here for completeness */
1500 case 501:
1501 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1502 type = q_u->info.share.info501.info_501.type;
1503 psd = NULL;
1504 break;
1505 #endif
1506 case 502:
1507 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1508 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1509 type = q_u->info.share.info502.info_502.type;
1510 psd = q_u->info.share.info502.info_502_str.sd;
1511 map_generic_share_sd_bits(psd);
1512 break;
1513 case 1004:
1514 pstrcpy(pathname, lp_pathname(snum));
1515 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1516 type = STYPE_DISKTREE;
1517 break;
1518 case 1005:
1519 /* XP re-sets the csc policy even if it wasn't changed by the
1520 user, so we must compare it to see if it's what is set in
1521 smb.conf, so that we can contine other ops like setting
1522 ACLs on a share */
1523 if (((q_u->info.share.info1005.share_info_flags &
1524 SHARE_1005_CSC_POLICY_MASK) >>
1525 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1526 return WERR_OK;
1527 else {
1528 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1529 return WERR_ACCESS_DENIED;
1531 break;
1532 case 1006:
1533 case 1007:
1534 return WERR_ACCESS_DENIED;
1535 break;
1536 case 1501:
1537 pstrcpy(pathname, lp_pathname(snum));
1538 fstrcpy(comment, lp_comment(snum));
1539 psd = q_u->info.share.info1501.sdb->sec;
1540 map_generic_share_sd_bits(psd);
1541 type = STYPE_DISKTREE;
1542 break;
1543 default:
1544 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1545 return WERR_UNKNOWN_LEVEL;
1548 /* We can only modify disk shares. */
1549 if (type != STYPE_DISKTREE)
1550 return WERR_ACCESS_DENIED;
1552 /* Check if the pathname is valid. */
1553 if (!(ptr = valid_share_pathname( pathname )))
1554 return WERR_OBJECT_PATH_INVALID;
1556 /* Ensure share name, pathname and comment don't contain '"' characters. */
1557 string_replace(share_name, '"', ' ');
1558 string_replace(ptr, '"', ' ');
1559 string_replace(comment, '"', ' ');
1561 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1562 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1564 /* Only call modify function if something changed. */
1566 if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1567 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1568 return WERR_ACCESS_DENIED;
1570 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1571 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1573 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1574 if ((ret = smbrun(command, NULL)) != 0) {
1575 DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1576 return WERR_ACCESS_DENIED;
1579 /* Tell everyone we updated smb.conf. */
1580 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1582 } else {
1583 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1586 /* Replace SD if changed. */
1587 if (psd) {
1588 SEC_DESC *old_sd;
1589 size_t sd_size;
1591 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1593 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1594 if (!set_share_security(p->mem_ctx, share_name, psd))
1595 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1596 share_name ));
1600 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1602 return WERR_OK;
1605 /*******************************************************************
1606 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1607 ********************************************************************/
1609 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1611 struct current_user user;
1612 pstring command;
1613 fstring share_name;
1614 fstring comment;
1615 pstring pathname;
1616 int type;
1617 int snum;
1618 int ret;
1619 char *ptr;
1620 SEC_DESC *psd = NULL;
1622 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1624 r_u->parm_error = 0;
1626 get_current_user(&user,p);
1628 if (user.uid != sec_initial_uid()) {
1629 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1630 return WERR_ACCESS_DENIED;
1633 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1634 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1635 return WERR_ACCESS_DENIED;
1638 switch (q_u->info_level) {
1639 case 0:
1640 /* No path. Not enough info in a level 0 to do anything. */
1641 return WERR_ACCESS_DENIED;
1642 case 1:
1643 /* Not enough info in a level 1 to do anything. */
1644 return WERR_ACCESS_DENIED;
1645 case 2:
1646 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1647 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1648 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1649 type = q_u->info.share.info2.info_2.type;
1650 break;
1651 case 501:
1652 /* No path. Not enough info in a level 501 to do anything. */
1653 return WERR_ACCESS_DENIED;
1654 case 502:
1655 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1656 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1657 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1658 type = q_u->info.share.info502.info_502.type;
1659 psd = q_u->info.share.info502.info_502_str.sd;
1660 map_generic_share_sd_bits(psd);
1661 break;
1663 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1665 case 1004:
1666 case 1005:
1667 case 1006:
1668 case 1007:
1669 return WERR_ACCESS_DENIED;
1670 break;
1671 case 1501:
1672 /* DFS only level. */
1673 return WERR_ACCESS_DENIED;
1674 default:
1675 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1676 return WERR_UNKNOWN_LEVEL;
1679 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1680 return WERR_ACCESS_DENIED;
1682 snum = find_service(share_name);
1684 /* Share already exists. */
1685 if (snum >= 0)
1686 return WERR_ALREADY_EXISTS;
1688 /* We can only add disk shares. */
1689 if (type != STYPE_DISKTREE)
1690 return WERR_ACCESS_DENIED;
1692 /* Check if the pathname is valid. */
1693 if (!(ptr = valid_share_pathname( pathname )))
1694 return WERR_OBJECT_PATH_INVALID;
1696 /* Ensure share name, pathname and comment don't contain '"' characters. */
1697 string_replace(share_name, '"', ' ');
1698 string_replace(ptr, '"', ' ');
1699 string_replace(comment, '"', ' ');
1701 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1702 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1704 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1705 if ((ret = smbrun(command, NULL)) != 0) {
1706 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1707 return WERR_ACCESS_DENIED;
1710 if (psd) {
1711 if (!set_share_security(p->mem_ctx, share_name, psd))
1712 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1713 share_name ));
1716 /* Tell everyone we updated smb.conf. */
1717 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1720 * We don't call reload_services() here, the message will
1721 * cause this to be done before the next packet is read
1722 * from the client. JRA.
1725 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1727 return WERR_OK;
1730 /*******************************************************************
1731 Net share delete. Call "delete share command" with the share name as
1732 a parameter.
1733 ********************************************************************/
1735 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1737 struct current_user user;
1738 pstring command;
1739 fstring share_name;
1740 int ret;
1741 int snum;
1743 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1745 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1747 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1748 return WERR_ACCESS_DENIED;
1750 snum = find_service(share_name);
1752 if (snum < 0)
1753 return WERR_NO_SUCH_SHARE;
1755 /* No change to printer shares. */
1756 if (lp_print_ok(snum))
1757 return WERR_ACCESS_DENIED;
1759 get_current_user(&user,p);
1761 if (user.uid != sec_initial_uid())
1762 return WERR_ACCESS_DENIED;
1764 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1765 return WERR_ACCESS_DENIED;
1767 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1768 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1770 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1771 if ((ret = smbrun(command, NULL)) != 0) {
1772 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1773 return WERR_ACCESS_DENIED;
1776 /* Delete the SD in the database. */
1777 delete_share_security(snum);
1779 /* Tell everyone we updated smb.conf. */
1780 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1782 lp_killservice(snum);
1784 return WERR_OK;
1787 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1789 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1791 return _srv_net_share_del(p, q_u, r_u);
1794 /*******************************************************************
1795 time of day
1796 ********************************************************************/
1798 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1800 TIME_OF_DAY_INFO *tod;
1801 struct tm *t;
1802 time_t unixdate = time(NULL);
1804 tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1805 if (!tod)
1806 return WERR_NOMEM;
1808 ZERO_STRUCTP(tod);
1810 r_u->tod = tod;
1811 r_u->ptr_srv_tod = 0x1;
1812 r_u->status = WERR_OK;
1814 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1816 t = gmtime(&unixdate);
1818 /* set up the */
1819 init_time_of_day_info(tod,
1820 unixdate,
1822 t->tm_hour,
1823 t->tm_min,
1824 t->tm_sec,
1826 TimeDiff(unixdate)/60,
1827 10000,
1828 t->tm_mday,
1829 t->tm_mon + 1,
1830 1900+t->tm_year,
1831 t->tm_wday);
1833 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1835 return r_u->status;
1838 /***********************************************************************************
1839 Win9x NT tools get security descriptor.
1840 ***********************************************************************************/
1842 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1843 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1845 SEC_DESC *psd = NULL;
1846 size_t sd_size;
1847 DATA_BLOB null_pw;
1848 pstring filename;
1849 pstring qualname;
1850 files_struct *fsp = NULL;
1851 SMB_STRUCT_STAT st;
1852 BOOL bad_path;
1853 int access_mode;
1854 int action;
1855 NTSTATUS nt_status;
1856 struct current_user user;
1857 connection_struct *conn = NULL;
1858 BOOL became_user = False;
1860 ZERO_STRUCT(st);
1862 r_u->status = WERR_OK;
1864 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1866 /* Null password is ok - we are already an authenticated user... */
1867 null_pw = data_blob(NULL, 0);
1869 get_current_user(&user, p);
1871 become_root();
1872 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1873 unbecome_root();
1875 if (conn == NULL) {
1876 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1877 r_u->status = ntstatus_to_werror(nt_status);
1878 goto error_exit;
1881 if (!become_user(conn, conn->vuid)) {
1882 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1883 r_u->status = WERR_ACCESS_DENIED;
1884 goto error_exit;
1886 became_user = True;
1888 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1889 unix_convert(filename, conn, NULL, &bad_path, &st);
1890 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1891 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1893 if (!fsp) {
1894 /* Perhaps it is a directory */
1895 if (errno == EISDIR)
1896 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1897 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1899 if (!fsp) {
1900 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1901 r_u->status = WERR_ACCESS_DENIED;
1902 goto error_exit;
1906 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1908 if (sd_size == 0) {
1909 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1910 r_u->status = WERR_ACCESS_DENIED;
1911 goto error_exit;
1914 r_u->ptr_response = 1;
1915 r_u->size_response = sd_size;
1916 r_u->ptr_secdesc = 1;
1917 r_u->size_secdesc = sd_size;
1918 r_u->sec_desc = psd;
1920 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1922 close_file(fsp, True);
1923 unbecome_user();
1924 close_cnum(conn, user.vuid);
1925 return r_u->status;
1927 error_exit:
1929 if(fsp) {
1930 close_file(fsp, True);
1933 if (became_user)
1934 unbecome_user();
1936 if (conn)
1937 close_cnum(conn, user.vuid);
1939 return r_u->status;
1942 /***********************************************************************************
1943 Win9x NT tools set security descriptor.
1944 ***********************************************************************************/
1946 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1947 SRV_R_NET_FILE_SET_SECDESC *r_u)
1949 BOOL ret;
1950 pstring filename;
1951 pstring qualname;
1952 DATA_BLOB null_pw;
1953 files_struct *fsp = NULL;
1954 SMB_STRUCT_STAT st;
1955 BOOL bad_path;
1956 int access_mode;
1957 int action;
1958 NTSTATUS nt_status;
1959 struct current_user user;
1960 connection_struct *conn = NULL;
1961 BOOL became_user = False;
1963 ZERO_STRUCT(st);
1965 r_u->status = WERR_OK;
1967 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1969 /* Null password is ok - we are already an authenticated user... */
1970 null_pw = data_blob(NULL, 0);
1972 get_current_user(&user, p);
1974 become_root();
1975 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1976 unbecome_root();
1978 if (conn == NULL) {
1979 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1980 r_u->status = ntstatus_to_werror(nt_status);
1981 goto error_exit;
1984 if (!become_user(conn, conn->vuid)) {
1985 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1986 r_u->status = WERR_ACCESS_DENIED;
1987 goto error_exit;
1989 became_user = True;
1991 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1992 unix_convert(filename, conn, NULL, &bad_path, &st);
1994 fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1995 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1997 if (!fsp) {
1998 /* Perhaps it is a directory */
1999 if (errno == EISDIR)
2000 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2001 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
2003 if (!fsp) {
2004 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2005 r_u->status = WERR_ACCESS_DENIED;
2006 goto error_exit;
2010 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2012 if (ret == False) {
2013 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2014 r_u->status = WERR_ACCESS_DENIED;
2015 goto error_exit;
2018 close_file(fsp, True);
2019 unbecome_user();
2020 close_cnum(conn, user.vuid);
2021 return r_u->status;
2023 error_exit:
2025 if(fsp) {
2026 close_file(fsp, True);
2029 if (became_user)
2030 unbecome_user();
2032 if (conn)
2033 close_cnum(conn, user.vuid);
2035 return r_u->status;
2038 /***********************************************************************************
2039 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2040 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2041 These disks would the disks listed by this function.
2042 Users could then create shares relative to these disks. Watch out for moving these disks around.
2043 "Nigel Williams" <nigel@veritas.com>.
2044 ***********************************************************************************/
2046 static const char *server_disks[] = {"C:"};
2048 static uint32 get_server_disk_count(void)
2050 return sizeof(server_disks)/sizeof(server_disks[0]);
2053 static uint32 init_server_disk_enum(uint32 *resume)
2055 uint32 server_disk_count = get_server_disk_count();
2057 /*resume can be an offset into the list for now*/
2059 if(*resume & 0x80000000)
2060 *resume = 0;
2062 if(*resume > server_disk_count)
2063 *resume = server_disk_count;
2065 return server_disk_count - *resume;
2068 static const char *next_server_disk_enum(uint32 *resume)
2070 const char *disk;
2072 if(init_server_disk_enum(resume) == 0)
2073 return NULL;
2075 disk = server_disks[*resume];
2077 (*resume)++;
2079 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2081 return disk;
2084 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2086 uint32 i;
2087 const char *disk_name;
2088 TALLOC_CTX *ctx = p->mem_ctx;
2089 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2091 r_u->status=WERR_OK;
2093 r_u->total_entries = init_server_disk_enum(&resume);
2095 r_u->disk_enum_ctr.unknown = 0;
2098 DISK_INFO *dinfo;
2100 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2102 if(!(dinfo = talloc(ctx, dinfo_size))) {
2103 return WERR_NOMEM;
2106 r_u->disk_enum_ctr.disk_info = dinfo;
2109 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2111 /*allow one DISK_INFO for null terminator*/
2113 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2115 r_u->disk_enum_ctr.entries_read++;
2117 /*copy disk name into a unicode string*/
2119 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2122 /* add a terminating null string. Is this there if there is more data to come? */
2124 r_u->disk_enum_ctr.entries_read++;
2126 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2128 init_enum_hnd(&r_u->enum_hnd, resume);
2130 return r_u->status;
2133 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2135 int snum;
2136 fstring share_name;
2138 r_u->status=WERR_OK;
2140 switch(q_u->type) {
2142 case 0x9:
2144 /*check if share name is ok*/
2145 /*also check if we already have a share with this name*/
2147 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2148 snum = find_service(share_name);
2150 /* Share already exists. */
2151 if (snum >= 0)
2152 r_u->status = WERR_ALREADY_EXISTS;
2153 break;
2155 default:
2156 /*unsupported type*/
2157 r_u->status = WERR_UNKNOWN_LEVEL;
2158 break;
2161 return r_u->status;