source: branches/samba-3.0/source/rpc_server/srv_srvsvc_nt.c@ 165

Last change on this file since 165 was 165, checked in by Paul Smedley, 17 years ago

Add 'missing' 3.0.34 diffs

File size: 61.4 KB
Line 
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.
13 *
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.
18 *
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.
22 */
23
24/* This is the implementation of the srvsvc pipe. */
25
26#include "includes.h"
27
28extern struct generic_mapping file_generic_mapping;
29
30#undef DBGC_CLASS
31#define DBGC_CLASS DBGC_RPC_SRV
32
33/* Use for enumerating connections, pipes, & files */
34
35struct file_enum_count {
36 TALLOC_CTX *ctx;
37 int count;
38 FILE_INFO_3 *info;
39};
40
41struct sess_file_count {
42 pid_t pid;
43 uid_t uid;
44 int count;
45};
46
47/****************************************************************************
48 Count the entries belonging to a service in the connection db.
49****************************************************************************/
50
51static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
52{
53 struct pipe_open_rec prec;
54 struct file_enum_count *fenum = (struct file_enum_count *)p;
55
56 if (dbuf.dsize != sizeof(struct pipe_open_rec))
57 return 0;
58
59 memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
60
61 if ( process_exists(prec.pid) ) {
62 FILE_INFO_3 *f;
63 int i = fenum->count;
64 pstring fullpath;
65
66 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
67
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;
72 }
73 fenum->info = f;
74
75
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),
79 0,
80 uidtoname( prec.uid ),
81 fullpath );
82
83 fenum->count++;
84 }
85
86 return 0;
87}
88
89/*******************************************************************
90********************************************************************/
91
92static WERROR net_enum_pipes( TALLOC_CTX *ctx, FILE_INFO_3 **info,
93 uint32 *count, uint32 resume )
94{
95 struct file_enum_count fenum;
96 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
97
98 if ( !conn_tdb ) {
99 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
100 return WERR_ACCESS_DENIED;
101 }
102
103 fenum.ctx = ctx;
104 fenum.count = *count;
105 fenum.info = *info;
106
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;
111 }
112
113 *info = fenum.info;
114 *count = fenum.count;
115
116 return WERR_OK;}
117
118/*******************************************************************
119********************************************************************/
120
121/* global needed to make use of the share_mode_forall() callback */
122static struct file_enum_count f_enum_cnt;
123
124static void enum_file_fn( const struct share_mode_entry *e,
125 const char *sharepath, const char *fname, void *state )
126{
127 struct file_enum_count *fenum = &f_enum_cnt;
128
129 /* If the pid was not found delete the entry from connections.tdb */
130
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;
139
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;
144 }
145 fenum->info = f;
146
147 /* need to count the number of locks on a file */
148
149 ZERO_STRUCT( fsp );
150 fsp.dev = e->dev;
151 fsp.inode = e->inode;
152
153 if ( (brl = brl_get_locks(NULL,&fsp)) != NULL ) {
154 num_locks = brl->num_locks;
155 TALLOC_FREE( brl );
156 }
157
158 if ( strcmp( fname, "." ) == 0 ) {
159 pstr_sprintf( fullpath, "C:%s", sharepath );
160 } else {
161 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
162 }
163 string_replace( fullpath, '/', '\\' );
164
165 /* mask out create (what ever that is) */
166 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
167
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 );
175
176 fenum->count++;
177 }
178
179 return;
180
181}
182
183/*******************************************************************
184********************************************************************/
185
186static WERROR net_enum_files( TALLOC_CTX *ctx, FILE_INFO_3 **info,
187 uint32 *count, uint32 resume )
188{
189 f_enum_cnt.ctx = ctx;
190 f_enum_cnt.count = *count;
191 f_enum_cnt.info = *info;
192
193 share_mode_forall( enum_file_fn, NULL );
194
195 *info = f_enum_cnt.info;
196 *count = f_enum_cnt.count;
197
198 return WERR_OK;
199}
200
201/*******************************************************************
202 Utility function to get the 'type' of a share from an snum.
203 ********************************************************************/
204static uint32 get_share_type(int snum)
205{
206 /* work out the share type */
207 uint32 type = STYPE_DISKTREE;
208
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;
215
216 return type;
217}
218
219/*******************************************************************
220 Fill in a share info level 0 structure.
221 ********************************************************************/
222
223static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
224{
225 pstring net_name;
226
227 pstrcpy(net_name, lp_servicename(snum));
228
229 init_srv_share_info0(&sh0->info_0, net_name);
230 init_srv_share_info0_str(&sh0->info_0_str, net_name);
231}
232
233/*******************************************************************
234 Fill in a share info level 1 structure.
235 ********************************************************************/
236
237static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
238{
239 pstring remark;
240
241 char *net_name = lp_servicename(snum);
242 pstrcpy(remark, lp_comment(snum));
243 standard_sub_conn(p->conn, remark,sizeof(remark));
244
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);
247}
248
249/*******************************************************************
250 Fill in a share info level 2 structure.
251 ********************************************************************/
252
253static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
254{
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);
262
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));
267
268 /*
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.
271 */
272
273 string_replace(path, '/', '\\');
274
275 pstrcpy(passwd, "");
276
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);
280
281 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
282}
283
284/*******************************************************************
285 Map any generic bits to file specific bits.
286********************************************************************/
287
288static void map_generic_share_sd_bits(SEC_DESC *psd)
289{
290 int i;
291 SEC_ACL *ps_dacl = NULL;
292
293 if (!psd)
294 return;
295
296 ps_dacl = psd->dacl;
297 if (!ps_dacl)
298 return;
299
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;
303
304 se_map_generic(&psa->access_mask, &file_generic_mapping);
305 psa->access_mask |= orig_mask;
306 }
307}
308
309/*******************************************************************
310 Fill in a share info level 501 structure.
311********************************************************************/
312
313static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
314{
315 pstring remark;
316
317 const char *net_name = lp_servicename(snum);
318 pstrcpy(remark, lp_comment(snum));
319 standard_sub_conn(p->conn, remark, sizeof(remark));
320
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);
323}
324
325/*******************************************************************
326 Fill in a share info level 502 structure.
327 ********************************************************************/
328
329static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
330{
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;
338
339
340 ZERO_STRUCTP(sh502);
341
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));
347
348 /*
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.
351 */
352
353 string_replace(path, '/', '\\');
354
355 pstrcpy(passwd, "");
356
357 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
358
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);
361}
362
363/***************************************************************************
364 Fill in a share info level 1004 structure.
365 ***************************************************************************/
366
367static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
368{
369 pstring remark;
370
371 pstrcpy(remark, lp_comment(snum));
372 standard_sub_conn(p->conn, remark, sizeof(remark));
373
374 ZERO_STRUCTP(sh1004);
375
376 init_srv_share_info1004(&sh1004->info_1004, remark);
377 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
378}
379
380/***************************************************************************
381 Fill in a share info level 1005 structure.
382 ***************************************************************************/
383
384static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
385{
386 sh1005->share_info_flags = 0;
387
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;
393}
394/***************************************************************************
395 Fill in a share info level 1006 structure.
396 ***************************************************************************/
397
398static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
399{
400 sh1006->max_uses = -1;
401}
402
403/***************************************************************************
404 Fill in a share info level 1007 structure.
405 ***************************************************************************/
406
407static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
408{
409 pstring alternate_directory_name = "";
410 uint32 flags = 0;
411
412 ZERO_STRUCTP(sh1007);
413
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);
416}
417
418/*******************************************************************
419 Fill in a share info level 1501 structure.
420 ********************************************************************/
421
422static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
423{
424 SEC_DESC *sd;
425 size_t sd_size;
426 TALLOC_CTX *ctx = p->mem_ctx;
427
428 ZERO_STRUCTP(sh1501);
429
430 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
431
432 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
433}
434
435/*******************************************************************
436 True if it ends in '$'.
437 ********************************************************************/
438
439static BOOL is_hidden_share(int snum)
440{
441 const char *net_name = lp_servicename(snum);
442
443 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
444}
445
446/*******************************************************************
447 Fill in a share info structure.
448 ********************************************************************/
449
450static 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)
452{
453 int num_entries = 0;
454 int num_services = 0;
455 int snum;
456 TALLOC_CTX *ctx = p->mem_ctx;
457
458 DEBUG(5,("init_srv_share_info_ctr\n"));
459
460 ZERO_STRUCTPN(ctr);
461
462 ctr->info_level = ctr->switch_value = info_level;
463 *resume_hnd = 0;
464
465 /* Ensure all the usershares are loaded. */
466 become_root();
467 num_services = load_usershare_shares();
468 unbecome_root();
469
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++;
474 }
475
476 *total_entries = num_entries;
477 ctr->num_entries2 = ctr->num_entries = num_entries;
478 ctr->ptr_share_info = ctr->ptr_entries = 1;
479
480 if (!num_entries)
481 return True;
482
483 switch (info_level) {
484 case 0:
485 {
486 SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
487 int i = 0;
488
489 if (!info0) {
490 return False;
491 }
492
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);
496 }
497 }
498
499 ctr->share.info0 = info0;
500 break;
501
502 }
503
504 case 1:
505 {
506 SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
507 int i = 0;
508
509 if (!info1) {
510 return False;
511 }
512
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);
516 }
517 }
518
519 ctr->share.info1 = info1;
520 break;
521 }
522
523 case 2:
524 {
525 SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
526 int i = 0;
527
528 if (!info2) {
529 return False;
530 }
531
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);
535 }
536 }
537
538 ctr->share.info2 = info2;
539 break;
540 }
541
542 case 501:
543 {
544 SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
545 int i = 0;
546
547 if (!info501) {
548 return False;
549 }
550
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);
554 }
555 }
556
557 ctr->share.info501 = info501;
558 break;
559 }
560
561 case 502:
562 {
563 SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
564 int i = 0;
565
566 if (!info502) {
567 return False;
568 }
569
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);
573 }
574 }
575
576 ctr->share.info502 = info502;
577 break;
578 }
579
580 /* here for completeness but not currently used with enum (1004 - 1501)*/
581
582 case 1004:
583 {
584 SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
585 int i = 0;
586
587 if (!info1004) {
588 return False;
589 }
590
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);
594 }
595 }
596
597 ctr->share.info1004 = info1004;
598 break;
599 }
600
601 case 1005:
602 {
603 SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
604 int i = 0;
605
606 if (!info1005) {
607 return False;
608 }
609
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);
613 }
614 }
615
616 ctr->share.info1005 = info1005;
617 break;
618 }
619
620 case 1006:
621 {
622 SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
623 int i = 0;
624
625 if (!info1006) {
626 return False;
627 }
628
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);
632 }
633 }
634
635 ctr->share.info1006 = info1006;
636 break;
637 }
638
639 case 1007:
640 {
641 SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
642 int i = 0;
643
644 if (!info1007) {
645 return False;
646 }
647
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);
651 }
652 }
653
654 ctr->share.info1007 = info1007;
655 break;
656 }
657
658 case 1501:
659 {
660 SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
661 int i = 0;
662
663 if (!info1501) {
664 return False;
665 }
666
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);
670 }
671 }
672
673 ctr->share.info1501 = info1501;
674 break;
675 }
676 default:
677 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
678 return False;
679 }
680
681 return True;
682}
683
684/*******************************************************************
685 Inits a SRV_R_NET_SHARE_ENUM structure.
686********************************************************************/
687
688static 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)
690{
691 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
692
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;
698 }
699
700 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
701}
702
703/*******************************************************************
704 Inits a SRV_R_NET_SHARE_GET_INFO structure.
705********************************************************************/
706
707static 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)
709{
710 WERROR status = WERR_OK;
711 int snum;
712
713 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
714
715 r_n->info.switch_value = info_level;
716
717 snum = find_service(share_name);
718
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;
736
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;
744
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;
759 }
760 } else {
761 status = WERR_INVALID_NAME;
762 }
763
764 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
765 r_n->status = status;
766}
767
768/*******************************************************************
769 fill in a sess info level 0 structure.
770 ********************************************************************/
771
772static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
773{
774 struct sessionid *session_list;
775 uint32 num_entries = 0;
776 (*stot) = list_sessions(&session_list);
777
778 if (ss0 == NULL) {
779 if (snum) {
780 (*snum) = 0;
781 }
782 SAFE_FREE(session_list);
783 return;
784 }
785
786 DEBUG(5,("init_srv_sess_0_ss0\n"));
787
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++;
792 }
793
794 ss0->num_entries_read = num_entries;
795 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
796 ss0->num_entries_read2 = num_entries;
797
798 if ((*snum) >= (*stot)) {
799 (*snum) = 0;
800 }
801
802 } else {
803 ss0->num_entries_read = 0;
804 ss0->ptr_sess_info = 0;
805 ss0->num_entries_read2 = 0;
806 }
807 SAFE_FREE(session_list);
808}
809
810/*******************************************************************
811********************************************************************/
812
813/* global needed to make use of the share_mode_forall() callback */
814static struct sess_file_count s_file_cnt;
815
816static void sess_file_fn( const struct share_mode_entry *e,
817 const char *sharepath, const char *fname, void *state )
818{
819 struct sess_file_count *sess = &s_file_cnt;
820
821 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
822 sess->count++;
823 }
824
825 return;
826}
827
828/*******************************************************************
829********************************************************************/
830
831static int net_count_files( uid_t uid, pid_t pid )
832{
833 s_file_cnt.count = 0;
834 s_file_cnt.uid = uid;
835 s_file_cnt.pid = pid;
836
837 share_mode_forall( sess_file_fn, NULL );
838
839 return s_file_cnt.count;
840}
841
842/*******************************************************************
843 fill in a sess info level 1 structure.
844 ********************************************************************/
845
846static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
847{
848 struct sessionid *session_list;
849 uint32 num_entries = 0;
850 time_t now = time(NULL);
851
852 if ( !snum ) {
853 ss1->num_entries_read = 0;
854 ss1->ptr_sess_info = 0;
855 ss1->num_entries_read2 = 0;
856
857 (*stot) = 0;
858
859 return;
860 }
861
862 if (ss1 == NULL) {
863 (*snum) = 0;
864 return;
865 }
866
867 (*stot) = list_sessions(&session_list);
868
869
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;
875
876 if ( !pw ) {
877 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
878 session_list[*snum].username));
879 continue;
880 }
881
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() );
885
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,
891 0,
892 guest);
893 num_entries++;
894 }
895
896 ss1->num_entries_read = num_entries;
897 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
898 ss1->num_entries_read2 = num_entries;
899
900 if ((*snum) >= (*stot)) {
901 (*snum) = 0;
902 }
903
904 SAFE_FREE(session_list);
905}
906
907/*******************************************************************
908 makes a SRV_R_NET_SESS_ENUM structure.
909********************************************************************/
910
911static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
912 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
913{
914 WERROR status = WERR_OK;
915 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
916
917 ctr->switch_value = switch_value;
918
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;
935 }
936
937 return status;
938}
939
940/*******************************************************************
941 makes a SRV_R_NET_SESS_ENUM structure.
942********************************************************************/
943
944static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
945 uint32 resume_hnd, int sess_level, int switch_value)
946{
947 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
948
949 r_n->sess_level = sess_level;
950
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);
955
956 if (!W_ERROR_IS_OK(r_n->status))
957 resume_hnd = 0;
958
959 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
960}
961
962/*******************************************************************
963 fill in a conn info level 0 structure.
964 ********************************************************************/
965
966static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
967{
968 uint32 num_entries = 0;
969 (*stot) = 1;
970
971 if (ss0 == NULL) {
972 (*snum) = 0;
973 return;
974 }
975
976 DEBUG(5,("init_srv_conn_0_ss0\n"));
977
978 if (snum) {
979 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
980
981 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
982
983 /* move on to creating next connection */
984 /* move on to creating next conn */
985 num_entries++;
986 }
987
988 ss0->num_entries_read = num_entries;
989 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
990 ss0->num_entries_read2 = num_entries;
991
992 if ((*snum) >= (*stot)) {
993 (*snum) = 0;
994 }
995
996 } else {
997 ss0->num_entries_read = 0;
998 ss0->ptr_conn_info = 0;
999 ss0->num_entries_read2 = 0;
1000
1001 (*stot) = 0;
1002 }
1003}
1004
1005/*******************************************************************
1006 fill in a conn info level 1 structure.
1007 ********************************************************************/
1008
1009static 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)
1013{
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);
1016}
1017
1018/*******************************************************************
1019 fill in a conn info level 1 structure.
1020 ********************************************************************/
1021
1022static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1023{
1024 uint32 num_entries = 0;
1025 (*stot) = 1;
1026
1027 if (ss1 == NULL) {
1028 (*snum) = 0;
1029 return;
1030 }
1031
1032 DEBUG(5,("init_srv_conn_1_ss1\n"));
1033
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$");
1039
1040 /* move on to creating next connection */
1041 /* move on to creating next conn */
1042 num_entries++;
1043 }
1044
1045 ss1->num_entries_read = num_entries;
1046 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1047 ss1->num_entries_read2 = num_entries;
1048
1049
1050 if ((*snum) >= (*stot)) {
1051 (*snum) = 0;
1052 }
1053
1054 } else {
1055 ss1->num_entries_read = 0;
1056 ss1->ptr_conn_info = 0;
1057 ss1->num_entries_read2 = 0;
1058
1059 (*stot) = 0;
1060 }
1061}
1062
1063/*******************************************************************
1064 makes a SRV_R_NET_CONN_ENUM structure.
1065********************************************************************/
1066
1067static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1068 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1069{
1070 WERROR status = WERR_OK;
1071 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1072
1073 ctr->switch_value = switch_value;
1074
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;
1091 }
1092
1093 return status;
1094}
1095
1096/*******************************************************************
1097 makes a SRV_R_NET_CONN_ENUM structure.
1098********************************************************************/
1099
1100static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1101 uint32 resume_hnd, int conn_level, int switch_value)
1102{
1103 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1104
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);
1110
1111 if (!W_ERROR_IS_OK(r_n->status))
1112 resume_hnd = 0;
1113
1114 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1115}
1116
1117/*******************************************************************
1118 makes a SRV_R_NET_FILE_ENUM structure.
1119********************************************************************/
1120
1121static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1122{
1123 TALLOC_CTX *ctx = get_talloc_ctx();
1124 SRV_FILE_INFO_CTR *ctr = &r->ctr;
1125
1126 /* TODO -- Windows enumerates
1127 (b) active pipes
1128 (c) open directories and files */
1129
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;
1133
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;
1137
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;
1143
1144 r->status = WERR_OK;
1145
1146done:
1147 if ( ctr->num_entries > 0 )
1148 ctr->ptr_entries = 1;
1149
1150 init_enum_hnd(&r->enum_hnd, 0);
1151
1152 return r->status;
1153}
1154
1155/*******************************************************************
1156*******************************************************************/
1157
1158WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1159{
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;
1165 }
1166
1167 return WERR_OK;
1168}
1169
1170/*******************************************************************
1171net server get info
1172********************************************************************/
1173
1174WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
1175{
1176 WERROR status = WERR_OK;
1177 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1178
1179 if (!ctr)
1180 return WERR_NOMEM;
1181
1182 ZERO_STRUCTP(ctr);
1183
1184 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1185
1186 if (!pipe_access_check(p)) {
1187 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1188 return WERR_ACCESS_DENIED;
1189 }
1190
1191 switch (q_u->switch_value) {
1192
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. */
1196
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;
1224 }
1225
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);
1228
1229 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1230
1231 return r_u->status;
1232}
1233
1234/*******************************************************************
1235net server set info
1236********************************************************************/
1237
1238WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1239{
1240 WERROR status = WERR_OK;
1241
1242 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1243
1244 /* Set up the net server set info structure. */
1245
1246 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1247
1248 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1249
1250 return r_u->status;
1251}
1252
1253/*******************************************************************
1254net conn enum
1255********************************************************************/
1256
1257WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1258{
1259 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1260
1261 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1262 if (!r_u->ctr)
1263 return WERR_NOMEM;
1264
1265 ZERO_STRUCTP(r_u->ctr);
1266
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);
1272
1273 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1274
1275 return r_u->status;
1276}
1277
1278/*******************************************************************
1279net sess enum
1280********************************************************************/
1281
1282WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1283{
1284 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1285
1286 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1287 if (!r_u->ctr)
1288 return WERR_NOMEM;
1289
1290 ZERO_STRUCTP(r_u->ctr);
1291
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);
1297
1298 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1299
1300 return r_u->status;
1301}
1302
1303/*******************************************************************
1304net sess del
1305********************************************************************/
1306
1307WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1308{
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;
1315
1316 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1317 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1318
1319 /* strip leading backslashes if any */
1320 while (machine[0] == '\\') {
1321 memmove(machine, &machine[1], strlen(machine));
1322 }
1323
1324 num_sessions = list_sessions(&session_list);
1325
1326 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1327
1328 r_u->status = WERR_ACCESS_DENIED;
1329
1330 get_current_user(&user, p);
1331
1332 /* fail out now if you are not root or not a domain admin */
1333
1334 if ((user.ut.uid != sec_initial_uid()) &&
1335 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1336
1337 goto done;
1338 }
1339
1340 for (snum = 0; snum < num_sessions; snum++) {
1341
1342 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1343 strequal(session_list[snum].remote_machine, machine)) {
1344
1345 if (user.ut.uid != sec_initial_uid()) {
1346 not_root = True;
1347 become_root();
1348 }
1349
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;
1352
1353 if (not_root)
1354 unbecome_root();
1355 }
1356 }
1357
1358 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1359
1360
1361done:
1362 SAFE_FREE(session_list);
1363
1364 return r_u->status;
1365}
1366
1367/*******************************************************************
1368 Net share enum all.
1369********************************************************************/
1370
1371WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1372{
1373 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1374
1375 if (!pipe_access_check(p)) {
1376 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1377 return WERR_ACCESS_DENIED;
1378 }
1379
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);
1384
1385 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1386
1387 return r_u->status;
1388}
1389
1390/*******************************************************************
1391 Net share enum.
1392********************************************************************/
1393
1394WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1395{
1396 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1397
1398 if (!pipe_access_check(p)) {
1399 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1400 return WERR_ACCESS_DENIED;
1401 }
1402
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);
1407
1408 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1409
1410 return r_u->status;
1411}
1412
1413/*******************************************************************
1414 Net share get info.
1415********************************************************************/
1416
1417WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1418{
1419 fstring share_name;
1420
1421 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1422
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);
1426
1427 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1428
1429 return r_u->status;
1430}
1431
1432/*******************************************************************
1433 Check a given DOS pathname is valid for a share.
1434********************************************************************/
1435
1436char *valid_share_pathname(char *dos_pathname)
1437{
1438 char *ptr;
1439
1440 /* Convert any '\' paths to '/' */
1441 unix_format(dos_pathname);
1442 unix_clean_name(dos_pathname);
1443
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;
1448
1449 /* Only absolute paths allowed. */
1450 if (*ptr != '/')
1451 return NULL;
1452
1453 return ptr;
1454}
1455
1456/*******************************************************************
1457 Net share set info. Modify share details.
1458********************************************************************/
1459
1460WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1461{
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;
1475
1476 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1477
1478 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1479
1480 r_u->parm_error = 0;
1481
1482 if ( strequal(share_name,"IPC$")
1483 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1484 || strequal(share_name,"global") )
1485 {
1486 return WERR_ACCESS_DENIED;
1487 }
1488
1489 snum = find_service(share_name);
1490
1491 /* Does this share exist ? */
1492 if (snum < 0)
1493 return WERR_NET_NAME_NOT_FOUND;
1494
1495 /* No change to printer shares. */
1496 if (lp_print_ok(snum))
1497 return WERR_ACCESS_DENIED;
1498
1499 get_current_user(&user,p);
1500
1501 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1502
1503 /* fail out now if you are not root and not a disk op */
1504
1505 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1506 return WERR_ACCESS_DENIED;
1507
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;
1554 }
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;
1568 }
1569
1570 /* We can only modify disk shares. */
1571 if (type != STYPE_DISKTREE)
1572 return WERR_ACCESS_DENIED;
1573
1574 /* Check if the pathname is valid. */
1575 if (!(path = valid_share_pathname( pathname )))
1576 return WERR_OBJECT_PATH_INVALID;
1577
1578 /* Ensure share name, pathname and comment don't contain '"' characters. */
1579 string_replace(share_name, '"', ' ');
1580 string_replace(path, '"', ' ');
1581 string_replace(comment, '"', ' ');
1582
1583 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1584 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1585
1586 /* Only call modify function if something changed. */
1587
1588 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1589 || (lp_max_connections(snum) != max_connections) )
1590 {
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;
1594 }
1595
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 );
1598
1599 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1600
1601 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1602
1603 if ( is_disk_op )
1604 become_root();
1605
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);
1609 }
1610
1611 if ( is_disk_op )
1612 unbecome_root();
1613
1614 /********* END SeDiskOperatorPrivilege BLOCK *********/
1615
1616 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1617
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 ));
1622 }
1623
1624 /* Replace SD if changed. */
1625 if (psd) {
1626 SEC_DESC *old_sd;
1627 size_t sd_size;
1628
1629 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1630
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 ));
1635 }
1636 }
1637
1638 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1639
1640 return WERR_OK;
1641}
1642
1643/*******************************************************************
1644 Net share add. Call 'add_share_command "sharename" "pathname"
1645 "comment" "max connections = "
1646********************************************************************/
1647
1648WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1649{
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;
1663
1664 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1665
1666 r_u->parm_error = 0;
1667
1668 get_current_user(&user,p);
1669
1670 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1671
1672 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1673 return WERR_ACCESS_DENIED;
1674
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;
1678 }
1679
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;
1705
1706 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1707
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;
1719 }
1720
1721 /* check for invalid share names */
1722
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;
1726 }
1727
1728 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1729 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1730 {
1731 return WERR_ACCESS_DENIED;
1732 }
1733
1734 snum = find_service(share_name);
1735
1736 /* Share already exists. */
1737 if (snum >= 0)
1738 return WERR_ALREADY_EXISTS;
1739
1740 /* We can only add disk shares. */
1741 if (type != STYPE_DISKTREE)
1742 return WERR_ACCESS_DENIED;
1743
1744 /* Check if the pathname is valid. */
1745 if (!(path = valid_share_pathname( pathname )))
1746 return WERR_OBJECT_PATH_INVALID;
1747
1748 /* Ensure share name, pathname and comment don't contain '"' characters. */
1749 string_replace(share_name, '"', ' ');
1750 string_replace(path, '"', ' ');
1751 string_replace(comment, '"', ' ');
1752
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);
1760
1761 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1762
1763 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1764
1765 if ( is_disk_op )
1766 become_root();
1767
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);
1771 }
1772
1773 if ( is_disk_op )
1774 unbecome_root();
1775
1776 /********* END SeDiskOperatorPrivilege BLOCK *********/
1777
1778 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1779
1780 if ( ret != 0 )
1781 return WERR_ACCESS_DENIED;
1782
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 ));
1786 }
1787 }
1788
1789 /*
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.
1793 */
1794
1795 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1796
1797 return WERR_OK;
1798}
1799
1800/*******************************************************************
1801 Net share delete. Call "delete share command" with the share name as
1802 a parameter.
1803********************************************************************/
1804
1805WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1806{
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;
1815
1816 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1817
1818 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1819
1820 if ( strequal(share_name,"IPC$")
1821 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1822 || strequal(share_name,"global") )
1823 {
1824 return WERR_ACCESS_DENIED;
1825 }
1826
1827 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1828 return WERR_NO_SUCH_SHARE;
1829 }
1830
1831 snum = find_service(share_name);
1832
1833 /* No change to printer shares. */
1834 if (lp_print_ok(snum))
1835 return WERR_ACCESS_DENIED;
1836
1837 get_current_user(&user,p);
1838
1839 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1840
1841 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1842 return WERR_ACCESS_DENIED;
1843
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;
1847 }
1848
1849 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1850 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1851
1852 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1853
1854 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1855
1856 if ( is_disk_op )
1857 become_root();
1858
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);
1862 }
1863
1864 if ( is_disk_op )
1865 unbecome_root();
1866
1867 /********* END SeDiskOperatorPrivilege BLOCK *********/
1868
1869 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1870
1871 if ( ret != 0 )
1872 return WERR_ACCESS_DENIED;
1873
1874 /* Delete the SD in the database. */
1875 delete_share_security(params);
1876
1877 lp_killservice(params->service);
1878
1879 return WERR_OK;
1880}
1881
1882WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1883{
1884 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1885
1886 return _srv_net_share_del(p, q_u, r_u);
1887}
1888
1889/*******************************************************************
1890time of day
1891********************************************************************/
1892
1893WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1894{
1895 TIME_OF_DAY_INFO *tod;
1896 struct tm *t;
1897 time_t unixdate = time(NULL);
1898
1899 /* We do this call first as if we do it *after* the gmtime call
1900 it overwrites the pointed-to values. JRA */
1901
1902 uint32 zone = get_time_zone(unixdate)/60;
1903
1904 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1905
1906 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1907 return WERR_NOMEM;
1908
1909 r_u->tod = tod;
1910 r_u->ptr_srv_tod = 0x1;
1911 r_u->status = WERR_OK;
1912
1913 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1914
1915 t = gmtime(&unixdate);
1916
1917 /* set up the */
1918 init_time_of_day_info(tod,
1919 unixdate,
1920 0,
1921 t->tm_hour,
1922 t->tm_min,
1923 t->tm_sec,
1924 0,
1925 zone,
1926 10000,
1927 t->tm_mday,
1928 t->tm_mon + 1,
1929 1900+t->tm_year,
1930 t->tm_wday);
1931
1932 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1933
1934 return r_u->status;
1935}
1936
1937/***********************************************************************************
1938 Win9x NT tools get security descriptor.
1939***********************************************************************************/
1940
1941WERROR _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)
1943{
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;
1955
1956 ZERO_STRUCT(st);
1957
1958 r_u->status = WERR_OK;
1959
1960 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1961
1962 /* Null password is ok - we are already an authenticated user... */
1963 null_pw = data_blob(NULL, 0);
1964
1965 get_current_user(&user, p);
1966
1967 become_root();
1968 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1969 unbecome_root();
1970
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;
1975 }
1976
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;
1981 }
1982 became_user = True;
1983
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;
1990 }
1991
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;
1997 }
1998
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,
2007 0,
2008 FILE_ATTRIBUTE_DIRECTORY,
2009 NULL, &fsp);
2010
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;
2015 }
2016 }
2017
2018 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2019
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;
2024 }
2025
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;
2031
2032 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2033
2034 close_file(fsp, NORMAL_CLOSE);
2035 unbecome_user();
2036 close_cnum(conn, user.vuid);
2037 return r_u->status;
2038
2039error_exit:
2040
2041 if(fsp) {
2042 close_file(fsp, NORMAL_CLOSE);
2043 }
2044
2045 if (became_user)
2046 unbecome_user();
2047
2048 if (conn)
2049 close_cnum(conn, user.vuid);
2050
2051 return r_u->status;
2052}
2053
2054/***********************************************************************************
2055 Win9x NT tools set security descriptor.
2056***********************************************************************************/
2057
2058WERROR _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)
2060{
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;
2071
2072 ZERO_STRUCT(st);
2073
2074 r_u->status = WERR_OK;
2075
2076 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2077
2078 /* Null password is ok - we are already an authenticated user... */
2079 null_pw = data_blob(NULL, 0);
2080
2081 get_current_user(&user, p);
2082
2083 become_root();
2084 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2085 unbecome_root();
2086
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;
2091 }
2092
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;
2097 }
2098 became_user = True;
2099
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;
2106 }
2107
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;
2113 }
2114
2115
2116 nt_status = open_file_stat(conn, filename, &st, &fsp);
2117
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,
2125 0,
2126 FILE_ATTRIBUTE_DIRECTORY,
2127 NULL, &fsp);
2128
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;
2133 }
2134 }
2135
2136 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2137
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;
2142 }
2143
2144 close_file(fsp, NORMAL_CLOSE);
2145 unbecome_user();
2146 close_cnum(conn, user.vuid);
2147 return r_u->status;
2148
2149error_exit:
2150
2151 if(fsp) {
2152 close_file(fsp, NORMAL_CLOSE);
2153 }
2154
2155 if (became_user) {
2156 unbecome_user();
2157 }
2158
2159 if (conn) {
2160 close_cnum(conn, user.vuid);
2161 }
2162
2163 return r_u->status;
2164}
2165
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" <[email protected]>.
2172***********************************************************************************/
2173
2174static const char *server_disks[] = {"C:"};
2175
2176static uint32 get_server_disk_count(void)
2177{
2178 return sizeof(server_disks)/sizeof(server_disks[0]);
2179}
2180
2181static uint32 init_server_disk_enum(uint32 *resume)
2182{
2183 uint32 server_disk_count = get_server_disk_count();
2184
2185 /*resume can be an offset into the list for now*/
2186
2187 if(*resume & 0x80000000)
2188 *resume = 0;
2189
2190 if(*resume > server_disk_count)
2191 *resume = server_disk_count;
2192
2193 return server_disk_count - *resume;
2194}
2195
2196static const char *next_server_disk_enum(uint32 *resume)
2197{
2198 const char *disk;
2199
2200 if(init_server_disk_enum(resume) == 0)
2201 return NULL;
2202
2203 disk = server_disks[*resume];
2204
2205 (*resume)++;
2206
2207 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2208
2209 return disk;
2210}
2211
2212WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2213{
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);
2218
2219 r_u->status=WERR_OK;
2220
2221 r_u->total_entries = init_server_disk_enum(&resume);
2222
2223 r_u->disk_enum_ctr.unknown = 0;
2224
2225 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2226 return WERR_NOMEM;
2227 }
2228
2229 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2230
2231 /*allow one DISK_INFO for null terminator*/
2232
2233 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2234
2235 r_u->disk_enum_ctr.entries_read++;
2236
2237 /*copy disk name into a unicode string*/
2238
2239 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2240 }
2241
2242 /* add a terminating null string. Is this there if there is more data to come? */
2243
2244 r_u->disk_enum_ctr.entries_read++;
2245
2246 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2247
2248 init_enum_hnd(&r_u->enum_hnd, resume);
2249
2250 return r_u->status;
2251}
2252
2253/********************************************************************
2254********************************************************************/
2255
2256WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2257{
2258 fstring sharename;
2259
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;
2266 }
2267 break;
2268
2269 default:
2270 return WERR_UNKNOWN_LEVEL;
2271 }
2272
2273 return WERR_OK;
2274}
2275
2276
2277/********************************************************************
2278********************************************************************/
2279
2280WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2281{
2282 return WERR_ACCESS_DENIED;
2283}
2284
Note: See TracBrowser for help on using the repository browser.