Samba 3.0.37 update: unpatched sources
[tomato.git] / release / src / router / samba3 / source / rpc_server / srv_srvsvc_nt.c
blob173979f8c68b83602e92a3dd032eda40ed36dadc
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;
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
33 /* Use for enumerating connections, pipes, & files */
35 struct file_enum_count {
36 TALLOC_CTX *ctx;
37 int count;
38 FILE_INFO_3 *info;
41 struct sess_file_count {
42 pid_t pid;
43 uid_t uid;
44 int count;
47 /****************************************************************************
48 Count the entries belonging to a service in the connection db.
49 ****************************************************************************/
51 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
53 struct pipe_open_rec prec;
54 struct file_enum_count *fenum = (struct file_enum_count *)p;
56 if (dbuf.dsize != sizeof(struct pipe_open_rec))
57 return 0;
59 memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
61 if ( process_exists(prec.pid) ) {
62 FILE_INFO_3 *f;
63 int i = fenum->count;
64 pstring fullpath;
66 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
68 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
69 if ( !f ) {
70 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
71 return 1;
73 fenum->info = f;
76 init_srv_file_info3( &fenum->info[i],
77 (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
78 (FILE_READ_DATA|FILE_WRITE_DATA),
80 uidtoname( prec.uid ),
81 fullpath );
83 fenum->count++;
86 return 0;
89 /*******************************************************************
90 ********************************************************************/
92 static WERROR net_enum_pipes( TALLOC_CTX *ctx, FILE_INFO_3 **info,
93 uint32 *count, uint32 resume )
95 struct file_enum_count fenum;
96 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
98 if ( !conn_tdb ) {
99 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
100 return WERR_ACCESS_DENIED;
103 fenum.ctx = ctx;
104 fenum.count = *count;
105 fenum.info = *info;
107 if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
108 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
109 tdb_errorstr(conn_tdb) ));
110 return WERR_NOMEM;
113 *info = fenum.info;
114 *count = fenum.count;
116 return WERR_OK;}
118 /*******************************************************************
119 ********************************************************************/
121 /* global needed to make use of the share_mode_forall() callback */
122 static struct file_enum_count f_enum_cnt;
124 static void enum_file_fn( const struct share_mode_entry *e,
125 const char *sharepath, const char *fname, void *state )
127 struct file_enum_count *fenum = &f_enum_cnt;
129 /* If the pid was not found delete the entry from connections.tdb */
131 if ( process_exists(e->pid) ) {
132 FILE_INFO_3 *f;
133 int i = fenum->count;
134 files_struct fsp;
135 struct byte_range_lock *brl;
136 int num_locks = 0;
137 pstring fullpath;
138 uint32 permissions;
140 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
141 if ( !f ) {
142 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
143 return;
145 fenum->info = f;
147 /* need to count the number of locks on a file */
149 ZERO_STRUCT( fsp );
150 fsp.dev = e->dev;
151 fsp.inode = e->inode;
153 if ( (brl = brl_get_locks(NULL,&fsp)) != NULL ) {
154 num_locks = brl->num_locks;
155 TALLOC_FREE( brl );
158 if ( strcmp( fname, "." ) == 0 ) {
159 pstr_sprintf( fullpath, "C:%s", sharepath );
160 } else {
161 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
163 string_replace( fullpath, '/', '\\' );
165 /* mask out create (what ever that is) */
166 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
168 /* now fill in the FILE_INFO_3 struct */
169 init_srv_file_info3( &fenum->info[i],
170 e->share_file_id,
171 permissions,
172 num_locks,
173 uidtoname(e->uid),
174 fullpath );
176 fenum->count++;
179 return;
183 /*******************************************************************
184 ********************************************************************/
186 static WERROR net_enum_files( TALLOC_CTX *ctx, FILE_INFO_3 **info,
187 uint32 *count, uint32 resume )
189 f_enum_cnt.ctx = ctx;
190 f_enum_cnt.count = *count;
191 f_enum_cnt.info = *info;
193 share_mode_forall( enum_file_fn, NULL );
195 *info = f_enum_cnt.info;
196 *count = f_enum_cnt.count;
198 return WERR_OK;
201 /*******************************************************************
202 Utility function to get the 'type' of a share from an snum.
203 ********************************************************************/
204 static uint32 get_share_type(int snum)
206 /* work out the share type */
207 uint32 type = STYPE_DISKTREE;
209 if (lp_print_ok(snum))
210 type = STYPE_PRINTQ;
211 if (strequal(lp_fstype(snum), "IPC"))
212 type = STYPE_IPC;
213 if (lp_administrative_share(snum))
214 type |= STYPE_HIDDEN;
216 return type;
219 /*******************************************************************
220 Fill in a share info level 0 structure.
221 ********************************************************************/
223 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
225 pstring net_name;
227 pstrcpy(net_name, lp_servicename(snum));
229 init_srv_share_info0(&sh0->info_0, net_name);
230 init_srv_share_info0_str(&sh0->info_0_str, net_name);
233 /*******************************************************************
234 Fill in a share info level 1 structure.
235 ********************************************************************/
237 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
239 pstring remark;
241 char *net_name = lp_servicename(snum);
242 pstrcpy(remark, lp_comment(snum));
243 standard_sub_conn(p->conn, remark,sizeof(remark));
245 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
246 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
249 /*******************************************************************
250 Fill in a share info level 2 structure.
251 ********************************************************************/
253 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
255 pstring remark;
256 pstring path;
257 pstring passwd;
258 int max_connections = lp_max_connections(snum);
259 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
260 int count = 0;
261 char *net_name = lp_servicename(snum);
263 pstrcpy(remark, lp_comment(snum));
264 standard_sub_conn(p->conn, remark,sizeof(remark));
265 pstrcpy(path, "C:");
266 pstrcat(path, lp_pathname(snum));
269 * Change / to \\ so that win2k will see it as a valid path. This was added to
270 * enable use of browsing in win2k add share dialog.
273 string_replace(path, '/', '\\');
275 pstrcpy(passwd, "");
277 count = count_current_connections( net_name, False );
278 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum),
279 remark, 0, max_uses, count, path, passwd);
281 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
284 /*******************************************************************
285 Map any generic bits to file specific bits.
286 ********************************************************************/
288 static void map_generic_share_sd_bits(SEC_DESC *psd)
290 int i;
291 SEC_ACL *ps_dacl = NULL;
293 if (!psd)
294 return;
296 ps_dacl = psd->dacl;
297 if (!ps_dacl)
298 return;
300 for (i = 0; i < ps_dacl->num_aces; i++) {
301 SEC_ACE *psa = &ps_dacl->aces[i];
302 uint32 orig_mask = psa->access_mask;
304 se_map_generic(&psa->access_mask, &file_generic_mapping);
305 psa->access_mask |= orig_mask;
309 /*******************************************************************
310 Fill in a share info level 501 structure.
311 ********************************************************************/
313 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
315 pstring remark;
317 const char *net_name = lp_servicename(snum);
318 pstrcpy(remark, lp_comment(snum));
319 standard_sub_conn(p->conn, remark, sizeof(remark));
321 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
322 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
325 /*******************************************************************
326 Fill in a share info level 502 structure.
327 ********************************************************************/
329 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
331 pstring net_name;
332 pstring remark;
333 pstring path;
334 pstring passwd;
335 SEC_DESC *sd;
336 size_t sd_size;
337 TALLOC_CTX *ctx = p->mem_ctx;
340 ZERO_STRUCTP(sh502);
342 pstrcpy(net_name, lp_servicename(snum));
343 pstrcpy(remark, lp_comment(snum));
344 standard_sub_conn(p->conn, remark,sizeof(remark));
345 pstrcpy(path, "C:");
346 pstrcat(path, lp_pathname(snum));
349 * Change / to \\ so that win2k will see it as a valid path. This was added to
350 * enable use of browsing in win2k add share dialog.
353 string_replace(path, '/', '\\');
355 pstrcpy(passwd, "");
357 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
359 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
360 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
363 /***************************************************************************
364 Fill in a share info level 1004 structure.
365 ***************************************************************************/
367 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
369 pstring remark;
371 pstrcpy(remark, lp_comment(snum));
372 standard_sub_conn(p->conn, remark, sizeof(remark));
374 ZERO_STRUCTP(sh1004);
376 init_srv_share_info1004(&sh1004->info_1004, remark);
377 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
380 /***************************************************************************
381 Fill in a share info level 1005 structure.
382 ***************************************************************************/
384 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
386 sh1005->share_info_flags = 0;
388 if(lp_host_msdfs() && lp_msdfs_root(snum))
389 sh1005->share_info_flags |=
390 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
391 sh1005->share_info_flags |=
392 lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
394 /***************************************************************************
395 Fill in a share info level 1006 structure.
396 ***************************************************************************/
398 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
400 sh1006->max_uses = -1;
403 /***************************************************************************
404 Fill in a share info level 1007 structure.
405 ***************************************************************************/
407 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
409 pstring alternate_directory_name = "";
410 uint32 flags = 0;
412 ZERO_STRUCTP(sh1007);
414 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
415 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
418 /*******************************************************************
419 Fill in a share info level 1501 structure.
420 ********************************************************************/
422 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
424 SEC_DESC *sd;
425 size_t sd_size;
426 TALLOC_CTX *ctx = p->mem_ctx;
428 ZERO_STRUCTP(sh1501);
430 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
432 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
435 /*******************************************************************
436 True if it ends in '$'.
437 ********************************************************************/
439 static BOOL is_hidden_share(int snum)
441 const char *net_name = lp_servicename(snum);
443 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
446 /*******************************************************************
447 Fill in a share info structure.
448 ********************************************************************/
450 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
451 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
453 int num_entries = 0;
454 int num_services = 0;
455 int snum;
456 TALLOC_CTX *ctx = p->mem_ctx;
458 DEBUG(5,("init_srv_share_info_ctr\n"));
460 ZERO_STRUCTPN(ctr);
462 ctr->info_level = ctr->switch_value = info_level;
463 *resume_hnd = 0;
465 /* Ensure all the usershares are loaded. */
466 become_root();
467 num_services = load_usershare_shares();
468 unbecome_root();
470 /* Count the number of entries. */
471 for (snum = 0; snum < num_services; snum++) {
472 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
473 num_entries++;
476 *total_entries = num_entries;
477 ctr->num_entries2 = ctr->num_entries = num_entries;
478 ctr->ptr_share_info = ctr->ptr_entries = 1;
480 if (!num_entries)
481 return True;
483 switch (info_level) {
484 case 0:
486 SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
487 int i = 0;
489 if (!info0) {
490 return False;
493 for (snum = *resume_hnd; snum < num_services; snum++) {
494 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
495 init_srv_share_info_0(p, &info0[i++], snum);
499 ctr->share.info0 = info0;
500 break;
504 case 1:
506 SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
507 int i = 0;
509 if (!info1) {
510 return False;
513 for (snum = *resume_hnd; snum < num_services; snum++) {
514 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
515 init_srv_share_info_1(p, &info1[i++], snum);
519 ctr->share.info1 = info1;
520 break;
523 case 2:
525 SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
526 int i = 0;
528 if (!info2) {
529 return False;
532 for (snum = *resume_hnd; snum < num_services; snum++) {
533 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
534 init_srv_share_info_2(p, &info2[i++], snum);
538 ctr->share.info2 = info2;
539 break;
542 case 501:
544 SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
545 int i = 0;
547 if (!info501) {
548 return False;
551 for (snum = *resume_hnd; snum < num_services; snum++) {
552 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
553 init_srv_share_info_501(p, &info501[i++], snum);
557 ctr->share.info501 = info501;
558 break;
561 case 502:
563 SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
564 int i = 0;
566 if (!info502) {
567 return False;
570 for (snum = *resume_hnd; snum < num_services; snum++) {
571 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
572 init_srv_share_info_502(p, &info502[i++], snum);
576 ctr->share.info502 = info502;
577 break;
580 /* here for completeness but not currently used with enum (1004 - 1501)*/
582 case 1004:
584 SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
585 int i = 0;
587 if (!info1004) {
588 return False;
591 for (snum = *resume_hnd; snum < num_services; snum++) {
592 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
593 init_srv_share_info_1004(p, &info1004[i++], snum);
597 ctr->share.info1004 = info1004;
598 break;
601 case 1005:
603 SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
604 int i = 0;
606 if (!info1005) {
607 return False;
610 for (snum = *resume_hnd; snum < num_services; snum++) {
611 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
612 init_srv_share_info_1005(p, &info1005[i++], snum);
616 ctr->share.info1005 = info1005;
617 break;
620 case 1006:
622 SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
623 int i = 0;
625 if (!info1006) {
626 return False;
629 for (snum = *resume_hnd; snum < num_services; snum++) {
630 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
631 init_srv_share_info_1006(p, &info1006[i++], snum);
635 ctr->share.info1006 = info1006;
636 break;
639 case 1007:
641 SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
642 int i = 0;
644 if (!info1007) {
645 return False;
648 for (snum = *resume_hnd; snum < num_services; snum++) {
649 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
650 init_srv_share_info_1007(p, &info1007[i++], snum);
654 ctr->share.info1007 = info1007;
655 break;
658 case 1501:
660 SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
661 int i = 0;
663 if (!info1501) {
664 return False;
667 for (snum = *resume_hnd; snum < num_services; snum++) {
668 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
669 init_srv_share_info_1501(p, &info1501[i++], snum);
673 ctr->share.info1501 = info1501;
674 break;
676 default:
677 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
678 return False;
681 return True;
684 /*******************************************************************
685 Inits a SRV_R_NET_SHARE_ENUM structure.
686 ********************************************************************/
688 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
689 uint32 info_level, uint32 resume_hnd, BOOL all)
691 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
693 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
694 &resume_hnd, &r_n->total_entries, all)) {
695 r_n->status = WERR_OK;
696 } else {
697 r_n->status = WERR_UNKNOWN_LEVEL;
700 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
703 /*******************************************************************
704 Inits a SRV_R_NET_SHARE_GET_INFO structure.
705 ********************************************************************/
707 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
708 char *share_name, uint32 info_level)
710 WERROR status = WERR_OK;
711 int snum;
713 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
715 r_n->info.switch_value = info_level;
717 snum = find_service(share_name);
719 if (snum >= 0) {
720 switch (info_level) {
721 case 0:
722 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
723 break;
724 case 1:
725 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
726 break;
727 case 2:
728 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
729 break;
730 case 501:
731 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
732 break;
733 case 502:
734 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
735 break;
737 /* here for completeness */
738 case 1004:
739 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
740 break;
741 case 1005:
742 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
743 break;
745 /* here for completeness 1006 - 1501 */
746 case 1006:
747 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
748 break;
749 case 1007:
750 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
751 break;
752 case 1501:
753 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
754 break;
755 default:
756 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
757 status = WERR_UNKNOWN_LEVEL;
758 break;
760 } else {
761 status = WERR_INVALID_NAME;
764 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
765 r_n->status = status;
768 /*******************************************************************
769 fill in a sess info level 0 structure.
770 ********************************************************************/
772 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
774 struct sessionid *session_list;
775 uint32 num_entries = 0;
776 (*stot) = list_sessions(&session_list);
778 if (ss0 == NULL) {
779 if (snum) {
780 (*snum) = 0;
782 SAFE_FREE(session_list);
783 return;
786 DEBUG(5,("init_srv_sess_0_ss0\n"));
788 if (snum) {
789 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
790 init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
791 num_entries++;
794 ss0->num_entries_read = num_entries;
795 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
796 ss0->num_entries_read2 = num_entries;
798 if ((*snum) >= (*stot)) {
799 (*snum) = 0;
802 } else {
803 ss0->num_entries_read = 0;
804 ss0->ptr_sess_info = 0;
805 ss0->num_entries_read2 = 0;
807 SAFE_FREE(session_list);
810 /*******************************************************************
811 ********************************************************************/
813 /* global needed to make use of the share_mode_forall() callback */
814 static struct sess_file_count s_file_cnt;
816 static void sess_file_fn( const struct share_mode_entry *e,
817 const char *sharepath, const char *fname, void *state )
819 struct sess_file_count *sess = &s_file_cnt;
821 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
822 sess->count++;
825 return;
828 /*******************************************************************
829 ********************************************************************/
831 static int net_count_files( uid_t uid, pid_t pid )
833 s_file_cnt.count = 0;
834 s_file_cnt.uid = uid;
835 s_file_cnt.pid = pid;
837 share_mode_forall( sess_file_fn, NULL );
839 return s_file_cnt.count;
842 /*******************************************************************
843 fill in a sess info level 1 structure.
844 ********************************************************************/
846 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
848 struct sessionid *session_list;
849 uint32 num_entries = 0;
850 time_t now = time(NULL);
852 if ( !snum ) {
853 ss1->num_entries_read = 0;
854 ss1->ptr_sess_info = 0;
855 ss1->num_entries_read2 = 0;
857 (*stot) = 0;
859 return;
862 if (ss1 == NULL) {
863 (*snum) = 0;
864 return;
867 (*stot) = list_sessions(&session_list);
870 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
871 uint32 num_files;
872 uint32 connect_time;
873 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
874 BOOL guest;
876 if ( !pw ) {
877 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
878 session_list[*snum].username));
879 continue;
882 connect_time = (uint32)(now - session_list[*snum].connect_start);
883 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
884 guest = strequal( session_list[*snum].username, lp_guestaccount() );
886 init_srv_sess_info1( &ss1->info_1[num_entries],
887 session_list[*snum].remote_machine,
888 session_list[*snum].username,
889 num_files,
890 connect_time,
892 guest);
893 num_entries++;
896 ss1->num_entries_read = num_entries;
897 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
898 ss1->num_entries_read2 = num_entries;
900 if ((*snum) >= (*stot)) {
901 (*snum) = 0;
904 SAFE_FREE(session_list);
907 /*******************************************************************
908 makes a SRV_R_NET_SESS_ENUM structure.
909 ********************************************************************/
911 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
912 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
914 WERROR status = WERR_OK;
915 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
917 ctr->switch_value = switch_value;
919 switch (switch_value) {
920 case 0:
921 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
922 ctr->ptr_sess_ctr = 1;
923 break;
924 case 1:
925 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
926 ctr->ptr_sess_ctr = 1;
927 break;
928 default:
929 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
930 (*resume_hnd) = 0;
931 (*total_entries) = 0;
932 ctr->ptr_sess_ctr = 0;
933 status = WERR_UNKNOWN_LEVEL;
934 break;
937 return status;
940 /*******************************************************************
941 makes a SRV_R_NET_SESS_ENUM structure.
942 ********************************************************************/
944 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
945 uint32 resume_hnd, int sess_level, int switch_value)
947 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
949 r_n->sess_level = sess_level;
951 if (sess_level == -1)
952 r_n->status = WERR_UNKNOWN_LEVEL;
953 else
954 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
956 if (!W_ERROR_IS_OK(r_n->status))
957 resume_hnd = 0;
959 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
962 /*******************************************************************
963 fill in a conn info level 0 structure.
964 ********************************************************************/
966 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
968 uint32 num_entries = 0;
969 (*stot) = 1;
971 if (ss0 == NULL) {
972 (*snum) = 0;
973 return;
976 DEBUG(5,("init_srv_conn_0_ss0\n"));
978 if (snum) {
979 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
981 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
983 /* move on to creating next connection */
984 /* move on to creating next conn */
985 num_entries++;
988 ss0->num_entries_read = num_entries;
989 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
990 ss0->num_entries_read2 = num_entries;
992 if ((*snum) >= (*stot)) {
993 (*snum) = 0;
996 } else {
997 ss0->num_entries_read = 0;
998 ss0->ptr_conn_info = 0;
999 ss0->num_entries_read2 = 0;
1001 (*stot) = 0;
1005 /*******************************************************************
1006 fill in a conn info level 1 structure.
1007 ********************************************************************/
1009 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1010 uint32 id, uint32 type,
1011 uint32 num_opens, uint32 num_users, uint32 open_time,
1012 const char *usr_name, const char *net_name)
1014 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1015 init_srv_conn_info1_str(str1, usr_name, net_name);
1018 /*******************************************************************
1019 fill in a conn info level 1 structure.
1020 ********************************************************************/
1022 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1024 uint32 num_entries = 0;
1025 (*stot) = 1;
1027 if (ss1 == NULL) {
1028 (*snum) = 0;
1029 return;
1032 DEBUG(5,("init_srv_conn_1_ss1\n"));
1034 if (snum) {
1035 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1036 init_srv_conn_1_info(&ss1->info_1[num_entries],
1037 &ss1->info_1_str[num_entries],
1038 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1040 /* move on to creating next connection */
1041 /* move on to creating next conn */
1042 num_entries++;
1045 ss1->num_entries_read = num_entries;
1046 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1047 ss1->num_entries_read2 = num_entries;
1050 if ((*snum) >= (*stot)) {
1051 (*snum) = 0;
1054 } else {
1055 ss1->num_entries_read = 0;
1056 ss1->ptr_conn_info = 0;
1057 ss1->num_entries_read2 = 0;
1059 (*stot) = 0;
1063 /*******************************************************************
1064 makes a SRV_R_NET_CONN_ENUM structure.
1065 ********************************************************************/
1067 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1068 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1070 WERROR status = WERR_OK;
1071 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1073 ctr->switch_value = switch_value;
1075 switch (switch_value) {
1076 case 0:
1077 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1078 ctr->ptr_conn_ctr = 1;
1079 break;
1080 case 1:
1081 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1082 ctr->ptr_conn_ctr = 1;
1083 break;
1084 default:
1085 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1086 (*resume_hnd = 0);
1087 (*total_entries) = 0;
1088 ctr->ptr_conn_ctr = 0;
1089 status = WERR_UNKNOWN_LEVEL;
1090 break;
1093 return status;
1096 /*******************************************************************
1097 makes a SRV_R_NET_CONN_ENUM structure.
1098 ********************************************************************/
1100 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1101 uint32 resume_hnd, int conn_level, int switch_value)
1103 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1105 r_n->conn_level = conn_level;
1106 if (conn_level == -1)
1107 r_n->status = WERR_UNKNOWN_LEVEL;
1108 else
1109 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1111 if (!W_ERROR_IS_OK(r_n->status))
1112 resume_hnd = 0;
1114 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1117 /*******************************************************************
1118 makes a SRV_R_NET_FILE_ENUM structure.
1119 ********************************************************************/
1121 static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1123 TALLOC_CTX *ctx = get_talloc_ctx();
1124 SRV_FILE_INFO_CTR *ctr = &r->ctr;
1126 /* TODO -- Windows enumerates
1127 (b) active pipes
1128 (c) open directories and files */
1130 r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1131 if ( !W_ERROR_IS_OK(r->status))
1132 goto done;
1134 r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1135 if ( !W_ERROR_IS_OK(r->status))
1136 goto done;
1138 r->level = ctr->level = 3;
1139 r->total_entries = ctr->num_entries;
1140 /* ctr->num_entries = r->total_entries - resume_hnd; */
1141 ctr->num_entries2 = ctr->num_entries;
1142 ctr->ptr_file_info = 1;
1144 r->status = WERR_OK;
1146 done:
1147 if ( ctr->num_entries > 0 )
1148 ctr->ptr_entries = 1;
1150 init_enum_hnd(&r->enum_hnd, 0);
1152 return r->status;
1155 /*******************************************************************
1156 *******************************************************************/
1158 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1160 switch ( q_u->level ) {
1161 case 3:
1162 return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );
1163 default:
1164 return WERR_UNKNOWN_LEVEL;
1167 return WERR_OK;
1170 /*******************************************************************
1171 net server get info
1172 ********************************************************************/
1174 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)
1176 WERROR status = WERR_OK;
1177 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1179 if (!ctr)
1180 return WERR_NOMEM;
1182 ZERO_STRUCTP(ctr);
1184 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1186 if (!pipe_access_check(p)) {
1187 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1188 return WERR_ACCESS_DENIED;
1191 switch (q_u->switch_value) {
1193 /* Technically level 102 should only be available to
1194 Administrators but there isn't anything super-secret
1195 here, as most of it is made up. */
1197 case 102:
1198 init_srv_info_102(&ctr->srv.sv102,
1199 500, global_myname(),
1200 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1201 lp_major_announce_version(), lp_minor_announce_version(),
1202 lp_default_server_announce(),
1203 0xffffffff, /* users */
1204 0xf, /* disc */
1205 0, /* hidden */
1206 240, /* announce */
1207 3000, /* announce delta */
1208 100000, /* licenses */
1209 "c:\\"); /* user path */
1210 break;
1211 case 101:
1212 init_srv_info_101(&ctr->srv.sv101,
1213 500, global_myname(),
1214 lp_major_announce_version(), lp_minor_announce_version(),
1215 lp_default_server_announce(),
1216 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1217 break;
1218 case 100:
1219 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1220 break;
1221 default:
1222 status = WERR_UNKNOWN_LEVEL;
1223 break;
1226 /* set up the net server get info structure */
1227 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1229 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1231 return r_u->status;
1234 /*******************************************************************
1235 net server set info
1236 ********************************************************************/
1238 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)
1240 WERROR status = WERR_OK;
1242 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1244 /* Set up the net server set info structure. */
1246 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1248 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1250 return r_u->status;
1253 /*******************************************************************
1254 net conn enum
1255 ********************************************************************/
1257 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1259 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1261 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1262 if (!r_u->ctr)
1263 return WERR_NOMEM;
1265 ZERO_STRUCTP(r_u->ctr);
1267 /* set up the */
1268 init_srv_r_net_conn_enum(r_u,
1269 get_enum_hnd(&q_u->enum_hnd),
1270 q_u->conn_level,
1271 q_u->ctr->switch_value);
1273 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1275 return r_u->status;
1278 /*******************************************************************
1279 net sess enum
1280 ********************************************************************/
1282 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1284 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1286 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1287 if (!r_u->ctr)
1288 return WERR_NOMEM;
1290 ZERO_STRUCTP(r_u->ctr);
1292 /* set up the */
1293 init_srv_r_net_sess_enum(r_u,
1294 get_enum_hnd(&q_u->enum_hnd),
1295 q_u->sess_level,
1296 q_u->ctr->switch_value);
1298 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1300 return r_u->status;
1303 /*******************************************************************
1304 net sess del
1305 ********************************************************************/
1307 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1309 struct sessionid *session_list;
1310 struct current_user user;
1311 int num_sessions, snum;
1312 fstring username;
1313 fstring machine;
1314 BOOL not_root = False;
1316 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1317 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1319 /* strip leading backslashes if any */
1320 while (machine[0] == '\\') {
1321 memmove(machine, &machine[1], strlen(machine));
1324 num_sessions = list_sessions(&session_list);
1326 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1328 r_u->status = WERR_ACCESS_DENIED;
1330 get_current_user(&user, p);
1332 /* fail out now if you are not root or not a domain admin */
1334 if ((user.ut.uid != sec_initial_uid()) &&
1335 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1337 goto done;
1340 for (snum = 0; snum < num_sessions; snum++) {
1342 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1343 strequal(session_list[snum].remote_machine, machine)) {
1345 if (user.ut.uid != sec_initial_uid()) {
1346 not_root = True;
1347 become_root();
1350 if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)))
1351 r_u->status = WERR_OK;
1353 if (not_root)
1354 unbecome_root();
1358 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1361 done:
1362 SAFE_FREE(session_list);
1364 return r_u->status;
1367 /*******************************************************************
1368 Net share enum all.
1369 ********************************************************************/
1371 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1373 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1375 if (!pipe_access_check(p)) {
1376 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1377 return WERR_ACCESS_DENIED;
1380 /* Create the list of shares for the response. */
1381 init_srv_r_net_share_enum(p, r_u,
1382 q_u->ctr.info_level,
1383 get_enum_hnd(&q_u->enum_hnd), True);
1385 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1387 return r_u->status;
1390 /*******************************************************************
1391 Net share enum.
1392 ********************************************************************/
1394 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1396 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1398 if (!pipe_access_check(p)) {
1399 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1400 return WERR_ACCESS_DENIED;
1403 /* Create the list of shares for the response. */
1404 init_srv_r_net_share_enum(p, r_u,
1405 q_u->ctr.info_level,
1406 get_enum_hnd(&q_u->enum_hnd), False);
1408 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1410 return r_u->status;
1413 /*******************************************************************
1414 Net share get info.
1415 ********************************************************************/
1417 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)
1419 fstring share_name;
1421 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1423 /* Create the list of shares for the response. */
1424 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1425 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1427 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1429 return r_u->status;
1432 /*******************************************************************
1433 Check a given DOS pathname is valid for a share.
1434 ********************************************************************/
1436 char *valid_share_pathname(char *dos_pathname)
1438 char *ptr;
1440 /* Convert any '\' paths to '/' */
1441 unix_format(dos_pathname);
1442 unix_clean_name(dos_pathname);
1444 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1445 ptr = dos_pathname;
1446 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1447 ptr += 2;
1449 /* Only absolute paths allowed. */
1450 if (*ptr != '/')
1451 return NULL;
1453 return ptr;
1456 /*******************************************************************
1457 Net share set info. Modify share details.
1458 ********************************************************************/
1460 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)
1462 struct current_user user;
1463 pstring command;
1464 fstring share_name;
1465 fstring comment;
1466 pstring pathname;
1467 int type;
1468 int snum;
1469 int ret;
1470 char *path;
1471 SEC_DESC *psd = NULL;
1472 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1473 BOOL is_disk_op = False;
1474 int max_connections = 0;
1476 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1478 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1480 r_u->parm_error = 0;
1482 if ( strequal(share_name,"IPC$")
1483 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1484 || strequal(share_name,"global") )
1486 return WERR_ACCESS_DENIED;
1489 snum = find_service(share_name);
1491 /* Does this share exist ? */
1492 if (snum < 0)
1493 return WERR_NET_NAME_NOT_FOUND;
1495 /* No change to printer shares. */
1496 if (lp_print_ok(snum))
1497 return WERR_ACCESS_DENIED;
1499 get_current_user(&user,p);
1501 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1503 /* fail out now if you are not root and not a disk op */
1505 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1506 return WERR_ACCESS_DENIED;
1508 switch (q_u->info_level) {
1509 case 1:
1510 pstrcpy(pathname, lp_pathname(snum));
1511 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1512 type = q_u->info.share.info2.info_2.type;
1513 psd = NULL;
1514 break;
1515 case 2:
1516 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1517 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1518 type = q_u->info.share.info2.info_2.type;
1519 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1520 psd = NULL;
1521 break;
1522 #if 0
1523 /* not supported on set but here for completeness */
1524 case 501:
1525 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1526 type = q_u->info.share.info501.info_501.type;
1527 psd = NULL;
1528 break;
1529 #endif
1530 case 502:
1531 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1532 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1533 type = q_u->info.share.info502.info_502.type;
1534 psd = q_u->info.share.info502.info_502_str.sd;
1535 map_generic_share_sd_bits(psd);
1536 break;
1537 case 1004:
1538 pstrcpy(pathname, lp_pathname(snum));
1539 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1540 type = STYPE_DISKTREE;
1541 break;
1542 case 1005:
1543 /* XP re-sets the csc policy even if it wasn't changed by the
1544 user, so we must compare it to see if it's what is set in
1545 smb.conf, so that we can contine other ops like setting
1546 ACLs on a share */
1547 if (((q_u->info.share.info1005.share_info_flags &
1548 SHARE_1005_CSC_POLICY_MASK) >>
1549 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1550 return WERR_OK;
1551 else {
1552 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1553 return WERR_ACCESS_DENIED;
1555 case 1006:
1556 case 1007:
1557 return WERR_ACCESS_DENIED;
1558 case 1501:
1559 pstrcpy(pathname, lp_pathname(snum));
1560 fstrcpy(comment, lp_comment(snum));
1561 psd = q_u->info.share.info1501.sdb->sec;
1562 map_generic_share_sd_bits(psd);
1563 type = STYPE_DISKTREE;
1564 break;
1565 default:
1566 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1567 return WERR_UNKNOWN_LEVEL;
1570 /* We can only modify disk shares. */
1571 if (type != STYPE_DISKTREE)
1572 return WERR_ACCESS_DENIED;
1574 /* Check if the pathname is valid. */
1575 if (!(path = valid_share_pathname( pathname )))
1576 return WERR_OBJECT_PATH_INVALID;
1578 /* Ensure share name, pathname and comment don't contain '"' characters. */
1579 string_replace(share_name, '"', ' ');
1580 string_replace(path, '"', ' ');
1581 string_replace(comment, '"', ' ');
1583 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1584 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1586 /* Only call modify function if something changed. */
1588 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1589 || (lp_max_connections(snum) != max_connections) )
1591 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1592 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1593 return WERR_ACCESS_DENIED;
1596 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1597 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1599 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1601 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1603 if ( is_disk_op )
1604 become_root();
1606 if ( (ret = smbrun(command, NULL)) == 0 ) {
1607 /* Tell everyone we updated smb.conf. */
1608 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1611 if ( is_disk_op )
1612 unbecome_root();
1614 /********* END SeDiskOperatorPrivilege BLOCK *********/
1616 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1618 if ( ret != 0 )
1619 return WERR_ACCESS_DENIED;
1620 } else {
1621 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1624 /* Replace SD if changed. */
1625 if (psd) {
1626 SEC_DESC *old_sd;
1627 size_t sd_size;
1629 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1631 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1632 if (!set_share_security(share_name, psd))
1633 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1634 share_name ));
1638 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1640 return WERR_OK;
1643 /*******************************************************************
1644 Net share add. Call 'add_share_command "sharename" "pathname"
1645 "comment" "max connections = "
1646 ********************************************************************/
1648 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1650 struct current_user user;
1651 pstring command;
1652 fstring share_name;
1653 fstring comment;
1654 pstring pathname;
1655 int type;
1656 int snum;
1657 int ret;
1658 char *path;
1659 SEC_DESC *psd = NULL;
1660 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1661 BOOL is_disk_op;
1662 int max_connections = 0;
1664 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1666 r_u->parm_error = 0;
1668 get_current_user(&user,p);
1670 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1672 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1673 return WERR_ACCESS_DENIED;
1675 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1676 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1677 return WERR_ACCESS_DENIED;
1680 switch (q_u->info_level) {
1681 case 0:
1682 /* No path. Not enough info in a level 0 to do anything. */
1683 return WERR_ACCESS_DENIED;
1684 case 1:
1685 /* Not enough info in a level 1 to do anything. */
1686 return WERR_ACCESS_DENIED;
1687 case 2:
1688 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1689 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1690 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1691 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1692 type = q_u->info.share.info2.info_2.type;
1693 break;
1694 case 501:
1695 /* No path. Not enough info in a level 501 to do anything. */
1696 return WERR_ACCESS_DENIED;
1697 case 502:
1698 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1699 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1700 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1701 type = q_u->info.share.info502.info_502.type;
1702 psd = q_u->info.share.info502.info_502_str.sd;
1703 map_generic_share_sd_bits(psd);
1704 break;
1706 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1708 case 1004:
1709 case 1005:
1710 case 1006:
1711 case 1007:
1712 return WERR_ACCESS_DENIED;
1713 case 1501:
1714 /* DFS only level. */
1715 return WERR_ACCESS_DENIED;
1716 default:
1717 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1718 return WERR_UNKNOWN_LEVEL;
1721 /* check for invalid share names */
1723 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1724 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1725 return WERR_INVALID_NAME;
1728 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1729 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1731 return WERR_ACCESS_DENIED;
1734 snum = find_service(share_name);
1736 /* Share already exists. */
1737 if (snum >= 0)
1738 return WERR_ALREADY_EXISTS;
1740 /* We can only add disk shares. */
1741 if (type != STYPE_DISKTREE)
1742 return WERR_ACCESS_DENIED;
1744 /* Check if the pathname is valid. */
1745 if (!(path = valid_share_pathname( pathname )))
1746 return WERR_OBJECT_PATH_INVALID;
1748 /* Ensure share name, pathname and comment don't contain '"' characters. */
1749 string_replace(share_name, '"', ' ');
1750 string_replace(path, '"', ' ');
1751 string_replace(comment, '"', ' ');
1753 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1754 lp_add_share_cmd(),
1755 dyn_CONFIGFILE,
1756 share_name,
1757 path,
1758 comment,
1759 max_connections);
1761 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1763 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1765 if ( is_disk_op )
1766 become_root();
1768 if ( (ret = smbrun(command, NULL)) == 0 ) {
1769 /* Tell everyone we updated smb.conf. */
1770 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1773 if ( is_disk_op )
1774 unbecome_root();
1776 /********* END SeDiskOperatorPrivilege BLOCK *********/
1778 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1780 if ( ret != 0 )
1781 return WERR_ACCESS_DENIED;
1783 if (psd) {
1784 if (!set_share_security(share_name, psd)) {
1785 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1790 * We don't call reload_services() here, the message will
1791 * cause this to be done before the next packet is read
1792 * from the client. JRA.
1795 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1797 return WERR_OK;
1800 /*******************************************************************
1801 Net share delete. Call "delete share command" with the share name as
1802 a parameter.
1803 ********************************************************************/
1805 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1807 struct current_user user;
1808 pstring command;
1809 fstring share_name;
1810 int ret;
1811 int snum;
1812 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1813 BOOL is_disk_op;
1814 struct share_params *params;
1816 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1818 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1820 if ( strequal(share_name,"IPC$")
1821 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1822 || strequal(share_name,"global") )
1824 return WERR_ACCESS_DENIED;
1827 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1828 return WERR_NO_SUCH_SHARE;
1831 snum = find_service(share_name);
1833 /* No change to printer shares. */
1834 if (lp_print_ok(snum))
1835 return WERR_ACCESS_DENIED;
1837 get_current_user(&user,p);
1839 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1841 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1842 return WERR_ACCESS_DENIED;
1844 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1845 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1846 return WERR_ACCESS_DENIED;
1849 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1850 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1852 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1854 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1856 if ( is_disk_op )
1857 become_root();
1859 if ( (ret = smbrun(command, NULL)) == 0 ) {
1860 /* Tell everyone we updated smb.conf. */
1861 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1864 if ( is_disk_op )
1865 unbecome_root();
1867 /********* END SeDiskOperatorPrivilege BLOCK *********/
1869 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1871 if ( ret != 0 )
1872 return WERR_ACCESS_DENIED;
1874 /* Delete the SD in the database. */
1875 delete_share_security(params);
1877 lp_killservice(params->service);
1879 return WERR_OK;
1882 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1884 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1886 return _srv_net_share_del(p, q_u, r_u);
1889 /*******************************************************************
1890 time of day
1891 ********************************************************************/
1893 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1895 TIME_OF_DAY_INFO *tod;
1896 struct tm *t;
1897 time_t unixdate = time(NULL);
1899 /* We do this call first as if we do it *after* the gmtime call
1900 it overwrites the pointed-to values. JRA */
1902 uint32 zone = get_time_zone(unixdate)/60;
1904 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1906 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1907 return WERR_NOMEM;
1909 r_u->tod = tod;
1910 r_u->ptr_srv_tod = 0x1;
1911 r_u->status = WERR_OK;
1913 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1915 t = gmtime(&unixdate);
1917 /* set up the */
1918 init_time_of_day_info(tod,
1919 unixdate,
1921 t->tm_hour,
1922 t->tm_min,
1923 t->tm_sec,
1925 zone,
1926 10000,
1927 t->tm_mday,
1928 t->tm_mon + 1,
1929 1900+t->tm_year,
1930 t->tm_wday);
1932 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1934 return r_u->status;
1937 /***********************************************************************************
1938 Win9x NT tools get security descriptor.
1939 ***********************************************************************************/
1941 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1942 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1944 SEC_DESC *psd = NULL;
1945 size_t sd_size;
1946 DATA_BLOB null_pw;
1947 pstring filename;
1948 pstring qualname;
1949 files_struct *fsp = NULL;
1950 SMB_STRUCT_STAT st;
1951 NTSTATUS nt_status;
1952 struct current_user user;
1953 connection_struct *conn = NULL;
1954 BOOL became_user = False;
1956 ZERO_STRUCT(st);
1958 r_u->status = WERR_OK;
1960 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1962 /* Null password is ok - we are already an authenticated user... */
1963 null_pw = data_blob(NULL, 0);
1965 get_current_user(&user, p);
1967 become_root();
1968 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1969 unbecome_root();
1971 if (conn == NULL) {
1972 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1973 r_u->status = ntstatus_to_werror(nt_status);
1974 goto error_exit;
1977 if (!become_user(conn, conn->vuid)) {
1978 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1979 r_u->status = WERR_ACCESS_DENIED;
1980 goto error_exit;
1982 became_user = True;
1984 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1985 nt_status = unix_convert(conn, filename, False, NULL, &st);
1986 if (!NT_STATUS_IS_OK(nt_status)) {
1987 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1988 r_u->status = WERR_ACCESS_DENIED;
1989 goto error_exit;
1992 nt_status = check_name(conn, filename);
1993 if (!NT_STATUS_IS_OK(nt_status)) {
1994 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
1995 r_u->status = WERR_ACCESS_DENIED;
1996 goto error_exit;
1999 nt_status = open_file_stat(conn, filename, &st, &fsp);
2000 if ( !NT_STATUS_IS_OK(nt_status)) {
2001 /* Perhaps it is a directory */
2002 if (errno == EISDIR)
2003 nt_status = open_directory(conn, filename, &st,
2004 READ_CONTROL_ACCESS,
2005 FILE_SHARE_READ|FILE_SHARE_WRITE,
2006 FILE_OPEN,
2008 FILE_ATTRIBUTE_DIRECTORY,
2009 NULL, &fsp);
2011 if (!NT_STATUS_IS_OK(nt_status)) {
2012 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2013 r_u->status = ntstatus_to_werror(nt_status);
2014 goto error_exit;
2018 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2020 if (sd_size == 0) {
2021 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2022 r_u->status = WERR_ACCESS_DENIED;
2023 goto error_exit;
2026 r_u->ptr_response = 1;
2027 r_u->size_response = sd_size;
2028 r_u->ptr_secdesc = 1;
2029 r_u->size_secdesc = sd_size;
2030 r_u->sec_desc = psd;
2032 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2034 close_file(fsp, NORMAL_CLOSE);
2035 unbecome_user();
2036 close_cnum(conn, user.vuid);
2037 return r_u->status;
2039 error_exit:
2041 if(fsp) {
2042 close_file(fsp, NORMAL_CLOSE);
2045 if (became_user)
2046 unbecome_user();
2048 if (conn)
2049 close_cnum(conn, user.vuid);
2051 return r_u->status;
2054 /***********************************************************************************
2055 Win9x NT tools set security descriptor.
2056 ***********************************************************************************/
2058 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2059 SRV_R_NET_FILE_SET_SECDESC *r_u)
2061 BOOL ret;
2062 pstring filename;
2063 pstring qualname;
2064 DATA_BLOB null_pw;
2065 files_struct *fsp = NULL;
2066 SMB_STRUCT_STAT st;
2067 NTSTATUS nt_status;
2068 struct current_user user;
2069 connection_struct *conn = NULL;
2070 BOOL became_user = False;
2072 ZERO_STRUCT(st);
2074 r_u->status = WERR_OK;
2076 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2078 /* Null password is ok - we are already an authenticated user... */
2079 null_pw = data_blob(NULL, 0);
2081 get_current_user(&user, p);
2083 become_root();
2084 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2085 unbecome_root();
2087 if (conn == NULL) {
2088 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2089 r_u->status = ntstatus_to_werror(nt_status);
2090 goto error_exit;
2093 if (!become_user(conn, conn->vuid)) {
2094 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2095 r_u->status = WERR_ACCESS_DENIED;
2096 goto error_exit;
2098 became_user = True;
2100 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2101 nt_status = unix_convert(conn, filename, False, NULL, &st);
2102 if (!NT_STATUS_IS_OK(nt_status)) {
2103 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2104 r_u->status = WERR_ACCESS_DENIED;
2105 goto error_exit;
2108 nt_status = check_name(conn, filename);
2109 if (!NT_STATUS_IS_OK(nt_status)) {
2110 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2111 r_u->status = WERR_ACCESS_DENIED;
2112 goto error_exit;
2116 nt_status = open_file_stat(conn, filename, &st, &fsp);
2118 if ( !NT_STATUS_IS_OK(nt_status) ) {
2119 /* Perhaps it is a directory */
2120 if (errno == EISDIR)
2121 nt_status = open_directory(conn, filename, &st,
2122 FILE_READ_ATTRIBUTES,
2123 FILE_SHARE_READ|FILE_SHARE_WRITE,
2124 FILE_OPEN,
2126 FILE_ATTRIBUTE_DIRECTORY,
2127 NULL, &fsp);
2129 if ( !NT_STATUS_IS_OK(nt_status) ) {
2130 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2131 r_u->status = ntstatus_to_werror(nt_status);
2132 goto error_exit;
2136 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2138 if (ret == False) {
2139 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2140 r_u->status = WERR_ACCESS_DENIED;
2141 goto error_exit;
2144 close_file(fsp, NORMAL_CLOSE);
2145 unbecome_user();
2146 close_cnum(conn, user.vuid);
2147 return r_u->status;
2149 error_exit:
2151 if(fsp) {
2152 close_file(fsp, NORMAL_CLOSE);
2155 if (became_user) {
2156 unbecome_user();
2159 if (conn) {
2160 close_cnum(conn, user.vuid);
2163 return r_u->status;
2166 /***********************************************************************************
2167 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2168 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2169 These disks would the disks listed by this function.
2170 Users could then create shares relative to these disks. Watch out for moving these disks around.
2171 "Nigel Williams" <nigel@veritas.com>.
2172 ***********************************************************************************/
2174 static const char *server_disks[] = {"C:"};
2176 static uint32 get_server_disk_count(void)
2178 return sizeof(server_disks)/sizeof(server_disks[0]);
2181 static uint32 init_server_disk_enum(uint32 *resume)
2183 uint32 server_disk_count = get_server_disk_count();
2185 /*resume can be an offset into the list for now*/
2187 if(*resume & 0x80000000)
2188 *resume = 0;
2190 if(*resume > server_disk_count)
2191 *resume = server_disk_count;
2193 return server_disk_count - *resume;
2196 static const char *next_server_disk_enum(uint32 *resume)
2198 const char *disk;
2200 if(init_server_disk_enum(resume) == 0)
2201 return NULL;
2203 disk = server_disks[*resume];
2205 (*resume)++;
2207 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2209 return disk;
2212 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2214 uint32 i;
2215 const char *disk_name;
2216 TALLOC_CTX *ctx = p->mem_ctx;
2217 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2219 r_u->status=WERR_OK;
2221 r_u->total_entries = init_server_disk_enum(&resume);
2223 r_u->disk_enum_ctr.unknown = 0;
2225 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2226 return WERR_NOMEM;
2229 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2231 /*allow one DISK_INFO for null terminator*/
2233 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2235 r_u->disk_enum_ctr.entries_read++;
2237 /*copy disk name into a unicode string*/
2239 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2242 /* add a terminating null string. Is this there if there is more data to come? */
2244 r_u->disk_enum_ctr.entries_read++;
2246 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2248 init_enum_hnd(&r_u->enum_hnd, resume);
2250 return r_u->status;
2253 /********************************************************************
2254 ********************************************************************/
2256 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2258 fstring sharename;
2260 switch ( q_u->type ) {
2261 case 0x9:
2262 rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2263 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2264 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2265 return WERR_INVALID_NAME;
2267 break;
2269 default:
2270 return WERR_UNKNOWN_LEVEL;
2273 return WERR_OK;
2277 /********************************************************************
2278 ********************************************************************/
2280 WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2282 return WERR_ACCESS_DENIED;