[GLUE] Rsync SAMBA_3_0 SVN r25598 in order to create the v3-0-test branch.
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blobd03ab66b50d1ceda7671e199a0fd07256f5e635d
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 char *net_name = lp_servicename(snum);
207 int len_net_name = strlen(net_name);
209 /* work out the share type */
210 uint32 type = STYPE_DISKTREE;
212 if (lp_print_ok(snum))
213 type = STYPE_PRINTQ;
214 if (strequal(lp_fstype(snum), "IPC"))
215 type = STYPE_IPC;
216 if (net_name[len_net_name-1] == '$')
217 type |= STYPE_HIDDEN;
219 return type;
222 /*******************************************************************
223 Fill in a share info level 0 structure.
224 ********************************************************************/
226 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
228 pstring net_name;
230 pstrcpy(net_name, lp_servicename(snum));
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, int snum)
242 pstring remark;
244 char *net_name = lp_servicename(snum);
245 pstrcpy(remark, lp_comment(snum));
246 standard_sub_conn(p->conn, remark,sizeof(remark));
248 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
249 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
252 /*******************************************************************
253 Fill in a share info level 2 structure.
254 ********************************************************************/
256 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
258 pstring remark;
259 pstring path;
260 pstring passwd;
261 int max_connections = lp_max_connections(snum);
262 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
263 int count = 0;
264 char *net_name = lp_servicename(snum);
266 pstrcpy(remark, lp_comment(snum));
267 standard_sub_conn(p->conn, remark,sizeof(remark));
268 pstrcpy(path, "C:");
269 pstrcat(path, lp_pathname(snum));
272 * Change / to \\ so that win2k will see it as a valid path. This was added to
273 * enable use of browsing in win2k add share dialog.
276 string_replace(path, '/', '\\');
278 pstrcpy(passwd, "");
280 count = count_current_connections( net_name, False );
281 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum),
282 remark, 0, max_uses, count, path, passwd);
284 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
287 /*******************************************************************
288 Map any generic bits to file specific bits.
289 ********************************************************************/
291 static void map_generic_share_sd_bits(SEC_DESC *psd)
293 int i;
294 SEC_ACL *ps_dacl = NULL;
296 if (!psd)
297 return;
299 ps_dacl = psd->dacl;
300 if (!ps_dacl)
301 return;
303 for (i = 0; i < ps_dacl->num_aces; i++) {
304 SEC_ACE *psa = &ps_dacl->aces[i];
305 uint32 orig_mask = psa->access_mask;
307 se_map_generic(&psa->access_mask, &file_generic_mapping);
308 psa->access_mask |= orig_mask;
312 /*******************************************************************
313 Fill in a share info level 501 structure.
314 ********************************************************************/
316 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
318 pstring remark;
320 const char *net_name = lp_servicename(snum);
321 pstrcpy(remark, lp_comment(snum));
322 standard_sub_conn(p->conn, remark, sizeof(remark));
324 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
325 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
328 /*******************************************************************
329 Fill in a share info level 502 structure.
330 ********************************************************************/
332 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
334 pstring net_name;
335 pstring remark;
336 pstring path;
337 pstring passwd;
338 SEC_DESC *sd;
339 size_t sd_size;
340 TALLOC_CTX *ctx = p->mem_ctx;
343 ZERO_STRUCTP(sh502);
345 pstrcpy(net_name, lp_servicename(snum));
346 pstrcpy(remark, lp_comment(snum));
347 standard_sub_conn(p->conn, remark,sizeof(remark));
348 pstrcpy(path, "C:");
349 pstrcat(path, lp_pathname(snum));
352 * Change / to \\ so that win2k will see it as a valid path. This was added to
353 * enable use of browsing in win2k add share dialog.
356 string_replace(path, '/', '\\');
358 pstrcpy(passwd, "");
360 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
362 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
363 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
366 /***************************************************************************
367 Fill in a share info level 1004 structure.
368 ***************************************************************************/
370 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
372 pstring remark;
374 pstrcpy(remark, lp_comment(snum));
375 standard_sub_conn(p->conn, remark, sizeof(remark));
377 ZERO_STRUCTP(sh1004);
379 init_srv_share_info1004(&sh1004->info_1004, remark);
380 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
383 /***************************************************************************
384 Fill in a share info level 1005 structure.
385 ***************************************************************************/
387 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
389 sh1005->share_info_flags = 0;
391 if(lp_host_msdfs() && lp_msdfs_root(snum))
392 sh1005->share_info_flags |=
393 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
394 sh1005->share_info_flags |=
395 lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
397 /***************************************************************************
398 Fill in a share info level 1006 structure.
399 ***************************************************************************/
401 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
403 sh1006->max_uses = -1;
406 /***************************************************************************
407 Fill in a share info level 1007 structure.
408 ***************************************************************************/
410 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
412 pstring alternate_directory_name = "";
413 uint32 flags = 0;
415 ZERO_STRUCTP(sh1007);
417 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
418 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
421 /*******************************************************************
422 Fill in a share info level 1501 structure.
423 ********************************************************************/
425 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
427 SEC_DESC *sd;
428 size_t sd_size;
429 TALLOC_CTX *ctx = p->mem_ctx;
431 ZERO_STRUCTP(sh1501);
433 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
435 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
438 /*******************************************************************
439 True if it ends in '$'.
440 ********************************************************************/
442 static BOOL is_hidden_share(int snum)
444 const char *net_name = lp_servicename(snum);
446 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
449 /*******************************************************************
450 Fill in a share info structure.
451 ********************************************************************/
453 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
454 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
456 int num_entries = 0;
457 int num_services = 0;
458 int snum;
459 TALLOC_CTX *ctx = p->mem_ctx;
461 DEBUG(5,("init_srv_share_info_ctr\n"));
463 ZERO_STRUCTPN(ctr);
465 ctr->info_level = ctr->switch_value = info_level;
466 *resume_hnd = 0;
468 /* Ensure all the usershares are loaded. */
469 become_root();
470 num_services = load_usershare_shares();
471 unbecome_root();
473 /* Count the number of entries. */
474 for (snum = 0; snum < num_services; snum++) {
475 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
476 num_entries++;
479 *total_entries = num_entries;
480 ctr->num_entries2 = ctr->num_entries = num_entries;
481 ctr->ptr_share_info = ctr->ptr_entries = 1;
483 if (!num_entries)
484 return True;
486 switch (info_level) {
487 case 0:
489 SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
490 int i = 0;
492 if (!info0) {
493 return False;
496 for (snum = *resume_hnd; snum < num_services; snum++) {
497 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
498 init_srv_share_info_0(p, &info0[i++], snum);
502 ctr->share.info0 = info0;
503 break;
507 case 1:
509 SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
510 int i = 0;
512 if (!info1) {
513 return False;
516 for (snum = *resume_hnd; snum < num_services; snum++) {
517 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
518 init_srv_share_info_1(p, &info1[i++], snum);
522 ctr->share.info1 = info1;
523 break;
526 case 2:
528 SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
529 int i = 0;
531 if (!info2) {
532 return False;
535 for (snum = *resume_hnd; snum < num_services; snum++) {
536 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
537 init_srv_share_info_2(p, &info2[i++], snum);
541 ctr->share.info2 = info2;
542 break;
545 case 501:
547 SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
548 int i = 0;
550 if (!info501) {
551 return False;
554 for (snum = *resume_hnd; snum < num_services; snum++) {
555 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
556 init_srv_share_info_501(p, &info501[i++], snum);
560 ctr->share.info501 = info501;
561 break;
564 case 502:
566 SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
567 int i = 0;
569 if (!info502) {
570 return False;
573 for (snum = *resume_hnd; snum < num_services; snum++) {
574 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
575 init_srv_share_info_502(p, &info502[i++], snum);
579 ctr->share.info502 = info502;
580 break;
583 /* here for completeness but not currently used with enum (1004 - 1501)*/
585 case 1004:
587 SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
588 int i = 0;
590 if (!info1004) {
591 return False;
594 for (snum = *resume_hnd; snum < num_services; snum++) {
595 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
596 init_srv_share_info_1004(p, &info1004[i++], snum);
600 ctr->share.info1004 = info1004;
601 break;
604 case 1005:
606 SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
607 int i = 0;
609 if (!info1005) {
610 return False;
613 for (snum = *resume_hnd; snum < num_services; snum++) {
614 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
615 init_srv_share_info_1005(p, &info1005[i++], snum);
619 ctr->share.info1005 = info1005;
620 break;
623 case 1006:
625 SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
626 int i = 0;
628 if (!info1006) {
629 return False;
632 for (snum = *resume_hnd; snum < num_services; snum++) {
633 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
634 init_srv_share_info_1006(p, &info1006[i++], snum);
638 ctr->share.info1006 = info1006;
639 break;
642 case 1007:
644 SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
645 int i = 0;
647 if (!info1007) {
648 return False;
651 for (snum = *resume_hnd; snum < num_services; snum++) {
652 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
653 init_srv_share_info_1007(p, &info1007[i++], snum);
657 ctr->share.info1007 = info1007;
658 break;
661 case 1501:
663 SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
664 int i = 0;
666 if (!info1501) {
667 return False;
670 for (snum = *resume_hnd; snum < num_services; snum++) {
671 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
672 init_srv_share_info_1501(p, &info1501[i++], snum);
676 ctr->share.info1501 = info1501;
677 break;
679 default:
680 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
681 return False;
684 return True;
687 /*******************************************************************
688 Inits a SRV_R_NET_SHARE_ENUM structure.
689 ********************************************************************/
691 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
692 uint32 info_level, uint32 resume_hnd, BOOL all)
694 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
696 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
697 &resume_hnd, &r_n->total_entries, all)) {
698 r_n->status = WERR_OK;
699 } else {
700 r_n->status = WERR_UNKNOWN_LEVEL;
703 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
706 /*******************************************************************
707 Inits a SRV_R_NET_SHARE_GET_INFO structure.
708 ********************************************************************/
710 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
711 char *share_name, uint32 info_level)
713 WERROR status = WERR_OK;
714 int snum;
716 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
718 r_n->info.switch_value = info_level;
720 snum = find_service(share_name);
722 if (snum >= 0) {
723 switch (info_level) {
724 case 0:
725 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
726 break;
727 case 1:
728 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
729 break;
730 case 2:
731 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
732 break;
733 case 501:
734 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
735 break;
736 case 502:
737 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
738 break;
740 /* here for completeness */
741 case 1004:
742 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
743 break;
744 case 1005:
745 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
746 break;
748 /* here for completeness 1006 - 1501 */
749 case 1006:
750 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
751 break;
752 case 1007:
753 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
754 break;
755 case 1501:
756 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
757 break;
758 default:
759 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
760 status = WERR_UNKNOWN_LEVEL;
761 break;
763 } else {
764 status = WERR_INVALID_NAME;
767 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
768 r_n->status = status;
771 /*******************************************************************
772 fill in a sess info level 0 structure.
773 ********************************************************************/
775 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
777 struct sessionid *session_list;
778 uint32 num_entries = 0;
779 (*stot) = list_sessions(&session_list);
781 if (ss0 == NULL) {
782 if (snum) {
783 (*snum) = 0;
785 SAFE_FREE(session_list);
786 return;
789 DEBUG(5,("init_srv_sess_0_ss0\n"));
791 if (snum) {
792 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
793 init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
794 num_entries++;
797 ss0->num_entries_read = num_entries;
798 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
799 ss0->num_entries_read2 = num_entries;
801 if ((*snum) >= (*stot)) {
802 (*snum) = 0;
805 } else {
806 ss0->num_entries_read = 0;
807 ss0->ptr_sess_info = 0;
808 ss0->num_entries_read2 = 0;
810 SAFE_FREE(session_list);
813 /*******************************************************************
814 ********************************************************************/
816 /* global needed to make use of the share_mode_forall() callback */
817 static struct sess_file_count s_file_cnt;
819 static void sess_file_fn( const struct share_mode_entry *e,
820 const char *sharepath, const char *fname, void *state )
822 struct sess_file_count *sess = &s_file_cnt;
824 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
825 sess->count++;
828 return;
831 /*******************************************************************
832 ********************************************************************/
834 static int net_count_files( uid_t uid, pid_t pid )
836 s_file_cnt.count = 0;
837 s_file_cnt.uid = uid;
838 s_file_cnt.pid = pid;
840 share_mode_forall( sess_file_fn, NULL );
842 return s_file_cnt.count;
845 /*******************************************************************
846 fill in a sess info level 1 structure.
847 ********************************************************************/
849 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
851 struct sessionid *session_list;
852 uint32 num_entries = 0;
853 time_t now = time(NULL);
855 if ( !snum ) {
856 ss1->num_entries_read = 0;
857 ss1->ptr_sess_info = 0;
858 ss1->num_entries_read2 = 0;
860 (*stot) = 0;
862 return;
865 if (ss1 == NULL) {
866 (*snum) = 0;
867 return;
870 (*stot) = list_sessions(&session_list);
873 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
874 uint32 num_files;
875 uint32 connect_time;
876 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
877 BOOL guest;
879 if ( !pw ) {
880 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
881 session_list[*snum].username));
882 continue;
885 connect_time = (uint32)(now - session_list[*snum].connect_start);
886 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
887 guest = strequal( session_list[*snum].username, lp_guestaccount() );
889 init_srv_sess_info1( &ss1->info_1[num_entries],
890 session_list[*snum].remote_machine,
891 session_list[*snum].username,
892 num_files,
893 connect_time,
895 guest);
896 num_entries++;
899 ss1->num_entries_read = num_entries;
900 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
901 ss1->num_entries_read2 = num_entries;
903 if ((*snum) >= (*stot)) {
904 (*snum) = 0;
907 SAFE_FREE(session_list);
910 /*******************************************************************
911 makes a SRV_R_NET_SESS_ENUM structure.
912 ********************************************************************/
914 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
915 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
917 WERROR status = WERR_OK;
918 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
920 ctr->switch_value = switch_value;
922 switch (switch_value) {
923 case 0:
924 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
925 ctr->ptr_sess_ctr = 1;
926 break;
927 case 1:
928 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
929 ctr->ptr_sess_ctr = 1;
930 break;
931 default:
932 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
933 (*resume_hnd) = 0;
934 (*total_entries) = 0;
935 ctr->ptr_sess_ctr = 0;
936 status = WERR_UNKNOWN_LEVEL;
937 break;
940 return status;
943 /*******************************************************************
944 makes a SRV_R_NET_SESS_ENUM structure.
945 ********************************************************************/
947 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
948 uint32 resume_hnd, int sess_level, int switch_value)
950 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
952 r_n->sess_level = sess_level;
954 if (sess_level == -1)
955 r_n->status = WERR_UNKNOWN_LEVEL;
956 else
957 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
959 if (!W_ERROR_IS_OK(r_n->status))
960 resume_hnd = 0;
962 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
965 /*******************************************************************
966 fill in a conn info level 0 structure.
967 ********************************************************************/
969 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
971 uint32 num_entries = 0;
972 (*stot) = 1;
974 if (ss0 == NULL) {
975 (*snum) = 0;
976 return;
979 DEBUG(5,("init_srv_conn_0_ss0\n"));
981 if (snum) {
982 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
984 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
986 /* move on to creating next connection */
987 /* move on to creating next conn */
988 num_entries++;
991 ss0->num_entries_read = num_entries;
992 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
993 ss0->num_entries_read2 = num_entries;
995 if ((*snum) >= (*stot)) {
996 (*snum) = 0;
999 } else {
1000 ss0->num_entries_read = 0;
1001 ss0->ptr_conn_info = 0;
1002 ss0->num_entries_read2 = 0;
1004 (*stot) = 0;
1008 /*******************************************************************
1009 fill in a conn info level 1 structure.
1010 ********************************************************************/
1012 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1013 uint32 id, uint32 type,
1014 uint32 num_opens, uint32 num_users, uint32 open_time,
1015 const char *usr_name, const char *net_name)
1017 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1018 init_srv_conn_info1_str(str1, usr_name, net_name);
1021 /*******************************************************************
1022 fill in a conn info level 1 structure.
1023 ********************************************************************/
1025 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1027 uint32 num_entries = 0;
1028 (*stot) = 1;
1030 if (ss1 == NULL) {
1031 (*snum) = 0;
1032 return;
1035 DEBUG(5,("init_srv_conn_1_ss1\n"));
1037 if (snum) {
1038 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1039 init_srv_conn_1_info(&ss1->info_1[num_entries],
1040 &ss1->info_1_str[num_entries],
1041 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1043 /* move on to creating next connection */
1044 /* move on to creating next conn */
1045 num_entries++;
1048 ss1->num_entries_read = num_entries;
1049 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1050 ss1->num_entries_read2 = num_entries;
1053 if ((*snum) >= (*stot)) {
1054 (*snum) = 0;
1057 } else {
1058 ss1->num_entries_read = 0;
1059 ss1->ptr_conn_info = 0;
1060 ss1->num_entries_read2 = 0;
1062 (*stot) = 0;
1066 /*******************************************************************
1067 makes a SRV_R_NET_CONN_ENUM structure.
1068 ********************************************************************/
1070 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1071 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1073 WERROR status = WERR_OK;
1074 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1076 ctr->switch_value = switch_value;
1078 switch (switch_value) {
1079 case 0:
1080 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1081 ctr->ptr_conn_ctr = 1;
1082 break;
1083 case 1:
1084 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1085 ctr->ptr_conn_ctr = 1;
1086 break;
1087 default:
1088 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1089 (*resume_hnd = 0);
1090 (*total_entries) = 0;
1091 ctr->ptr_conn_ctr = 0;
1092 status = WERR_UNKNOWN_LEVEL;
1093 break;
1096 return status;
1099 /*******************************************************************
1100 makes a SRV_R_NET_CONN_ENUM structure.
1101 ********************************************************************/
1103 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1104 uint32 resume_hnd, int conn_level, int switch_value)
1106 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1108 r_n->conn_level = conn_level;
1109 if (conn_level == -1)
1110 r_n->status = WERR_UNKNOWN_LEVEL;
1111 else
1112 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1114 if (!W_ERROR_IS_OK(r_n->status))
1115 resume_hnd = 0;
1117 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1120 /*******************************************************************
1121 makes a SRV_R_NET_FILE_ENUM structure.
1122 ********************************************************************/
1124 static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1126 TALLOC_CTX *ctx = get_talloc_ctx();
1127 SRV_FILE_INFO_CTR *ctr = &r->ctr;
1129 /* TODO -- Windows enumerates
1130 (b) active pipes
1131 (c) open directories and files */
1133 r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1134 if ( !W_ERROR_IS_OK(r->status))
1135 goto done;
1137 r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1138 if ( !W_ERROR_IS_OK(r->status))
1139 goto done;
1141 r->level = ctr->level = 3;
1142 r->total_entries = ctr->num_entries;
1143 /* ctr->num_entries = r->total_entries - resume_hnd; */
1144 ctr->num_entries2 = ctr->num_entries;
1145 ctr->ptr_file_info = 1;
1147 r->status = WERR_OK;
1149 done:
1150 if ( ctr->num_entries > 0 )
1151 ctr->ptr_entries = 1;
1153 init_enum_hnd(&r->enum_hnd, 0);
1155 return r->status;
1158 /*******************************************************************
1159 *******************************************************************/
1161 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1163 switch ( q_u->level ) {
1164 case 3:
1165 return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );
1166 default:
1167 return WERR_UNKNOWN_LEVEL;
1170 return WERR_OK;
1173 /*******************************************************************
1174 net server get info
1175 ********************************************************************/
1177 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)
1179 WERROR status = WERR_OK;
1180 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1182 if (!ctr)
1183 return WERR_NOMEM;
1185 ZERO_STRUCTP(ctr);
1187 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1189 if (!pipe_access_check(p)) {
1190 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1191 return WERR_ACCESS_DENIED;
1194 switch (q_u->switch_value) {
1196 /* Technically level 102 should only be available to
1197 Administrators but there isn't anything super-secret
1198 here, as most of it is made up. */
1200 case 102:
1201 init_srv_info_102(&ctr->srv.sv102,
1202 500, global_myname(),
1203 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1204 lp_major_announce_version(), lp_minor_announce_version(),
1205 lp_default_server_announce(),
1206 0xffffffff, /* users */
1207 0xf, /* disc */
1208 0, /* hidden */
1209 240, /* announce */
1210 3000, /* announce delta */
1211 100000, /* licenses */
1212 "c:\\"); /* user path */
1213 break;
1214 case 101:
1215 init_srv_info_101(&ctr->srv.sv101,
1216 500, global_myname(),
1217 lp_major_announce_version(), lp_minor_announce_version(),
1218 lp_default_server_announce(),
1219 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1220 break;
1221 case 100:
1222 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1223 break;
1224 default:
1225 status = WERR_UNKNOWN_LEVEL;
1226 break;
1229 /* set up the net server get info structure */
1230 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1232 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1234 return r_u->status;
1237 /*******************************************************************
1238 net server set info
1239 ********************************************************************/
1241 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)
1243 WERROR status = WERR_OK;
1245 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1247 /* Set up the net server set info structure. */
1249 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1251 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1253 return r_u->status;
1256 /*******************************************************************
1257 net conn enum
1258 ********************************************************************/
1260 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1262 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1264 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1265 if (!r_u->ctr)
1266 return WERR_NOMEM;
1268 ZERO_STRUCTP(r_u->ctr);
1270 /* set up the */
1271 init_srv_r_net_conn_enum(r_u,
1272 get_enum_hnd(&q_u->enum_hnd),
1273 q_u->conn_level,
1274 q_u->ctr->switch_value);
1276 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1278 return r_u->status;
1281 /*******************************************************************
1282 net sess enum
1283 ********************************************************************/
1285 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1287 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1289 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1290 if (!r_u->ctr)
1291 return WERR_NOMEM;
1293 ZERO_STRUCTP(r_u->ctr);
1295 /* set up the */
1296 init_srv_r_net_sess_enum(r_u,
1297 get_enum_hnd(&q_u->enum_hnd),
1298 q_u->sess_level,
1299 q_u->ctr->switch_value);
1301 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1303 return r_u->status;
1306 /*******************************************************************
1307 net sess del
1308 ********************************************************************/
1310 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1312 struct sessionid *session_list;
1313 struct current_user user;
1314 int num_sessions, snum;
1315 fstring username;
1316 fstring machine;
1317 BOOL not_root = False;
1319 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1320 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1322 /* strip leading backslashes if any */
1323 while (machine[0] == '\\') {
1324 memmove(machine, &machine[1], strlen(machine));
1327 num_sessions = list_sessions(&session_list);
1329 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1331 r_u->status = WERR_ACCESS_DENIED;
1333 get_current_user(&user, p);
1335 /* fail out now if you are not root or not a domain admin */
1337 if ((user.ut.uid != sec_initial_uid()) &&
1338 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1340 goto done;
1343 for (snum = 0; snum < num_sessions; snum++) {
1345 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1346 strequal(session_list[snum].remote_machine, machine)) {
1348 if (user.ut.uid != sec_initial_uid()) {
1349 not_root = True;
1350 become_root();
1353 if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)))
1354 r_u->status = WERR_OK;
1356 if (not_root)
1357 unbecome_root();
1361 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1364 done:
1365 SAFE_FREE(session_list);
1367 return r_u->status;
1370 /*******************************************************************
1371 Net share enum all.
1372 ********************************************************************/
1374 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1376 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1378 if (!pipe_access_check(p)) {
1379 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1380 return WERR_ACCESS_DENIED;
1383 /* Create the list of shares for the response. */
1384 init_srv_r_net_share_enum(p, r_u,
1385 q_u->ctr.info_level,
1386 get_enum_hnd(&q_u->enum_hnd), True);
1388 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1390 return r_u->status;
1393 /*******************************************************************
1394 Net share enum.
1395 ********************************************************************/
1397 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1399 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1401 if (!pipe_access_check(p)) {
1402 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1403 return WERR_ACCESS_DENIED;
1406 /* Create the list of shares for the response. */
1407 init_srv_r_net_share_enum(p, r_u,
1408 q_u->ctr.info_level,
1409 get_enum_hnd(&q_u->enum_hnd), False);
1411 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1413 return r_u->status;
1416 /*******************************************************************
1417 Net share get info.
1418 ********************************************************************/
1420 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)
1422 fstring share_name;
1424 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1426 /* Create the list of shares for the response. */
1427 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1428 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1430 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1432 return r_u->status;
1435 /*******************************************************************
1436 Check a given DOS pathname is valid for a share.
1437 ********************************************************************/
1439 char *valid_share_pathname(char *dos_pathname)
1441 char *ptr;
1443 /* Convert any '\' paths to '/' */
1444 unix_format(dos_pathname);
1445 unix_clean_name(dos_pathname);
1447 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1448 ptr = dos_pathname;
1449 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1450 ptr += 2;
1452 /* Only absolute paths allowed. */
1453 if (*ptr != '/')
1454 return NULL;
1456 return ptr;
1459 /*******************************************************************
1460 Net share set info. Modify share details.
1461 ********************************************************************/
1463 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)
1465 struct current_user user;
1466 pstring command;
1467 fstring share_name;
1468 fstring comment;
1469 pstring pathname;
1470 int type;
1471 int snum;
1472 int ret;
1473 char *path;
1474 SEC_DESC *psd = NULL;
1475 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1476 BOOL is_disk_op = False;
1477 int max_connections = 0;
1479 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1481 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1483 r_u->parm_error = 0;
1485 if ( strequal(share_name,"IPC$")
1486 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1487 || strequal(share_name,"global") )
1489 return WERR_ACCESS_DENIED;
1492 snum = find_service(share_name);
1494 /* Does this share exist ? */
1495 if (snum < 0)
1496 return WERR_NET_NAME_NOT_FOUND;
1498 /* No change to printer shares. */
1499 if (lp_print_ok(snum))
1500 return WERR_ACCESS_DENIED;
1502 get_current_user(&user,p);
1504 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1506 /* fail out now if you are not root and not a disk op */
1508 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1509 return WERR_ACCESS_DENIED;
1511 switch (q_u->info_level) {
1512 case 1:
1513 pstrcpy(pathname, lp_pathname(snum));
1514 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1515 type = q_u->info.share.info2.info_2.type;
1516 psd = NULL;
1517 break;
1518 case 2:
1519 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1520 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1521 type = q_u->info.share.info2.info_2.type;
1522 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1523 psd = NULL;
1524 break;
1525 #if 0
1526 /* not supported on set but here for completeness */
1527 case 501:
1528 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1529 type = q_u->info.share.info501.info_501.type;
1530 psd = NULL;
1531 break;
1532 #endif
1533 case 502:
1534 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1535 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1536 type = q_u->info.share.info502.info_502.type;
1537 psd = q_u->info.share.info502.info_502_str.sd;
1538 map_generic_share_sd_bits(psd);
1539 break;
1540 case 1004:
1541 pstrcpy(pathname, lp_pathname(snum));
1542 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1543 type = STYPE_DISKTREE;
1544 break;
1545 case 1005:
1546 /* XP re-sets the csc policy even if it wasn't changed by the
1547 user, so we must compare it to see if it's what is set in
1548 smb.conf, so that we can contine other ops like setting
1549 ACLs on a share */
1550 if (((q_u->info.share.info1005.share_info_flags &
1551 SHARE_1005_CSC_POLICY_MASK) >>
1552 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1553 return WERR_OK;
1554 else {
1555 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1556 return WERR_ACCESS_DENIED;
1558 case 1006:
1559 case 1007:
1560 return WERR_ACCESS_DENIED;
1561 case 1501:
1562 pstrcpy(pathname, lp_pathname(snum));
1563 fstrcpy(comment, lp_comment(snum));
1564 psd = q_u->info.share.info1501.sdb->sec;
1565 map_generic_share_sd_bits(psd);
1566 type = STYPE_DISKTREE;
1567 break;
1568 default:
1569 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1570 return WERR_UNKNOWN_LEVEL;
1573 /* We can only modify disk shares. */
1574 if (type != STYPE_DISKTREE)
1575 return WERR_ACCESS_DENIED;
1577 /* Check if the pathname is valid. */
1578 if (!(path = valid_share_pathname( pathname )))
1579 return WERR_OBJECT_PATH_INVALID;
1581 /* Ensure share name, pathname and comment don't contain '"' characters. */
1582 string_replace(share_name, '"', ' ');
1583 string_replace(path, '"', ' ');
1584 string_replace(comment, '"', ' ');
1586 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1587 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1589 /* Only call modify function if something changed. */
1591 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1592 || (lp_max_connections(snum) != max_connections) )
1594 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1595 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1596 return WERR_ACCESS_DENIED;
1599 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1600 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1602 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1604 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1606 if ( is_disk_op )
1607 become_root();
1609 if ( (ret = smbrun(command, NULL)) == 0 ) {
1610 /* Tell everyone we updated smb.conf. */
1611 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1614 if ( is_disk_op )
1615 unbecome_root();
1617 /********* END SeDiskOperatorPrivilege BLOCK *********/
1619 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1621 if ( ret != 0 )
1622 return WERR_ACCESS_DENIED;
1623 } else {
1624 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1627 /* Replace SD if changed. */
1628 if (psd) {
1629 SEC_DESC *old_sd;
1630 size_t sd_size;
1632 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1634 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1635 if (!set_share_security(share_name, psd))
1636 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1637 share_name ));
1641 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1643 return WERR_OK;
1646 /*******************************************************************
1647 Net share add. Call 'add_share_command "sharename" "pathname"
1648 "comment" "max connections = "
1649 ********************************************************************/
1651 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1653 struct current_user user;
1654 pstring command;
1655 fstring share_name;
1656 fstring comment;
1657 pstring pathname;
1658 int type;
1659 int snum;
1660 int ret;
1661 char *path;
1662 SEC_DESC *psd = NULL;
1663 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1664 BOOL is_disk_op;
1665 int max_connections = 0;
1667 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1669 r_u->parm_error = 0;
1671 get_current_user(&user,p);
1673 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1675 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1676 return WERR_ACCESS_DENIED;
1678 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1679 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1680 return WERR_ACCESS_DENIED;
1683 switch (q_u->info_level) {
1684 case 0:
1685 /* No path. Not enough info in a level 0 to do anything. */
1686 return WERR_ACCESS_DENIED;
1687 case 1:
1688 /* Not enough info in a level 1 to do anything. */
1689 return WERR_ACCESS_DENIED;
1690 case 2:
1691 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1692 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1693 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1694 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1695 type = q_u->info.share.info2.info_2.type;
1696 break;
1697 case 501:
1698 /* No path. Not enough info in a level 501 to do anything. */
1699 return WERR_ACCESS_DENIED;
1700 case 502:
1701 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1702 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1703 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1704 type = q_u->info.share.info502.info_502.type;
1705 psd = q_u->info.share.info502.info_502_str.sd;
1706 map_generic_share_sd_bits(psd);
1707 break;
1709 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1711 case 1004:
1712 case 1005:
1713 case 1006:
1714 case 1007:
1715 return WERR_ACCESS_DENIED;
1716 case 1501:
1717 /* DFS only level. */
1718 return WERR_ACCESS_DENIED;
1719 default:
1720 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1721 return WERR_UNKNOWN_LEVEL;
1724 /* check for invalid share names */
1726 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1727 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1728 return WERR_INVALID_NAME;
1731 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1732 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1734 return WERR_ACCESS_DENIED;
1737 snum = find_service(share_name);
1739 /* Share already exists. */
1740 if (snum >= 0)
1741 return WERR_ALREADY_EXISTS;
1743 /* We can only add disk shares. */
1744 if (type != STYPE_DISKTREE)
1745 return WERR_ACCESS_DENIED;
1747 /* Check if the pathname is valid. */
1748 if (!(path = valid_share_pathname( pathname )))
1749 return WERR_OBJECT_PATH_INVALID;
1751 /* Ensure share name, pathname and comment don't contain '"' characters. */
1752 string_replace(share_name, '"', ' ');
1753 string_replace(path, '"', ' ');
1754 string_replace(comment, '"', ' ');
1756 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1757 lp_add_share_cmd(),
1758 dyn_CONFIGFILE,
1759 share_name,
1760 path,
1761 comment,
1762 max_connections);
1764 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1766 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1768 if ( is_disk_op )
1769 become_root();
1771 if ( (ret = smbrun(command, NULL)) == 0 ) {
1772 /* Tell everyone we updated smb.conf. */
1773 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1776 if ( is_disk_op )
1777 unbecome_root();
1779 /********* END SeDiskOperatorPrivilege BLOCK *********/
1781 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1783 if ( ret != 0 )
1784 return WERR_ACCESS_DENIED;
1786 if (psd) {
1787 if (!set_share_security(share_name, psd)) {
1788 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1793 * We don't call reload_services() here, the message will
1794 * cause this to be done before the next packet is read
1795 * from the client. JRA.
1798 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1800 return WERR_OK;
1803 /*******************************************************************
1804 Net share delete. Call "delete share command" with the share name as
1805 a parameter.
1806 ********************************************************************/
1808 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1810 struct current_user user;
1811 pstring command;
1812 fstring share_name;
1813 int ret;
1814 int snum;
1815 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1816 BOOL is_disk_op;
1817 struct share_params *params;
1819 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1821 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1823 if ( strequal(share_name,"IPC$")
1824 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1825 || strequal(share_name,"global") )
1827 return WERR_ACCESS_DENIED;
1830 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1831 return WERR_NO_SUCH_SHARE;
1834 snum = find_service(share_name);
1836 /* No change to printer shares. */
1837 if (lp_print_ok(snum))
1838 return WERR_ACCESS_DENIED;
1840 get_current_user(&user,p);
1842 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1844 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1845 return WERR_ACCESS_DENIED;
1847 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1848 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1849 return WERR_ACCESS_DENIED;
1852 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1853 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1855 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1857 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1859 if ( is_disk_op )
1860 become_root();
1862 if ( (ret = smbrun(command, NULL)) == 0 ) {
1863 /* Tell everyone we updated smb.conf. */
1864 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1867 if ( is_disk_op )
1868 unbecome_root();
1870 /********* END SeDiskOperatorPrivilege BLOCK *********/
1872 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1874 if ( ret != 0 )
1875 return WERR_ACCESS_DENIED;
1877 /* Delete the SD in the database. */
1878 delete_share_security(params);
1880 lp_killservice(params->service);
1882 return WERR_OK;
1885 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1887 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1889 return _srv_net_share_del(p, q_u, r_u);
1892 /*******************************************************************
1893 time of day
1894 ********************************************************************/
1896 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1898 TIME_OF_DAY_INFO *tod;
1899 struct tm *t;
1900 time_t unixdate = time(NULL);
1902 /* We do this call first as if we do it *after* the gmtime call
1903 it overwrites the pointed-to values. JRA */
1905 uint32 zone = get_time_zone(unixdate)/60;
1907 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1909 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1910 return WERR_NOMEM;
1912 r_u->tod = tod;
1913 r_u->ptr_srv_tod = 0x1;
1914 r_u->status = WERR_OK;
1916 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1918 t = gmtime(&unixdate);
1920 /* set up the */
1921 init_time_of_day_info(tod,
1922 unixdate,
1924 t->tm_hour,
1925 t->tm_min,
1926 t->tm_sec,
1928 zone,
1929 10000,
1930 t->tm_mday,
1931 t->tm_mon + 1,
1932 1900+t->tm_year,
1933 t->tm_wday);
1935 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1937 return r_u->status;
1940 /***********************************************************************************
1941 Win9x NT tools get security descriptor.
1942 ***********************************************************************************/
1944 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1945 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1947 SEC_DESC *psd = NULL;
1948 size_t sd_size;
1949 DATA_BLOB null_pw;
1950 pstring filename;
1951 pstring qualname;
1952 files_struct *fsp = NULL;
1953 SMB_STRUCT_STAT st;
1954 NTSTATUS nt_status;
1955 struct current_user user;
1956 connection_struct *conn = NULL;
1957 BOOL became_user = False;
1959 ZERO_STRUCT(st);
1961 r_u->status = WERR_OK;
1963 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1965 /* Null password is ok - we are already an authenticated user... */
1966 null_pw = data_blob(NULL, 0);
1968 get_current_user(&user, p);
1970 become_root();
1971 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1972 unbecome_root();
1974 if (conn == NULL) {
1975 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1976 r_u->status = ntstatus_to_werror(nt_status);
1977 goto error_exit;
1980 if (!become_user(conn, conn->vuid)) {
1981 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1982 r_u->status = WERR_ACCESS_DENIED;
1983 goto error_exit;
1985 became_user = True;
1987 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1988 nt_status = unix_convert(conn, filename, False, NULL, &st);
1989 if (!NT_STATUS_IS_OK(nt_status)) {
1990 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1991 r_u->status = WERR_ACCESS_DENIED;
1992 goto error_exit;
1995 nt_status = check_name(conn, filename);
1996 if (!NT_STATUS_IS_OK(nt_status)) {
1997 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
1998 r_u->status = WERR_ACCESS_DENIED;
1999 goto error_exit;
2002 nt_status = open_file_stat(conn, filename, &st, &fsp);
2003 if ( !NT_STATUS_IS_OK(nt_status)) {
2004 /* Perhaps it is a directory */
2005 if (errno == EISDIR)
2006 nt_status = open_directory(conn, filename, &st,
2007 READ_CONTROL_ACCESS,
2008 FILE_SHARE_READ|FILE_SHARE_WRITE,
2009 FILE_OPEN,
2011 FILE_ATTRIBUTE_DIRECTORY,
2012 NULL, &fsp);
2014 if (!NT_STATUS_IS_OK(nt_status)) {
2015 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2016 r_u->status = ntstatus_to_werror(nt_status);
2017 goto error_exit;
2021 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2023 if (sd_size == 0) {
2024 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2025 r_u->status = WERR_ACCESS_DENIED;
2026 goto error_exit;
2029 r_u->ptr_response = 1;
2030 r_u->size_response = sd_size;
2031 r_u->ptr_secdesc = 1;
2032 r_u->size_secdesc = sd_size;
2033 r_u->sec_desc = psd;
2035 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2037 close_file(fsp, NORMAL_CLOSE);
2038 unbecome_user();
2039 close_cnum(conn, user.vuid);
2040 return r_u->status;
2042 error_exit:
2044 if(fsp) {
2045 close_file(fsp, NORMAL_CLOSE);
2048 if (became_user)
2049 unbecome_user();
2051 if (conn)
2052 close_cnum(conn, user.vuid);
2054 return r_u->status;
2057 /***********************************************************************************
2058 Win9x NT tools set security descriptor.
2059 ***********************************************************************************/
2061 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2062 SRV_R_NET_FILE_SET_SECDESC *r_u)
2064 BOOL ret;
2065 pstring filename;
2066 pstring qualname;
2067 DATA_BLOB null_pw;
2068 files_struct *fsp = NULL;
2069 SMB_STRUCT_STAT st;
2070 NTSTATUS nt_status;
2071 struct current_user user;
2072 connection_struct *conn = NULL;
2073 BOOL became_user = False;
2075 ZERO_STRUCT(st);
2077 r_u->status = WERR_OK;
2079 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2081 /* Null password is ok - we are already an authenticated user... */
2082 null_pw = data_blob(NULL, 0);
2084 get_current_user(&user, p);
2086 become_root();
2087 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2088 unbecome_root();
2090 if (conn == NULL) {
2091 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2092 r_u->status = ntstatus_to_werror(nt_status);
2093 goto error_exit;
2096 if (!become_user(conn, conn->vuid)) {
2097 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2098 r_u->status = WERR_ACCESS_DENIED;
2099 goto error_exit;
2101 became_user = True;
2103 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2104 nt_status = unix_convert(conn, filename, False, NULL, &st);
2105 if (!NT_STATUS_IS_OK(nt_status)) {
2106 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2107 r_u->status = WERR_ACCESS_DENIED;
2108 goto error_exit;
2111 nt_status = check_name(conn, filename);
2112 if (!NT_STATUS_IS_OK(nt_status)) {
2113 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2114 r_u->status = WERR_ACCESS_DENIED;
2115 goto error_exit;
2119 nt_status = open_file_stat(conn, filename, &st, &fsp);
2121 if ( !NT_STATUS_IS_OK(nt_status) ) {
2122 /* Perhaps it is a directory */
2123 if (errno == EISDIR)
2124 nt_status = open_directory(conn, filename, &st,
2125 FILE_READ_ATTRIBUTES,
2126 FILE_SHARE_READ|FILE_SHARE_WRITE,
2127 FILE_OPEN,
2129 FILE_ATTRIBUTE_DIRECTORY,
2130 NULL, &fsp);
2132 if ( !NT_STATUS_IS_OK(nt_status) ) {
2133 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2134 r_u->status = ntstatus_to_werror(nt_status);
2135 goto error_exit;
2139 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2141 if (ret == False) {
2142 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2143 r_u->status = WERR_ACCESS_DENIED;
2144 goto error_exit;
2147 close_file(fsp, NORMAL_CLOSE);
2148 unbecome_user();
2149 close_cnum(conn, user.vuid);
2150 return r_u->status;
2152 error_exit:
2154 if(fsp) {
2155 close_file(fsp, NORMAL_CLOSE);
2158 if (became_user) {
2159 unbecome_user();
2162 if (conn) {
2163 close_cnum(conn, user.vuid);
2166 return r_u->status;
2169 /***********************************************************************************
2170 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2171 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2172 These disks would the disks listed by this function.
2173 Users could then create shares relative to these disks. Watch out for moving these disks around.
2174 "Nigel Williams" <nigel@veritas.com>.
2175 ***********************************************************************************/
2177 static const char *server_disks[] = {"C:"};
2179 static uint32 get_server_disk_count(void)
2181 return sizeof(server_disks)/sizeof(server_disks[0]);
2184 static uint32 init_server_disk_enum(uint32 *resume)
2186 uint32 server_disk_count = get_server_disk_count();
2188 /*resume can be an offset into the list for now*/
2190 if(*resume & 0x80000000)
2191 *resume = 0;
2193 if(*resume > server_disk_count)
2194 *resume = server_disk_count;
2196 return server_disk_count - *resume;
2199 static const char *next_server_disk_enum(uint32 *resume)
2201 const char *disk;
2203 if(init_server_disk_enum(resume) == 0)
2204 return NULL;
2206 disk = server_disks[*resume];
2208 (*resume)++;
2210 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2212 return disk;
2215 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2217 uint32 i;
2218 const char *disk_name;
2219 TALLOC_CTX *ctx = p->mem_ctx;
2220 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2222 r_u->status=WERR_OK;
2224 r_u->total_entries = init_server_disk_enum(&resume);
2226 r_u->disk_enum_ctr.unknown = 0;
2228 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2229 return WERR_NOMEM;
2232 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2234 /*allow one DISK_INFO for null terminator*/
2236 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2238 r_u->disk_enum_ctr.entries_read++;
2240 /*copy disk name into a unicode string*/
2242 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2245 /* add a terminating null string. Is this there if there is more data to come? */
2247 r_u->disk_enum_ctr.entries_read++;
2249 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2251 init_enum_hnd(&r_u->enum_hnd, resume);
2253 return r_u->status;
2256 /********************************************************************
2257 ********************************************************************/
2259 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2261 fstring sharename;
2263 switch ( q_u->type ) {
2264 case 0x9:
2265 rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2266 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2267 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2268 return WERR_INVALID_NAME;
2270 break;
2272 default:
2273 return WERR_UNKNOWN_LEVEL;
2276 return WERR_OK;
2280 /********************************************************************
2281 ********************************************************************/
2283 WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2285 return WERR_ACCESS_DENIED;