r18413: Based on the new torture test I added in samba4 it turns out
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blobc65401f1c4d52fa7ade65e898c34d50e60cb2624
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 * Copyright (C) Gerald (Jerry) Carter 2006.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* This is the implementation of the srvsvc pipe. */
26 #include "includes.h"
28 extern struct generic_mapping file_generic_mapping;
29 extern userdom_struct current_user_info;
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_SRV
34 /* Use for enumerating connections, pipes, & files */
36 struct file_enum_count {
37 TALLOC_CTX *ctx;
38 int count;
39 FILE_INFO_3 *info;
42 struct sess_file_count {
43 pid_t pid;
44 uid_t uid;
45 int count;
48 /****************************************************************************
49 Count the entries belonging to a service in the connection db.
50 ****************************************************************************/
52 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
54 struct pipe_open_rec prec;
55 struct file_enum_count *fenum = (struct file_enum_count *)p;
57 if (dbuf.dsize != sizeof(struct pipe_open_rec))
58 return 0;
60 memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
62 if ( process_exists(prec.pid) ) {
63 FILE_INFO_3 *f;
64 int i = fenum->count;
65 pstring fullpath;
67 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
69 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
70 if ( !f ) {
71 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
72 return 1;
74 fenum->info = f;
77 init_srv_file_info3( &fenum->info[i],
78 (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
79 (FILE_READ_DATA|FILE_WRITE_DATA),
81 uidtoname( prec.uid ),
82 fullpath );
84 fenum->count++;
87 return 0;
90 /*******************************************************************
91 ********************************************************************/
93 static WERROR net_enum_pipes( TALLOC_CTX *ctx, FILE_INFO_3 **info,
94 uint32 *count, uint32 resume )
96 struct file_enum_count fenum;
97 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
99 if ( !conn_tdb ) {
100 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
101 return WERR_ACCESS_DENIED;
104 fenum.ctx = ctx;
105 fenum.count = *count;
106 fenum.info = *info;
108 if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
109 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
110 tdb_errorstr(conn_tdb) ));
111 return WERR_NOMEM;
114 *info = fenum.info;
115 *count = fenum.count;
117 return WERR_OK;}
119 /*******************************************************************
120 ********************************************************************/
122 /* global needed to make use of the share_mode_forall() callback */
123 static struct file_enum_count f_enum_cnt;
125 static void enum_file_fn( const struct share_mode_entry *e,
126 const char *sharepath, const char *fname,
127 void *dummy )
129 struct file_enum_count *fenum = &f_enum_cnt;
131 /* If the pid was not found delete the entry from connections.tdb */
133 if ( process_exists(e->pid) ) {
134 FILE_INFO_3 *f;
135 int i = fenum->count;
136 files_struct fsp;
137 struct byte_range_lock *brl;
138 int num_locks = 0;
139 pstring fullpath;
140 uint32 permissions;
142 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
143 if ( !f ) {
144 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
145 return;
147 fenum->info = f;
149 /* need to count the number of locks on a file */
151 ZERO_STRUCT( fsp );
152 fsp.dev = e->dev;
153 fsp.inode = e->inode;
155 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
156 num_locks = brl->num_locks;
157 TALLOC_FREE( brl );
160 if ( strcmp( fname, "." ) == 0 ) {
161 pstr_sprintf( fullpath, "C:%s", sharepath );
162 } else {
163 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
165 string_replace( fullpath, '/', '\\' );
167 /* mask out create (what ever that is) */
168 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
170 /* now fill in the FILE_INFO_3 struct */
171 init_srv_file_info3( &fenum->info[i],
172 e->share_file_id,
173 permissions,
174 num_locks,
175 uidtoname(e->uid),
176 fullpath );
178 fenum->count++;
181 return;
185 /*******************************************************************
186 ********************************************************************/
188 static WERROR net_enum_files( TALLOC_CTX *ctx, FILE_INFO_3 **info,
189 uint32 *count, uint32 resume )
191 f_enum_cnt.ctx = ctx;
192 f_enum_cnt.count = *count;
193 f_enum_cnt.info = *info;
195 share_mode_forall( enum_file_fn, NULL );
197 *info = f_enum_cnt.info;
198 *count = f_enum_cnt.count;
200 return WERR_OK;
203 /*******************************************************************
204 Utility function to get the 'type' of a share from a share definition.
205 ********************************************************************/
206 static uint32 get_share_type(const struct share_params *params)
208 char *net_name = lp_servicename(params->service);
209 int len_net_name = strlen(net_name);
211 /* work out the share type */
212 uint32 type = STYPE_DISKTREE;
214 if (lp_print_ok(params->service))
215 type = STYPE_PRINTQ;
216 if (strequal(lp_fstype(params->service), "IPC"))
217 type = STYPE_IPC;
218 if (net_name[len_net_name] == '$')
219 type |= STYPE_HIDDEN;
221 return type;
224 /*******************************************************************
225 Fill in a share info level 0 structure.
226 ********************************************************************/
228 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0,
229 const struct share_params *params)
231 char *net_name = lp_servicename(params->service);
232 init_srv_share_info0(&sh0->info_0, net_name);
233 init_srv_share_info0_str(&sh0->info_0_str, net_name);
236 /*******************************************************************
237 Fill in a share info level 1 structure.
238 ********************************************************************/
240 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1,
241 const struct share_params *params)
243 connection_struct *conn = p->conn;
244 char *net_name = lp_servicename(params->service);
245 char *remark;
247 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
248 conn->user, conn->connectpath, conn->gid,
249 get_current_username(),
250 current_user_info.domain,
251 lp_comment(params->service));
253 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(params),
254 remark);
255 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
258 /*******************************************************************
259 Fill in a share info level 2 structure.
260 ********************************************************************/
262 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2,
263 const struct share_params *params)
265 connection_struct *conn = p->conn;
266 char *remark;
267 char *path;
268 int max_connections = lp_max_connections(params->service);
269 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
270 int count = 0;
271 char *net_name = lp_servicename(params->service);
273 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
274 conn->user, conn->connectpath, conn->gid,
275 get_current_username(),
276 current_user_info.domain,
277 lp_comment(params->service));
278 path = talloc_asprintf(p->mem_ctx, "C:%s",
279 lp_pathname(params->service));
282 * Change / to \\ so that win2k will see it as a valid path. This was
283 * added to enable use of browsing in win2k add share dialog.
286 string_replace(path, '/', '\\');
288 count = count_current_connections( net_name, False );
289 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(params),
290 remark, 0, max_uses, count, path, "");
292 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, "");
295 /*******************************************************************
296 Map any generic bits to file specific bits.
297 ********************************************************************/
299 static void map_generic_share_sd_bits(SEC_DESC *psd)
301 int i;
302 SEC_ACL *ps_dacl = NULL;
304 if (!psd)
305 return;
307 ps_dacl = psd->dacl;
308 if (!ps_dacl)
309 return;
311 for (i = 0; i < ps_dacl->num_aces; i++) {
312 SEC_ACE *psa = &ps_dacl->ace[i];
313 uint32 orig_mask = psa->info.mask;
315 se_map_generic(&psa->info.mask, &file_generic_mapping);
316 psa->info.mask |= orig_mask;
320 /*******************************************************************
321 Fill in a share info level 501 structure.
322 ********************************************************************/
324 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501,
325 const struct share_params *params)
327 connection_struct *conn = p->conn;
328 char *remark;
329 const char *net_name = lp_servicename(params->service);
331 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
332 conn->user, conn->connectpath, conn->gid,
333 get_current_username(),
334 current_user_info.domain,
335 lp_comment(params->service));
337 init_srv_share_info501(&sh501->info_501, net_name,
338 get_share_type(params), remark,
339 (lp_csc_policy(params->service) << 4));
340 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
343 /*******************************************************************
344 Fill in a share info level 502 structure.
345 ********************************************************************/
347 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502,
348 const struct share_params *params)
350 connection_struct *conn = p->conn;
351 char *net_name;
352 char *remark;
353 char *path;
354 SEC_DESC *sd;
355 size_t sd_size;
356 TALLOC_CTX *ctx = p->mem_ctx;
359 ZERO_STRUCTP(sh502);
361 net_name = lp_servicename(params->service);
363 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
364 conn->user, conn->connectpath, conn->gid,
365 get_current_username(),
366 current_user_info.domain,
367 lp_comment(params->service));
369 path = talloc_asprintf(p->mem_ctx, "C:%s",
370 lp_pathname(params->service));
373 * Change / to \\ so that win2k will see it as a valid path. This was
374 * added to enable use of browsing in win2k add share dialog.
377 string_replace(path, '/', '\\');
379 sd = get_share_security(ctx, lp_servicename(params->service),
380 &sd_size);
382 init_srv_share_info502(&sh502->info_502, net_name,
383 get_share_type(params), remark, 0, 0xffffffff,
384 1, path, "", sd, sd_size);
385 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark,
386 path, "", sd, sd_size);
389 /***************************************************************************
390 Fill in a share info level 1004 structure.
391 ***************************************************************************/
393 static void init_srv_share_info_1004(pipes_struct *p,
394 SRV_SHARE_INFO_1004* sh1004,
395 const struct share_params *params)
397 connection_struct *conn = p->conn;
398 char *remark;
400 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
401 conn->user, conn->connectpath, conn->gid,
402 get_current_username(),
403 current_user_info.domain,
404 lp_comment(params->service));
406 ZERO_STRUCTP(sh1004);
408 init_srv_share_info1004(&sh1004->info_1004, remark);
409 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
412 /***************************************************************************
413 Fill in a share info level 1005 structure.
414 ***************************************************************************/
416 static void init_srv_share_info_1005(pipes_struct *p,
417 SRV_SHARE_INFO_1005* sh1005,
418 const struct share_params *params)
420 sh1005->share_info_flags = 0;
422 if(lp_host_msdfs() && lp_msdfs_root(params->service))
423 sh1005->share_info_flags |=
424 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
425 sh1005->share_info_flags |=
426 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
428 /***************************************************************************
429 Fill in a share info level 1006 structure.
430 ***************************************************************************/
432 static void init_srv_share_info_1006(pipes_struct *p,
433 SRV_SHARE_INFO_1006* sh1006,
434 const struct share_params *params)
436 sh1006->max_uses = -1;
439 /***************************************************************************
440 Fill in a share info level 1007 structure.
441 ***************************************************************************/
443 static void init_srv_share_info_1007(pipes_struct *p,
444 SRV_SHARE_INFO_1007* sh1007,
445 const struct share_params *params)
447 pstring alternate_directory_name = "";
448 uint32 flags = 0;
450 ZERO_STRUCTP(sh1007);
452 init_srv_share_info1007(&sh1007->info_1007, flags,
453 alternate_directory_name);
454 init_srv_share_info1007_str(&sh1007->info_1007_str,
455 alternate_directory_name);
458 /*******************************************************************
459 Fill in a share info level 1501 structure.
460 ********************************************************************/
462 static void init_srv_share_info_1501(pipes_struct *p,
463 SRV_SHARE_INFO_1501 *sh1501,
464 const struct share_params *params)
466 SEC_DESC *sd;
467 size_t sd_size;
468 TALLOC_CTX *ctx = p->mem_ctx;
470 ZERO_STRUCTP(sh1501);
472 sd = get_share_security(ctx, lp_servicename(params->service),
473 &sd_size);
475 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
478 /*******************************************************************
479 True if it ends in '$'.
480 ********************************************************************/
482 static BOOL is_hidden_share(const struct share_params *params)
484 const char *net_name = lp_servicename(params->service);
486 return (net_name[strlen(net_name) - 1] == '$');
489 /*******************************************************************
490 Fill in a share info structure.
491 ********************************************************************/
493 static WERROR init_srv_share_info_ctr(pipes_struct *p,
494 SRV_SHARE_INFO_CTR *ctr,
495 uint32 info_level, uint32 *resume_hnd,
496 uint32 *total_entries, BOOL all_shares)
498 int num_entries = 0;
499 TALLOC_CTX *ctx = p->mem_ctx;
500 struct share_iterator *shares;
501 struct share_params *share;
503 DEBUG(5,("init_srv_share_info_ctr\n"));
505 ZERO_STRUCT(ctr->share);
507 ctr->info_level = ctr->switch_value = info_level;
508 *resume_hnd = 0;
510 /* Ensure all the usershares are loaded. */
511 become_root();
512 load_usershare_shares();
513 unbecome_root();
515 num_entries = 0;
517 ZERO_STRUCT(ctr->share);
519 if (!(shares = share_list_all(ctx))) {
520 DEBUG(5, ("Could not list shares\n"));
521 return WERR_ACCESS_DENIED;
524 while ((share = next_share(shares)) != NULL) {
525 if (!lp_browseable(share->service)) {
526 continue;
528 if (!all_shares && is_hidden_share(share)) {
529 continue;
532 switch (info_level) {
533 case 0:
535 SRV_SHARE_INFO_0 i;
536 init_srv_share_info_0(p, &i, share);
537 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_0, i,
538 &ctr->share.info0, &num_entries);
539 if (ctr->share.info0 == NULL) {
540 return WERR_NOMEM;
542 break;
545 case 1:
547 SRV_SHARE_INFO_1 i;
548 init_srv_share_info_1(p, &i, share);
549 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_1, i,
550 &ctr->share.info1, &num_entries);
551 if (ctr->share.info1 == NULL) {
552 return WERR_NOMEM;
554 break;
557 case 2:
559 SRV_SHARE_INFO_2 i;
560 init_srv_share_info_2(p, &i, share);
561 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_2, i,
562 &ctr->share.info2, &num_entries);
563 if (ctr->share.info2 == NULL) {
564 return WERR_NOMEM;
566 break;
569 case 501:
571 SRV_SHARE_INFO_501 i;
572 init_srv_share_info_501(p, &i, share);
573 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_501, i,
574 &ctr->share.info501, &num_entries);
575 if (ctr->share.info501 == NULL) {
576 return WERR_NOMEM;
578 break;
581 case 502:
583 SRV_SHARE_INFO_502 i;
584 init_srv_share_info_502(p, &i, share);
585 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_502, i,
586 &ctr->share.info502, &num_entries);
587 if (ctr->share.info502 == NULL) {
588 return WERR_NOMEM;
590 break;
593 /* here for completeness but not currently used with enum
594 * (1004 - 1501)*/
596 case 1004:
598 SRV_SHARE_INFO_1004 i;
599 init_srv_share_info_1004(p, &i, share);
600 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_1004, i,
601 &ctr->share.info1004, &num_entries);
602 if (ctr->share.info1004 == NULL) {
603 return WERR_NOMEM;
605 break;
608 case 1005:
610 SRV_SHARE_INFO_1005 i;
611 init_srv_share_info_1005(p, &i, share);
612 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_1005, i,
613 &ctr->share.info1005, &num_entries);
614 if (ctr->share.info1005 == NULL) {
615 return WERR_NOMEM;
617 break;
620 case 1006:
622 SRV_SHARE_INFO_1006 i;
623 init_srv_share_info_1006(p, &i, share);
624 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_1006, i,
625 &ctr->share.info1006, &num_entries);
626 if (ctr->share.info1006 == NULL) {
627 return WERR_NOMEM;
629 break;
632 case 1007:
634 SRV_SHARE_INFO_1007 i;
635 init_srv_share_info_1007(p, &i, share);
636 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_1007, i,
637 &ctr->share.info1007, &num_entries);
638 if (ctr->share.info1007 == NULL) {
639 return WERR_NOMEM;
641 break;
644 case 1501:
646 SRV_SHARE_INFO_1501 i;
647 init_srv_share_info_1501(p, &i, share);
648 ADD_TO_ARRAY(ctx, SRV_SHARE_INFO_1501, i,
649 &ctr->share.info1501, &num_entries);
650 if (ctr->share.info1501 == NULL) {
651 return WERR_NOMEM;
653 break;
655 default:
656 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
657 "value %d\n", info_level));
658 return WERR_UNKNOWN_LEVEL;
661 TALLOC_FREE(share);
664 *total_entries = num_entries;
665 ctr->num_entries2 = ctr->num_entries = num_entries;
666 ctr->ptr_share_info = ctr->ptr_entries = 1;
668 return WERR_OK;
671 /*******************************************************************
672 Inits a SRV_R_NET_SHARE_ENUM structure.
673 ********************************************************************/
675 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
676 uint32 info_level, uint32 resume_hnd, BOOL all)
678 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
680 r_n->status = init_srv_share_info_ctr(p, &r_n->ctr, info_level,
681 &resume_hnd,
682 &r_n->total_entries, all);
684 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
687 /*******************************************************************
688 Inits a SRV_R_NET_SHARE_GET_INFO structure.
689 ********************************************************************/
691 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
692 char *share_name, uint32 info_level)
694 WERROR status = WERR_OK;
695 const struct share_params *params;
697 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
699 r_n->info.switch_value = info_level;
701 params = get_share_params(p->mem_ctx, share_name);
703 if (params != NULL) {
704 switch (info_level) {
705 case 0:
706 init_srv_share_info_0(p, &r_n->info.share.info0,
707 params);
708 break;
709 case 1:
710 init_srv_share_info_1(p, &r_n->info.share.info1,
711 params);
712 break;
713 case 2:
714 init_srv_share_info_2(p, &r_n->info.share.info2,
715 params);
716 break;
717 case 501:
718 init_srv_share_info_501(p, &r_n->info.share.info501,
719 params);
720 break;
721 case 502:
722 init_srv_share_info_502(p, &r_n->info.share.info502,
723 params);
724 break;
726 /* here for completeness */
727 case 1004:
728 init_srv_share_info_1004(p, &r_n->info.share.info1004,
729 params);
730 break;
731 case 1005:
732 init_srv_share_info_1005(p, &r_n->info.share.info1005,
733 params);
734 break;
736 /* here for completeness 1006 - 1501 */
737 case 1006:
738 init_srv_share_info_1006(p, &r_n->info.share.info1006,
739 params);
740 break;
741 case 1007:
742 init_srv_share_info_1007(p, &r_n->info.share.info1007,
743 params);
744 break;
745 case 1501:
746 init_srv_share_info_1501(p, &r_n->info.share.info1501,
747 params);
748 break;
749 default:
750 DEBUG(5,("init_srv_net_share_get_info: unsupported "
751 "switch value %d\n", info_level));
752 status = WERR_UNKNOWN_LEVEL;
753 break;
755 } else {
756 status = WERR_INVALID_NAME;
759 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
760 r_n->status = status;
763 /*******************************************************************
764 fill in a sess info level 0 structure.
765 ********************************************************************/
767 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
769 struct sessionid *session_list;
770 uint32 num_entries = 0;
771 (*stot) = list_sessions(&session_list);
773 if (ss0 == NULL) {
774 if (snum) {
775 (*snum) = 0;
777 SAFE_FREE(session_list);
778 return;
781 DEBUG(5,("init_srv_sess_0_ss0\n"));
783 if (snum) {
784 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
785 init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
786 num_entries++;
789 ss0->num_entries_read = num_entries;
790 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
791 ss0->num_entries_read2 = num_entries;
793 if ((*snum) >= (*stot)) {
794 (*snum) = 0;
797 } else {
798 ss0->num_entries_read = 0;
799 ss0->ptr_sess_info = 0;
800 ss0->num_entries_read2 = 0;
802 SAFE_FREE(session_list);
805 /*******************************************************************
806 ********************************************************************/
808 static void sess_file_fn( const struct share_mode_entry *e,
809 const char *sharepath, const char *fname,
810 void *private_data )
812 struct sess_file_count *sess = (struct sess_file_count *)private_data;
814 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
815 sess->count++;
818 return;
821 /*******************************************************************
822 ********************************************************************/
824 static int net_count_files( uid_t uid, pid_t pid )
826 struct sess_file_count s_file_cnt;
828 s_file_cnt.count = 0;
829 s_file_cnt.uid = uid;
830 s_file_cnt.pid = pid;
832 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
834 return s_file_cnt.count;
837 /*******************************************************************
838 fill in a sess info level 1 structure.
839 ********************************************************************/
841 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
843 struct sessionid *session_list;
844 uint32 num_entries = 0;
845 time_t now = time(NULL);
847 if ( !snum ) {
848 ss1->num_entries_read = 0;
849 ss1->ptr_sess_info = 0;
850 ss1->num_entries_read2 = 0;
852 (*stot) = 0;
854 return;
857 if (ss1 == NULL) {
858 (*snum) = 0;
859 return;
862 (*stot) = list_sessions(&session_list);
865 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
866 uint32 num_files;
867 uint32 connect_time;
868 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
869 BOOL guest;
871 if ( !pw ) {
872 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
873 session_list[*snum].username));
874 continue;
877 connect_time = (uint32)(now - session_list[*snum].connect_start);
878 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
879 guest = strequal( session_list[*snum].username, lp_guestaccount() );
881 init_srv_sess_info1( &ss1->info_1[num_entries],
882 session_list[*snum].remote_machine,
883 session_list[*snum].username,
884 num_files,
885 connect_time,
887 guest);
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 SAFE_FREE(session_list);
902 /*******************************************************************
903 makes a SRV_R_NET_SESS_ENUM structure.
904 ********************************************************************/
906 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
907 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
909 WERROR status = WERR_OK;
910 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
912 ctr->switch_value = switch_value;
914 switch (switch_value) {
915 case 0:
916 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
917 ctr->ptr_sess_ctr = 1;
918 break;
919 case 1:
920 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
921 ctr->ptr_sess_ctr = 1;
922 break;
923 default:
924 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
925 (*resume_hnd) = 0;
926 (*total_entries) = 0;
927 ctr->ptr_sess_ctr = 0;
928 status = WERR_UNKNOWN_LEVEL;
929 break;
932 return status;
935 /*******************************************************************
936 makes a SRV_R_NET_SESS_ENUM structure.
937 ********************************************************************/
939 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
940 uint32 resume_hnd, int sess_level, int switch_value)
942 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
944 r_n->sess_level = sess_level;
946 if (sess_level == -1)
947 r_n->status = WERR_UNKNOWN_LEVEL;
948 else
949 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
951 if (!W_ERROR_IS_OK(r_n->status))
952 resume_hnd = 0;
954 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
957 /*******************************************************************
958 fill in a conn info level 0 structure.
959 ********************************************************************/
961 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
963 uint32 num_entries = 0;
964 (*stot) = 1;
966 if (ss0 == NULL) {
967 (*snum) = 0;
968 return;
971 DEBUG(5,("init_srv_conn_0_ss0\n"));
973 if (snum) {
974 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
976 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
978 /* move on to creating next connection */
979 /* move on to creating next conn */
980 num_entries++;
983 ss0->num_entries_read = num_entries;
984 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
985 ss0->num_entries_read2 = num_entries;
987 if ((*snum) >= (*stot)) {
988 (*snum) = 0;
991 } else {
992 ss0->num_entries_read = 0;
993 ss0->ptr_conn_info = 0;
994 ss0->num_entries_read2 = 0;
996 (*stot) = 0;
1000 /*******************************************************************
1001 fill in a conn info level 1 structure.
1002 ********************************************************************/
1004 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1005 uint32 id, uint32 type,
1006 uint32 num_opens, uint32 num_users, uint32 open_time,
1007 const char *usr_name, const char *net_name)
1009 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1010 init_srv_conn_info1_str(str1, usr_name, net_name);
1013 /*******************************************************************
1014 fill in a conn info level 1 structure.
1015 ********************************************************************/
1017 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1019 uint32 num_entries = 0;
1020 (*stot) = 1;
1022 if (ss1 == NULL) {
1023 (*snum) = 0;
1024 return;
1027 DEBUG(5,("init_srv_conn_1_ss1\n"));
1029 if (snum) {
1030 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1031 init_srv_conn_1_info(&ss1->info_1[num_entries],
1032 &ss1->info_1_str[num_entries],
1033 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1035 /* move on to creating next connection */
1036 /* move on to creating next conn */
1037 num_entries++;
1040 ss1->num_entries_read = num_entries;
1041 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1042 ss1->num_entries_read2 = num_entries;
1045 if ((*snum) >= (*stot)) {
1046 (*snum) = 0;
1049 } else {
1050 ss1->num_entries_read = 0;
1051 ss1->ptr_conn_info = 0;
1052 ss1->num_entries_read2 = 0;
1054 (*stot) = 0;
1058 /*******************************************************************
1059 makes a SRV_R_NET_CONN_ENUM structure.
1060 ********************************************************************/
1062 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1063 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1065 WERROR status = WERR_OK;
1066 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1068 ctr->switch_value = switch_value;
1070 switch (switch_value) {
1071 case 0:
1072 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1073 ctr->ptr_conn_ctr = 1;
1074 break;
1075 case 1:
1076 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1077 ctr->ptr_conn_ctr = 1;
1078 break;
1079 default:
1080 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1081 (*resume_hnd = 0);
1082 (*total_entries) = 0;
1083 ctr->ptr_conn_ctr = 0;
1084 status = WERR_UNKNOWN_LEVEL;
1085 break;
1088 return status;
1091 /*******************************************************************
1092 makes a SRV_R_NET_CONN_ENUM structure.
1093 ********************************************************************/
1095 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1096 uint32 resume_hnd, int conn_level, int switch_value)
1098 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1100 r_n->conn_level = conn_level;
1101 if (conn_level == -1)
1102 r_n->status = WERR_UNKNOWN_LEVEL;
1103 else
1104 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1106 if (!W_ERROR_IS_OK(r_n->status))
1107 resume_hnd = 0;
1109 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1112 /*******************************************************************
1113 makes a SRV_R_NET_FILE_ENUM structure.
1114 ********************************************************************/
1116 static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1118 TALLOC_CTX *ctx = get_talloc_ctx();
1119 SRV_FILE_INFO_CTR *ctr = &r->ctr;
1121 /* TODO -- Windows enumerates
1122 (b) active pipes
1123 (c) open directories and files */
1125 r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1126 if ( !W_ERROR_IS_OK(r->status))
1127 goto done;
1129 r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1130 if ( !W_ERROR_IS_OK(r->status))
1131 goto done;
1133 r->level = ctr->level = 3;
1134 r->total_entries = ctr->num_entries;
1135 /* ctr->num_entries = r->total_entries - resume_hnd; */
1136 ctr->num_entries2 = ctr->num_entries;
1137 ctr->ptr_file_info = 1;
1139 r->status = WERR_OK;
1141 done:
1142 if ( ctr->num_entries > 0 )
1143 ctr->ptr_entries = 1;
1145 init_enum_hnd(&r->enum_hnd, 0);
1147 return r->status;
1150 /*******************************************************************
1151 *******************************************************************/
1153 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1155 switch ( q_u->level ) {
1156 case 3:
1157 return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );
1158 default:
1159 return WERR_UNKNOWN_LEVEL;
1162 return WERR_OK;
1165 /*******************************************************************
1166 net server get info
1167 ********************************************************************/
1169 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)
1171 WERROR status = WERR_OK;
1172 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1174 if (!ctr)
1175 return WERR_NOMEM;
1177 ZERO_STRUCTP(ctr);
1179 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1181 if (!pipe_access_check(p)) {
1182 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1183 return WERR_ACCESS_DENIED;
1186 switch (q_u->switch_value) {
1188 /* Technically level 102 should only be available to
1189 Administrators but there isn't anything super-secret
1190 here, as most of it is made up. */
1192 case 102:
1193 init_srv_info_102(&ctr->srv.sv102,
1194 500, global_myname(),
1195 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1196 lp_major_announce_version(), lp_minor_announce_version(),
1197 lp_default_server_announce(),
1198 0xffffffff, /* users */
1199 0xf, /* disc */
1200 0, /* hidden */
1201 240, /* announce */
1202 3000, /* announce delta */
1203 100000, /* licenses */
1204 "c:\\"); /* user path */
1205 break;
1206 case 101:
1207 init_srv_info_101(&ctr->srv.sv101,
1208 500, global_myname(),
1209 lp_major_announce_version(), lp_minor_announce_version(),
1210 lp_default_server_announce(),
1211 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1212 break;
1213 case 100:
1214 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1215 break;
1216 default:
1217 status = WERR_UNKNOWN_LEVEL;
1218 break;
1221 /* set up the net server get info structure */
1222 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1224 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1226 return r_u->status;
1229 /*******************************************************************
1230 net server set info
1231 ********************************************************************/
1233 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)
1235 WERROR status = WERR_OK;
1237 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1239 /* Set up the net server set info structure. */
1241 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1243 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1245 return r_u->status;
1248 /*******************************************************************
1249 net conn enum
1250 ********************************************************************/
1252 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1254 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1256 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1257 if (!r_u->ctr)
1258 return WERR_NOMEM;
1260 ZERO_STRUCTP(r_u->ctr);
1262 /* set up the */
1263 init_srv_r_net_conn_enum(r_u,
1264 get_enum_hnd(&q_u->enum_hnd),
1265 q_u->conn_level,
1266 q_u->ctr->switch_value);
1268 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1270 return r_u->status;
1273 /*******************************************************************
1274 net sess enum
1275 ********************************************************************/
1277 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1279 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1281 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1282 if (!r_u->ctr)
1283 return WERR_NOMEM;
1285 ZERO_STRUCTP(r_u->ctr);
1287 /* set up the */
1288 init_srv_r_net_sess_enum(r_u,
1289 get_enum_hnd(&q_u->enum_hnd),
1290 q_u->sess_level,
1291 q_u->ctr->switch_value);
1293 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1295 return r_u->status;
1298 /*******************************************************************
1299 net sess del
1300 ********************************************************************/
1302 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1304 struct sessionid *session_list;
1305 int num_sessions, snum;
1306 fstring username;
1307 fstring machine;
1309 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1310 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1312 /* strip leading backslashes if any */
1313 while (machine[0] == '\\') {
1314 memmove(machine, &machine[1], strlen(machine));
1317 num_sessions = list_sessions(&session_list);
1319 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1321 r_u->status = WERR_ACCESS_DENIED;
1323 /* fail out now if you are not root or not a domain admin */
1325 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1326 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1328 goto done;
1331 for (snum = 0; snum < num_sessions; snum++) {
1333 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1334 strequal(session_list[snum].remote_machine, machine)) {
1336 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1337 r_u->status = WERR_OK;
1341 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1344 done:
1345 SAFE_FREE(session_list);
1347 return r_u->status;
1350 /*******************************************************************
1351 Net share enum all.
1352 ********************************************************************/
1354 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1356 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1358 if (!pipe_access_check(p)) {
1359 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1360 return WERR_ACCESS_DENIED;
1363 /* Create the list of shares for the response. */
1364 init_srv_r_net_share_enum(p, r_u,
1365 q_u->ctr.info_level,
1366 get_enum_hnd(&q_u->enum_hnd), True);
1368 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1370 return r_u->status;
1373 /*******************************************************************
1374 Net share enum.
1375 ********************************************************************/
1377 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1379 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1381 if (!pipe_access_check(p)) {
1382 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1383 return WERR_ACCESS_DENIED;
1386 /* Create the list of shares for the response. */
1387 init_srv_r_net_share_enum(p, r_u,
1388 q_u->ctr.info_level,
1389 get_enum_hnd(&q_u->enum_hnd), False);
1391 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1393 return r_u->status;
1396 /*******************************************************************
1397 Net share get info.
1398 ********************************************************************/
1400 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)
1402 fstring share_name;
1404 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1406 /* Create the list of shares for the response. */
1407 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1408 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1410 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1412 return r_u->status;
1415 /*******************************************************************
1416 Check a given DOS pathname is valid for a share.
1417 ********************************************************************/
1419 char *valid_share_pathname(char *dos_pathname)
1421 char *ptr;
1423 /* Convert any '\' paths to '/' */
1424 unix_format(dos_pathname);
1425 unix_clean_name(dos_pathname);
1427 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1428 ptr = dos_pathname;
1429 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1430 ptr += 2;
1432 /* Only absolute paths allowed. */
1433 if (*ptr != '/')
1434 return NULL;
1436 return ptr;
1439 /*******************************************************************
1440 Net share set info. Modify share details.
1441 ********************************************************************/
1443 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)
1445 pstring command;
1446 fstring share_name;
1447 fstring comment;
1448 pstring pathname;
1449 int type;
1450 int snum;
1451 int ret;
1452 char *path;
1453 SEC_DESC *psd = NULL;
1454 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1455 BOOL is_disk_op = False;
1456 int max_connections = 0;
1458 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1460 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1462 r_u->parm_error = 0;
1464 if ( strequal(share_name,"IPC$")
1465 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1466 || strequal(share_name,"global") )
1468 return WERR_ACCESS_DENIED;
1471 snum = find_service(share_name);
1473 /* Does this share exist ? */
1474 if (snum < 0)
1475 return WERR_NET_NAME_NOT_FOUND;
1477 /* No change to printer shares. */
1478 if (lp_print_ok(snum))
1479 return WERR_ACCESS_DENIED;
1481 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1483 /* fail out now if you are not root and not a disk op */
1485 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1486 return WERR_ACCESS_DENIED;
1488 switch (q_u->info_level) {
1489 case 1:
1490 pstrcpy(pathname, lp_pathname(snum));
1491 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1492 type = q_u->info.share.info2.info_2.type;
1493 psd = NULL;
1494 break;
1495 case 2:
1496 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1497 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1498 type = q_u->info.share.info2.info_2.type;
1499 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1500 psd = NULL;
1501 break;
1502 #if 0
1503 /* not supported on set but here for completeness */
1504 case 501:
1505 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1506 type = q_u->info.share.info501.info_501.type;
1507 psd = NULL;
1508 break;
1509 #endif
1510 case 502:
1511 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1512 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1513 type = q_u->info.share.info502.info_502.type;
1514 psd = q_u->info.share.info502.info_502_str.sd;
1515 map_generic_share_sd_bits(psd);
1516 break;
1517 case 1004:
1518 pstrcpy(pathname, lp_pathname(snum));
1519 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1520 type = STYPE_DISKTREE;
1521 break;
1522 case 1005:
1523 /* XP re-sets the csc policy even if it wasn't changed by the
1524 user, so we must compare it to see if it's what is set in
1525 smb.conf, so that we can contine other ops like setting
1526 ACLs on a share */
1527 if (((q_u->info.share.info1005.share_info_flags &
1528 SHARE_1005_CSC_POLICY_MASK) >>
1529 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1530 return WERR_OK;
1531 else {
1532 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1533 return WERR_ACCESS_DENIED;
1535 case 1006:
1536 case 1007:
1537 return WERR_ACCESS_DENIED;
1538 case 1501:
1539 pstrcpy(pathname, lp_pathname(snum));
1540 fstrcpy(comment, lp_comment(snum));
1541 psd = q_u->info.share.info1501.sdb->sec;
1542 map_generic_share_sd_bits(psd);
1543 type = STYPE_DISKTREE;
1544 break;
1545 default:
1546 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1547 return WERR_UNKNOWN_LEVEL;
1550 /* We can only modify disk shares. */
1551 if (type != STYPE_DISKTREE)
1552 return WERR_ACCESS_DENIED;
1554 /* Check if the pathname is valid. */
1555 if (!(path = valid_share_pathname( pathname )))
1556 return WERR_OBJECT_PATH_INVALID;
1558 /* Ensure share name, pathname and comment don't contain '"' characters. */
1559 string_replace(share_name, '"', ' ');
1560 string_replace(path, '"', ' ');
1561 string_replace(comment, '"', ' ');
1563 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1564 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1566 /* Only call modify function if something changed. */
1568 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1569 || (lp_max_connections(snum) != max_connections) )
1571 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1572 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1573 return WERR_ACCESS_DENIED;
1576 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1577 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1579 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1581 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1583 if ( is_disk_op )
1584 become_root();
1586 if ( (ret = smbrun(command, NULL)) == 0 ) {
1587 /* Tell everyone we updated smb.conf. */
1588 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1591 if ( is_disk_op )
1592 unbecome_root();
1594 /********* END SeDiskOperatorPrivilege BLOCK *********/
1596 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1598 if ( ret != 0 )
1599 return WERR_ACCESS_DENIED;
1600 } else {
1601 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1604 /* Replace SD if changed. */
1605 if (psd) {
1606 SEC_DESC *old_sd;
1607 size_t sd_size;
1609 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1610 &sd_size);
1612 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1613 if (!set_share_security(p->mem_ctx, share_name, psd))
1614 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1615 share_name ));
1619 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1621 return WERR_OK;
1624 /*******************************************************************
1625 Net share add. Call 'add_share_command "sharename" "pathname"
1626 "comment" "max connections = "
1627 ********************************************************************/
1629 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1631 pstring command;
1632 fstring share_name;
1633 fstring comment;
1634 pstring pathname;
1635 int type;
1636 int snum;
1637 int ret;
1638 char *path;
1639 SEC_DESC *psd = NULL;
1640 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1641 BOOL is_disk_op;
1642 int max_connections = 0;
1644 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1646 r_u->parm_error = 0;
1648 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1650 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1651 return WERR_ACCESS_DENIED;
1653 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1654 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1655 return WERR_ACCESS_DENIED;
1658 switch (q_u->info_level) {
1659 case 0:
1660 /* No path. Not enough info in a level 0 to do anything. */
1661 return WERR_ACCESS_DENIED;
1662 case 1:
1663 /* Not enough info in a level 1 to do anything. */
1664 return WERR_ACCESS_DENIED;
1665 case 2:
1666 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1667 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1668 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1669 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1670 type = q_u->info.share.info2.info_2.type;
1671 break;
1672 case 501:
1673 /* No path. Not enough info in a level 501 to do anything. */
1674 return WERR_ACCESS_DENIED;
1675 case 502:
1676 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1677 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1678 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1679 type = q_u->info.share.info502.info_502.type;
1680 psd = q_u->info.share.info502.info_502_str.sd;
1681 map_generic_share_sd_bits(psd);
1682 break;
1684 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1686 case 1004:
1687 case 1005:
1688 case 1006:
1689 case 1007:
1690 return WERR_ACCESS_DENIED;
1691 case 1501:
1692 /* DFS only level. */
1693 return WERR_ACCESS_DENIED;
1694 default:
1695 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1696 return WERR_UNKNOWN_LEVEL;
1699 /* check for invalid share names */
1701 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1702 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1703 return WERR_INVALID_NAME;
1706 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1707 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1709 return WERR_ACCESS_DENIED;
1712 snum = find_service(share_name);
1714 /* Share already exists. */
1715 if (snum >= 0)
1716 return WERR_ALREADY_EXISTS;
1718 /* We can only add disk shares. */
1719 if (type != STYPE_DISKTREE)
1720 return WERR_ACCESS_DENIED;
1722 /* Check if the pathname is valid. */
1723 if (!(path = valid_share_pathname( pathname )))
1724 return WERR_OBJECT_PATH_INVALID;
1726 /* Ensure share name, pathname and comment don't contain '"' characters. */
1727 string_replace(share_name, '"', ' ');
1728 string_replace(path, '"', ' ');
1729 string_replace(comment, '"', ' ');
1731 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1732 lp_add_share_cmd(),
1733 dyn_CONFIGFILE,
1734 share_name,
1735 path,
1736 comment,
1737 max_connections);
1739 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1741 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1743 if ( is_disk_op )
1744 become_root();
1746 if ( (ret = smbrun(command, NULL)) == 0 ) {
1747 /* Tell everyone we updated smb.conf. */
1748 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1751 if ( is_disk_op )
1752 unbecome_root();
1754 /********* END SeDiskOperatorPrivilege BLOCK *********/
1756 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1758 if ( ret != 0 )
1759 return WERR_ACCESS_DENIED;
1761 if (psd) {
1762 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1763 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1768 * We don't call reload_services() here, the message will
1769 * cause this to be done before the next packet is read
1770 * from the client. JRA.
1773 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1775 return WERR_OK;
1778 /*******************************************************************
1779 Net share delete. Call "delete share command" with the share name as
1780 a parameter.
1781 ********************************************************************/
1783 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1785 pstring command;
1786 fstring share_name;
1787 int ret;
1788 int snum;
1789 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1790 BOOL is_disk_op;
1792 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1794 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1796 if ( strequal(share_name,"IPC$")
1797 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1798 || strequal(share_name,"global") )
1800 return WERR_ACCESS_DENIED;
1803 snum = find_service(share_name);
1805 if (snum < 0)
1806 return WERR_NO_SUCH_SHARE;
1808 /* No change to printer shares. */
1809 if (lp_print_ok(snum))
1810 return WERR_ACCESS_DENIED;
1812 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1814 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1815 return WERR_ACCESS_DENIED;
1817 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1818 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1819 return WERR_ACCESS_DENIED;
1822 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1823 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1825 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1827 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1829 if ( is_disk_op )
1830 become_root();
1832 if ( (ret = smbrun(command, NULL)) == 0 ) {
1833 /* Tell everyone we updated smb.conf. */
1834 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1837 if ( is_disk_op )
1838 unbecome_root();
1840 /********* END SeDiskOperatorPrivilege BLOCK *********/
1842 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1844 if ( ret != 0 )
1845 return WERR_ACCESS_DENIED;
1847 /* Delete the SD in the database. */
1848 delete_share_security(snum);
1850 lp_killservice(snum);
1852 return WERR_OK;
1855 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1857 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1859 return _srv_net_share_del(p, q_u, r_u);
1862 /*******************************************************************
1863 time of day
1864 ********************************************************************/
1866 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1868 TIME_OF_DAY_INFO *tod;
1869 struct tm *t;
1870 time_t unixdate = time(NULL);
1872 /* We do this call first as if we do it *after* the gmtime call
1873 it overwrites the pointed-to values. JRA */
1875 uint32 zone = get_time_zone(unixdate)/60;
1877 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1879 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1880 return WERR_NOMEM;
1882 r_u->tod = tod;
1883 r_u->ptr_srv_tod = 0x1;
1884 r_u->status = WERR_OK;
1886 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1888 t = gmtime(&unixdate);
1890 /* set up the */
1891 init_time_of_day_info(tod,
1892 unixdate,
1894 t->tm_hour,
1895 t->tm_min,
1896 t->tm_sec,
1898 zone,
1899 10000,
1900 t->tm_mday,
1901 t->tm_mon + 1,
1902 1900+t->tm_year,
1903 t->tm_wday);
1905 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1907 return r_u->status;
1910 /***********************************************************************************
1911 Win9x NT tools get security descriptor.
1912 ***********************************************************************************/
1914 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1915 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1917 SEC_DESC *psd = NULL;
1918 size_t sd_size;
1919 DATA_BLOB null_pw;
1920 pstring filename;
1921 pstring qualname;
1922 files_struct *fsp = NULL;
1923 SMB_STRUCT_STAT st;
1924 BOOL bad_path;
1925 NTSTATUS nt_status;
1926 connection_struct *conn = NULL;
1927 BOOL became_user = False;
1929 ZERO_STRUCT(st);
1931 r_u->status = WERR_OK;
1933 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1935 /* Null password is ok - we are already an authenticated user... */
1936 null_pw = data_blob(NULL, 0);
1938 become_root();
1939 conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1940 unbecome_root();
1942 if (conn == NULL) {
1943 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1944 r_u->status = ntstatus_to_werror(nt_status);
1945 goto error_exit;
1948 if (!become_user(conn, conn->vuid)) {
1949 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1950 r_u->status = WERR_ACCESS_DENIED;
1951 goto error_exit;
1953 became_user = True;
1955 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1956 unix_convert(filename, conn, NULL, &bad_path, &st);
1957 if (bad_path) {
1958 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1959 r_u->status = WERR_ACCESS_DENIED;
1960 goto error_exit;
1963 if (!check_name(filename,conn)) {
1964 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
1965 r_u->status = WERR_ACCESS_DENIED;
1966 goto error_exit;
1969 nt_status = open_file_stat(conn, filename, &st, &fsp);
1970 if (!NT_STATUS_IS_OK(nt_status)) {
1971 /* Perhaps it is a directory */
1972 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1973 nt_status = open_directory(conn, filename, &st,
1974 READ_CONTROL_ACCESS,
1975 FILE_SHARE_READ|FILE_SHARE_WRITE,
1976 FILE_OPEN,
1978 NULL, &fsp);
1980 if (!NT_STATUS_IS_OK(nt_status)) {
1981 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1982 r_u->status = WERR_ACCESS_DENIED;
1983 goto error_exit;
1987 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1989 if (sd_size == 0) {
1990 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1991 r_u->status = WERR_ACCESS_DENIED;
1992 goto error_exit;
1995 r_u->ptr_response = 1;
1996 r_u->size_response = sd_size;
1997 r_u->ptr_secdesc = 1;
1998 r_u->size_secdesc = sd_size;
1999 r_u->sec_desc = psd;
2001 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2003 close_file(fsp, NORMAL_CLOSE);
2004 unbecome_user();
2005 close_cnum(conn, p->pipe_user.vuid);
2006 return r_u->status;
2008 error_exit:
2010 if(fsp) {
2011 close_file(fsp, NORMAL_CLOSE);
2014 if (became_user)
2015 unbecome_user();
2017 if (conn)
2018 close_cnum(conn, p->pipe_user.vuid);
2020 return r_u->status;
2023 /***********************************************************************************
2024 Win9x NT tools set security descriptor.
2025 ***********************************************************************************/
2027 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2028 SRV_R_NET_FILE_SET_SECDESC *r_u)
2030 BOOL ret;
2031 pstring filename;
2032 pstring qualname;
2033 DATA_BLOB null_pw;
2034 files_struct *fsp = NULL;
2035 SMB_STRUCT_STAT st;
2036 BOOL bad_path;
2037 NTSTATUS nt_status;
2038 connection_struct *conn = NULL;
2039 BOOL became_user = False;
2041 ZERO_STRUCT(st);
2043 r_u->status = WERR_OK;
2045 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2047 /* Null password is ok - we are already an authenticated user... */
2048 null_pw = data_blob(NULL, 0);
2050 become_root();
2051 conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2052 unbecome_root();
2054 if (conn == NULL) {
2055 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2056 r_u->status = ntstatus_to_werror(nt_status);
2057 goto error_exit;
2060 if (!become_user(conn, conn->vuid)) {
2061 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2062 r_u->status = WERR_ACCESS_DENIED;
2063 goto error_exit;
2065 became_user = True;
2067 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2068 unix_convert(filename, conn, NULL, &bad_path, &st);
2069 if (bad_path) {
2070 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2071 r_u->status = WERR_ACCESS_DENIED;
2072 goto error_exit;
2075 if (!check_name(filename,conn)) {
2076 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2077 r_u->status = WERR_ACCESS_DENIED;
2078 goto error_exit;
2082 nt_status = open_file_stat(conn, filename, &st, &fsp);
2084 if (!NT_STATUS_IS_OK(nt_status)) {
2085 /* Perhaps it is a directory */
2086 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2087 nt_status = open_directory(conn, filename, &st,
2088 FILE_READ_ATTRIBUTES,
2089 FILE_SHARE_READ|FILE_SHARE_WRITE,
2090 FILE_OPEN,
2092 NULL, &fsp);
2094 if (!NT_STATUS_IS_OK(nt_status)) {
2095 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2096 r_u->status = WERR_ACCESS_DENIED;
2097 goto error_exit;
2101 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2103 if (ret == False) {
2104 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2105 r_u->status = WERR_ACCESS_DENIED;
2106 goto error_exit;
2109 close_file(fsp, NORMAL_CLOSE);
2110 unbecome_user();
2111 close_cnum(conn, p->pipe_user.vuid);
2112 return r_u->status;
2114 error_exit:
2116 if(fsp) {
2117 close_file(fsp, NORMAL_CLOSE);
2120 if (became_user) {
2121 unbecome_user();
2124 if (conn) {
2125 close_cnum(conn, p->pipe_user.vuid);
2128 return r_u->status;
2131 /***********************************************************************************
2132 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2133 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2134 These disks would the disks listed by this function.
2135 Users could then create shares relative to these disks. Watch out for moving these disks around.
2136 "Nigel Williams" <nigel@veritas.com>.
2137 ***********************************************************************************/
2139 static const char *server_disks[] = {"C:"};
2141 static uint32 get_server_disk_count(void)
2143 return sizeof(server_disks)/sizeof(server_disks[0]);
2146 static uint32 init_server_disk_enum(uint32 *resume)
2148 uint32 server_disk_count = get_server_disk_count();
2150 /*resume can be an offset into the list for now*/
2152 if(*resume & 0x80000000)
2153 *resume = 0;
2155 if(*resume > server_disk_count)
2156 *resume = server_disk_count;
2158 return server_disk_count - *resume;
2161 static const char *next_server_disk_enum(uint32 *resume)
2163 const char *disk;
2165 if(init_server_disk_enum(resume) == 0)
2166 return NULL;
2168 disk = server_disks[*resume];
2170 (*resume)++;
2172 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2174 return disk;
2177 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2179 uint32 i;
2180 const char *disk_name;
2181 TALLOC_CTX *ctx = p->mem_ctx;
2182 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2184 r_u->status=WERR_OK;
2186 r_u->total_entries = init_server_disk_enum(&resume);
2188 r_u->disk_enum_ctr.unknown = 0;
2190 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2191 return WERR_NOMEM;
2194 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2196 /*allow one DISK_INFO for null terminator*/
2198 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2200 r_u->disk_enum_ctr.entries_read++;
2202 /*copy disk name into a unicode string*/
2204 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2207 /* add a terminating null string. Is this there if there is more data to come? */
2209 r_u->disk_enum_ctr.entries_read++;
2211 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2213 init_enum_hnd(&r_u->enum_hnd, resume);
2215 return r_u->status;
2218 /********************************************************************
2219 ********************************************************************/
2221 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2223 fstring sharename;
2224 int len;
2226 if ((q_u->flags != 0x0) && (q_u->flags != 0x80000000)) {
2227 return WERR_INVALID_PARAM;
2230 switch ( q_u->type ) {
2231 case 0x9:
2232 rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2234 len = strlen_m(sharename);
2236 if ((q_u->flags == 0x0) && (len > 81)) {
2237 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", sharename));
2238 return WERR_INVALID_NAME;
2240 if ((q_u->flags == 0x80000000) && (len > 13)) {
2241 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", sharename));
2242 return WERR_INVALID_NAME;
2245 if ( ! validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2246 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2247 return WERR_INVALID_NAME;
2249 break;
2251 default:
2252 return WERR_UNKNOWN_LEVEL;
2255 return WERR_OK;
2259 /********************************************************************
2260 ********************************************************************/
2262 WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2264 return WERR_ACCESS_DENIED;