source: branches/samba-3.2.x/source/rpc_server/srv_srvsvc_nt.c@ 233

Last change on this file since 233 was 233, checked in by Herwig Bauernfeind, 17 years ago

Update 3.2 branch to 3.2.9

File size: 70.5 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 * Copyright (C) Guenther Deschner 2008.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24/* This is the implementation of the srvsvc pipe. */
25
26#include "includes.h"
27
28extern const struct generic_mapping file_generic_mapping;
29
30#undef DBGC_CLASS
31#define DBGC_CLASS DBGC_RPC_SRV
32
33#define MAX_SERVER_DISK_ENTRIES 15
34
35/* Use for enumerating connections, pipes, & files */
36
37struct file_enum_count {
38 TALLOC_CTX *ctx;
39 const char *username;
40 struct srvsvc_NetFileCtr3 *ctr3;
41};
42
43struct sess_file_count {
44 struct server_id pid;
45 uid_t uid;
46 int count;
47};
48
49/****************************************************************************
50 Count the entries belonging to a service in the connection db.
51****************************************************************************/
52
53static int pipe_enum_fn( struct db_record *rec, void *p)
54{
55 struct pipe_open_rec prec;
56 struct file_enum_count *fenum = (struct file_enum_count *)p;
57 struct srvsvc_NetFileInfo3 *f;
58 int i = fenum->ctr3->count;
59 char *fullpath = NULL;
60 const char *username;
61
62 if (rec->value.dsize != sizeof(struct pipe_open_rec))
63 return 0;
64
65 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
66
67 if ( !process_exists(prec.pid) ) {
68 return 0;
69 }
70
71 username = uidtoname(prec.uid);
72
73 if ((fenum->username != NULL)
74 && !strequal(username, fenum->username)) {
75 return 0;
76 }
77
78 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
79 if (!fullpath) {
80 return 1;
81 }
82
83 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
84 struct srvsvc_NetFileInfo3, i+1);
85 if ( !f ) {
86 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
87 return 1;
88 }
89 fenum->ctr3->array = f;
90
91 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
92 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum),
93 (FILE_READ_DATA|FILE_WRITE_DATA),
94 0,
95 fullpath,
96 username);
97
98 fenum->ctr3->count++;
99
100 return 0;
101}
102
103/*******************************************************************
104********************************************************************/
105
106static WERROR net_enum_pipes(TALLOC_CTX *ctx,
107 const char *username,
108 struct srvsvc_NetFileCtr3 **ctr3,
109 uint32_t resume )
110{
111 struct file_enum_count fenum;
112
113 fenum.ctx = ctx;
114 fenum.username = username;
115 fenum.ctr3 = *ctr3;
116
117 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
118 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
119 "failed\n"));
120 return WERR_NOMEM;
121 }
122
123 *ctr3 = fenum.ctr3;
124
125 return WERR_OK;
126}
127
128/*******************************************************************
129********************************************************************/
130
131static void enum_file_fn( const struct share_mode_entry *e,
132 const char *sharepath, const char *fname,
133 void *private_data )
134{
135 struct file_enum_count *fenum =
136 (struct file_enum_count *)private_data;
137
138 struct srvsvc_NetFileInfo3 *f;
139 int i = fenum->ctr3->count;
140 files_struct fsp;
141 struct byte_range_lock *brl;
142 int num_locks = 0;
143 char *fullpath = NULL;
144 uint32 permissions;
145 const char *username;
146
147 /* If the pid was not found delete the entry from connections.tdb */
148
149 if ( !process_exists(e->pid) ) {
150 return;
151 }
152
153 username = uidtoname(e->uid);
154
155 if ((fenum->username != NULL)
156 && !strequal(username, fenum->username)) {
157 return;
158 }
159
160 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
161 struct srvsvc_NetFileInfo3, i+1);
162 if ( !f ) {
163 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
164 return;
165 }
166 fenum->ctr3->array = f;
167
168 /* need to count the number of locks on a file */
169
170 ZERO_STRUCT( fsp );
171 fsp.file_id = e->id;
172
173 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
174 num_locks = brl->num_locks;
175 TALLOC_FREE(brl);
176 }
177
178 if ( strcmp( fname, "." ) == 0 ) {
179 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
180 } else {
181 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
182 sharepath, fname );
183 }
184 if (!fullpath) {
185 return;
186 }
187 string_replace( fullpath, '/', '\\' );
188
189 /* mask out create (what ever that is) */
190 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
191
192 /* now fill in the srvsvc_NetFileInfo3 struct */
193 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
194 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id),
195 permissions,
196 num_locks,
197 fullpath,
198 username);
199 fenum->ctr3->count++;
200}
201
202/*******************************************************************
203********************************************************************/
204
205static WERROR net_enum_files(TALLOC_CTX *ctx,
206 const char *username,
207 struct srvsvc_NetFileCtr3 **ctr3,
208 uint32_t resume)
209{
210 struct file_enum_count f_enum_cnt;
211
212 f_enum_cnt.ctx = ctx;
213 f_enum_cnt.username = username;
214 f_enum_cnt.ctr3 = *ctr3;
215
216 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
217
218 *ctr3 = f_enum_cnt.ctr3;
219
220 return WERR_OK;
221}
222
223/*******************************************************************
224 Utility function to get the 'type' of a share from an snum.
225 ********************************************************************/
226static uint32 get_share_type(int snum)
227{
228 /* work out the share type */
229 uint32 type = STYPE_DISKTREE;
230
231 if (lp_print_ok(snum))
232 type = STYPE_PRINTQ;
233 if (strequal(lp_fstype(snum), "IPC"))
234 type = STYPE_IPC;
235 if (lp_administrative_share(snum))
236 type |= STYPE_HIDDEN;
237
238 return type;
239}
240
241/*******************************************************************
242 Fill in a share info level 0 structure.
243 ********************************************************************/
244
245static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
246{
247 const char *net_name = lp_servicename(snum);
248
249 init_srvsvc_NetShareInfo0(r, net_name);
250}
251
252/*******************************************************************
253 Fill in a share info level 1 structure.
254 ********************************************************************/
255
256static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
257{
258 char *net_name = lp_servicename(snum);
259 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
260
261 if (remark) {
262 remark = standard_sub_conn(p->mem_ctx,
263 p->conn,
264 remark);
265 }
266
267 init_srvsvc_NetShareInfo1(r, net_name,
268 get_share_type(snum),
269 remark ? remark : "");
270}
271
272/*******************************************************************
273 Fill in a share info level 2 structure.
274 ********************************************************************/
275
276static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
277{
278 char *remark = NULL;
279 char *path = NULL;
280 int max_connections = lp_max_connections(snum);
281 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
282 int count = 0;
283 char *net_name = lp_servicename(snum);
284
285 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
286 if (remark) {
287 remark = standard_sub_conn(p->mem_ctx,
288 p->conn,
289 remark);
290 }
291 path = talloc_asprintf(p->mem_ctx,
292 "C:%s", lp_pathname(snum));
293
294 if (path) {
295 /*
296 * Change / to \\ so that win2k will see it as a valid path.
297 * This was added to enable use of browsing in win2k add
298 * share dialog.
299 */
300
301 string_replace(path, '/', '\\');
302 }
303
304 count = count_current_connections(net_name, false);
305
306 init_srvsvc_NetShareInfo2(r, net_name,
307 get_share_type(snum),
308 remark ? remark : "",
309 0,
310 max_uses,
311 count,
312 path ? path : "",
313 "");
314}
315
316/*******************************************************************
317 Map any generic bits to file specific bits.
318********************************************************************/
319
320static void map_generic_share_sd_bits(SEC_DESC *psd)
321{
322 int i;
323 SEC_ACL *ps_dacl = NULL;
324
325 if (!psd)
326 return;
327
328 ps_dacl = psd->dacl;
329 if (!ps_dacl)
330 return;
331
332 for (i = 0; i < ps_dacl->num_aces; i++) {
333 SEC_ACE *psa = &ps_dacl->aces[i];
334 uint32 orig_mask = psa->access_mask;
335
336 se_map_generic(&psa->access_mask, &file_generic_mapping);
337 psa->access_mask |= orig_mask;
338 }
339}
340
341/*******************************************************************
342 Fill in a share info level 501 structure.
343********************************************************************/
344
345static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
346{
347 const char *net_name = lp_servicename(snum);
348 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
349
350 if (remark) {
351 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
352 }
353
354 init_srvsvc_NetShareInfo501(r, net_name,
355 get_share_type(snum),
356 remark ? remark : "",
357 (lp_csc_policy(snum) << 4));
358}
359
360/*******************************************************************
361 Fill in a share info level 502 structure.
362 ********************************************************************/
363
364static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
365{
366 const char *net_name = lp_servicename(snum);
367 char *path = NULL;
368 SEC_DESC *sd = NULL;
369 struct sec_desc_buf *sd_buf = NULL;
370 size_t sd_size = 0;
371 TALLOC_CTX *ctx = p->mem_ctx;
372 char *remark = talloc_strdup(ctx, lp_comment(snum));;
373
374 if (remark) {
375 remark = standard_sub_conn(ctx, p->conn, remark);
376 }
377 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
378 if (path) {
379 /*
380 * Change / to \\ so that win2k will see it as a valid path. This was added to
381 * enable use of browsing in win2k add share dialog.
382 */
383 string_replace(path, '/', '\\');
384 }
385
386 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
387
388 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
389
390 init_srvsvc_NetShareInfo502(r, net_name,
391 get_share_type(snum),
392 remark ? remark : "",
393 0,
394 (uint32_t)-1,
395 1,
396 path ? path : "",
397 "",
398 sd_buf);
399}
400
401/***************************************************************************
402 Fill in a share info level 1004 structure.
403 ***************************************************************************/
404
405static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
406{
407 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
408
409 if (remark) {
410 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
411 }
412
413 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
414}
415
416/***************************************************************************
417 Fill in a share info level 1005 structure.
418 ***************************************************************************/
419
420static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
421{
422 uint32_t dfs_flags = 0;
423
424 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
425 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
426 }
427
428 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
429
430 init_srvsvc_NetShareInfo1005(r, dfs_flags);
431}
432
433/***************************************************************************
434 Fill in a share info level 1006 structure.
435 ***************************************************************************/
436
437static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
438{
439 init_srvsvc_NetShareInfo1006(r, (uint32_t)-1);
440}
441
442/***************************************************************************
443 Fill in a share info level 1007 structure.
444 ***************************************************************************/
445
446static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
447{
448 uint32 flags = 0;
449
450 init_srvsvc_NetShareInfo1007(r, flags, "");
451}
452
453/*******************************************************************
454 Fill in a share info level 1501 structure.
455 ********************************************************************/
456
457static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
458{
459 SEC_DESC *sd;
460 size_t sd_size;
461 TALLOC_CTX *ctx = p->mem_ctx;
462
463 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
464
465 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
466}
467
468/*******************************************************************
469 True if it ends in '$'.
470 ********************************************************************/
471
472static bool is_hidden_share(int snum)
473{
474 const char *net_name = lp_servicename(snum);
475
476 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
477}
478
479/*******************************************************************
480 Fill in a share info structure.
481 ********************************************************************/
482
483static WERROR init_srv_share_info_ctr(pipes_struct *p,
484 struct srvsvc_NetShareInfoCtr *info_ctr,
485 uint32_t *resume_handle_p,
486 uint32_t *total_entries,
487 bool all_shares)
488{
489 int num_entries = 0;
490 int alloc_entries = 0;
491 int num_services = 0;
492 int snum;
493 TALLOC_CTX *ctx = p->mem_ctx;
494 int i = 0;
495 int valid_share_count = 0;
496 union srvsvc_NetShareCtr ctr;
497 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
498
499 DEBUG(5,("init_srv_share_info_ctr\n"));
500
501 /* Ensure all the usershares are loaded. */
502 become_root();
503 load_usershare_shares();
504 load_registry_shares();
505 num_services = lp_numservices();
506 unbecome_root();
507
508 /* Count the number of entries. */
509 for (snum = 0; snum < num_services; snum++) {
510 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
511 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
512 num_entries++;
513 } else {
514 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
515 }
516 }
517
518 if (!num_entries || (resume_handle >= num_entries)) {
519 return WERR_OK;
520 }
521
522 /* Calculate alloc entries. */
523 alloc_entries = num_entries - resume_handle;
524 switch (info_ctr->level) {
525 case 0:
526 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
527 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
528
529 ctr.ctr0->count = alloc_entries;
530 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
531 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
532
533 for (snum = 0; snum < num_services; snum++) {
534 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
535 (resume_handle <= (i + valid_share_count++)) ) {
536 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
537 }
538 }
539
540 break;
541
542 case 1:
543 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
544 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
545
546 ctr.ctr1->count = alloc_entries;
547 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
548 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
549
550 for (snum = 0; snum < num_services; snum++) {
551 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
552 (resume_handle <= (i + valid_share_count++)) ) {
553 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
554 }
555 }
556
557 break;
558
559 case 2:
560 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
561 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
562
563 ctr.ctr2->count = alloc_entries;
564 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
565 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
566
567 for (snum = 0; snum < num_services; snum++) {
568 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
569 (resume_handle <= (i + valid_share_count++)) ) {
570 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
571 }
572 }
573
574 break;
575
576 case 501:
577 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
578 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
579
580 ctr.ctr501->count = alloc_entries;
581 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
582 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
583
584 for (snum = 0; snum < num_services; snum++) {
585 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
586 (resume_handle <= (i + valid_share_count++)) ) {
587 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
588 }
589 }
590
591 break;
592
593 case 502:
594 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
595 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
596
597 ctr.ctr502->count = alloc_entries;
598 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
599 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
600
601 for (snum = 0; snum < num_services; snum++) {
602 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
603 (resume_handle <= (i + valid_share_count++)) ) {
604 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
605 }
606 }
607
608 break;
609
610 case 1004:
611 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
612 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
613
614 ctr.ctr1004->count = alloc_entries;
615 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
616 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
617
618 for (snum = 0; snum < num_services; snum++) {
619 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
620 (resume_handle <= (i + valid_share_count++)) ) {
621 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
622 }
623 }
624
625 break;
626
627 case 1005:
628 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
629 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
630
631 ctr.ctr1005->count = alloc_entries;
632 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
633 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
634
635 for (snum = 0; snum < num_services; snum++) {
636 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
637 (resume_handle <= (i + valid_share_count++)) ) {
638 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
639 }
640 }
641
642 break;
643
644 case 1006:
645 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
646 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
647
648 ctr.ctr1006->count = alloc_entries;
649 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
650 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
651
652 for (snum = 0; snum < num_services; snum++) {
653 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
654 (resume_handle <= (i + valid_share_count++)) ) {
655 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
656 }
657 }
658
659 break;
660
661 case 1007:
662 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
663 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
664
665 ctr.ctr1007->count = alloc_entries;
666 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
667 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
668
669 for (snum = 0; snum < num_services; snum++) {
670 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
671 (resume_handle <= (i + valid_share_count++)) ) {
672 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
673 }
674 }
675
676 break;
677
678 case 1501:
679 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
680 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
681
682 ctr.ctr1501->count = alloc_entries;
683 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
684 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
685
686 for (snum = 0; snum < num_services; snum++) {
687 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
688 (resume_handle <= (i + valid_share_count++)) ) {
689 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
690 }
691 }
692
693 break;
694
695 default:
696 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
697 info_ctr->level));
698 return WERR_UNKNOWN_LEVEL;
699 }
700
701 *total_entries = alloc_entries;
702 if (resume_handle_p) {
703 if (all_shares) {
704 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
705 } else {
706 *resume_handle_p = num_entries;
707 }
708 }
709
710 info_ctr->ctr = ctr;
711
712 return WERR_OK;
713}
714
715/*******************************************************************
716 fill in a sess info level 0 structure.
717 ********************************************************************/
718
719static WERROR init_srv_sess_info_0(pipes_struct *p,
720 struct srvsvc_NetSessCtr0 *ctr0,
721 uint32_t *resume_handle_p,
722 uint32_t *total_entries)
723{
724 struct sessionid *session_list;
725 uint32_t num_entries = 0;
726 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
727 *total_entries = list_sessions(p->mem_ctx, &session_list);
728
729 DEBUG(5,("init_srv_sess_info_0\n"));
730
731 if (ctr0 == NULL) {
732 if (resume_handle_p) {
733 *resume_handle_p = 0;
734 }
735 return WERR_OK;
736 }
737
738 for (; resume_handle < *total_entries; resume_handle++) {
739
740 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
741 ctr0->array,
742 struct srvsvc_NetSessInfo0,
743 num_entries+1);
744 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
745
746 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
747 session_list[resume_handle].remote_machine);
748 num_entries++;
749 }
750
751 ctr0->count = num_entries;
752
753 if (resume_handle_p) {
754 if (*resume_handle_p >= *total_entries) {
755 *resume_handle_p = 0;
756 } else {
757 *resume_handle_p = resume_handle;
758 }
759 }
760
761 return WERR_OK;
762}
763
764/*******************************************************************
765********************************************************************/
766
767static void sess_file_fn( const struct share_mode_entry *e,
768 const char *sharepath, const char *fname,
769 void *data )
770{
771 struct sess_file_count *sess = (struct sess_file_count *)data;
772
773 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
774 sess->count++;
775 }
776
777 return;
778}
779
780/*******************************************************************
781********************************************************************/
782
783static int net_count_files( uid_t uid, struct server_id pid )
784{
785 struct sess_file_count s_file_cnt;
786
787 s_file_cnt.count = 0;
788 s_file_cnt.uid = uid;
789 s_file_cnt.pid = pid;
790
791 share_mode_forall( sess_file_fn, &s_file_cnt );
792
793 return s_file_cnt.count;
794}
795
796/*******************************************************************
797 fill in a sess info level 1 structure.
798 ********************************************************************/
799
800static WERROR init_srv_sess_info_1(pipes_struct *p,
801 struct srvsvc_NetSessCtr1 *ctr1,
802 uint32_t *resume_handle_p,
803 uint32_t *total_entries)
804{
805 struct sessionid *session_list;
806 uint32_t num_entries = 0;
807 time_t now = time(NULL);
808 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
809
810 ZERO_STRUCTP(ctr1);
811
812 if (ctr1 == NULL) {
813 if (resume_handle_p) {
814 *resume_handle_p = 0;
815 }
816 return WERR_OK;
817 }
818
819 *total_entries = list_sessions(p->mem_ctx, &session_list);
820
821 for (; resume_handle < *total_entries; resume_handle++) {
822 uint32 num_files;
823 uint32 connect_time;
824 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
825 bool guest;
826
827 if ( !pw ) {
828 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
829 session_list[resume_handle].username));
830 continue;
831 }
832
833 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
834 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
835 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
836
837 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
838 ctr1->array,
839 struct srvsvc_NetSessInfo1,
840 num_entries+1);
841 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
842
843 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
844 session_list[resume_handle].remote_machine,
845 session_list[resume_handle].username,
846 num_files,
847 connect_time,
848 0,
849 guest);
850 num_entries++;
851 }
852
853 ctr1->count = num_entries;
854
855 if (resume_handle_p) {
856 if (*resume_handle_p >= *total_entries) {
857 *resume_handle_p = 0;
858 } else {
859 *resume_handle_p = resume_handle;
860 }
861 }
862
863 return WERR_OK;
864}
865
866/*******************************************************************
867 fill in a conn info level 0 structure.
868 ********************************************************************/
869
870static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
871 uint32_t *resume_handle_p,
872 uint32_t *total_entries)
873{
874 uint32_t num_entries = 0;
875 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
876
877 DEBUG(5,("init_srv_conn_info_0\n"));
878
879 if (ctr0 == NULL) {
880 if (resume_handle_p) {
881 *resume_handle_p = 0;
882 }
883 return WERR_OK;
884 }
885
886 *total_entries = 1;
887
888 ZERO_STRUCTP(ctr0);
889
890 for (; resume_handle < *total_entries; resume_handle++) {
891
892 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
893 ctr0->array,
894 struct srvsvc_NetConnInfo0,
895 num_entries+1);
896 if (!ctr0->array) {
897 return WERR_NOMEM;
898 }
899
900 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
901 (*total_entries));
902
903 /* move on to creating next connection */
904 num_entries++;
905 }
906
907 ctr0->count = num_entries;
908 *total_entries = num_entries;
909
910 if (resume_handle_p) {
911 if (*resume_handle_p >= *total_entries) {
912 *resume_handle_p = 0;
913 } else {
914 *resume_handle_p = resume_handle;
915 }
916 }
917
918 return WERR_OK;
919}
920
921/*******************************************************************
922 fill in a conn info level 1 structure.
923 ********************************************************************/
924
925static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
926 uint32_t *resume_handle_p,
927 uint32_t *total_entries)
928{
929 uint32_t num_entries = 0;
930 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
931
932 DEBUG(5,("init_srv_conn_info_1\n"));
933
934 if (ctr1 == NULL) {
935 if (resume_handle_p) {
936 *resume_handle_p = 0;
937 }
938 return WERR_OK;
939 }
940
941 *total_entries = 1;
942
943 ZERO_STRUCTP(ctr1);
944
945 for (; resume_handle < *total_entries; resume_handle++) {
946
947 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
948 ctr1->array,
949 struct srvsvc_NetConnInfo1,
950 num_entries+1);
951 if (!ctr1->array) {
952 return WERR_NOMEM;
953 }
954
955 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
956 (*total_entries),
957 0x3,
958 1,
959 1,
960 3,
961 "dummy_user",
962 "IPC$");
963
964 /* move on to creating next connection */
965 num_entries++;
966 }
967
968 ctr1->count = num_entries;
969 *total_entries = num_entries;
970
971 if (resume_handle_p) {
972 if (*resume_handle_p >= *total_entries) {
973 *resume_handle_p = 0;
974 } else {
975 *resume_handle_p = resume_handle;
976 }
977 }
978
979 return WERR_OK;
980}
981
982/*******************************************************************
983 _srvsvc_NetFileEnum
984*******************************************************************/
985
986WERROR _srvsvc_NetFileEnum(pipes_struct *p,
987 struct srvsvc_NetFileEnum *r)
988{
989 TALLOC_CTX *ctx = NULL;
990 struct srvsvc_NetFileCtr3 *ctr3;
991 uint32_t resume_hnd = 0;
992 WERROR werr;
993
994 switch (r->in.info_ctr->level) {
995 case 3:
996 break;
997 default:
998 return WERR_UNKNOWN_LEVEL;
999 }
1000
1001 ctx = talloc_tos();
1002 ctr3 = r->in.info_ctr->ctr.ctr3;
1003 if (!ctr3) {
1004 werr = WERR_INVALID_PARAM;
1005 goto done;
1006 }
1007
1008 /* TODO -- Windows enumerates
1009 (b) active pipes
1010 (c) open directories and files */
1011
1012 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1013 if (!W_ERROR_IS_OK(werr)) {
1014 goto done;
1015 }
1016
1017 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1018 if (!W_ERROR_IS_OK(werr)) {
1019 goto done;
1020 }
1021
1022 *r->out.totalentries = ctr3->count;
1023 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1024 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1025
1026 werr = WERR_OK;
1027
1028 done:
1029 return werr;
1030}
1031
1032/*******************************************************************
1033 _srvsvc_NetSrvGetInfo
1034********************************************************************/
1035
1036WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1037 struct srvsvc_NetSrvGetInfo *r)
1038{
1039 WERROR status = WERR_OK;
1040
1041 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1042
1043 if (!pipe_access_check(p)) {
1044 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1045 return WERR_ACCESS_DENIED;
1046 }
1047
1048 switch (r->in.level) {
1049
1050 /* Technically level 102 should only be available to
1051 Administrators but there isn't anything super-secret
1052 here, as most of it is made up. */
1053
1054 case 102: {
1055 struct srvsvc_NetSrvInfo102 *info102;
1056
1057 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1058 if (!info102) {
1059 return WERR_NOMEM;
1060 }
1061
1062 init_srvsvc_NetSrvInfo102(info102,
1063 PLATFORM_ID_NT,
1064 global_myname(),
1065 lp_major_announce_version(),
1066 lp_minor_announce_version(),
1067 lp_default_server_announce(),
1068 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1069 0xffffffff, /* users */
1070 0xf, /* disc */
1071 0, /* hidden */
1072 240, /* announce */
1073 3000, /* announce delta */
1074 100000, /* licenses */
1075 "c:\\"); /* user path */
1076 r->out.info->info102 = info102;
1077 break;
1078 }
1079 case 101: {
1080 struct srvsvc_NetSrvInfo101 *info101;
1081
1082 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1083 if (!info101) {
1084 return WERR_NOMEM;
1085 }
1086
1087 init_srvsvc_NetSrvInfo101(info101,
1088 PLATFORM_ID_NT,
1089 global_myname(),
1090 lp_major_announce_version(),
1091 lp_minor_announce_version(),
1092 lp_default_server_announce(),
1093 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1094 r->out.info->info101 = info101;
1095 break;
1096 }
1097 case 100: {
1098 struct srvsvc_NetSrvInfo100 *info100;
1099
1100 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1101 if (!info100) {
1102 return WERR_NOMEM;
1103 }
1104
1105 init_srvsvc_NetSrvInfo100(info100,
1106 PLATFORM_ID_NT,
1107 global_myname());
1108 r->out.info->info100 = info100;
1109
1110 break;
1111 }
1112 default:
1113 status = WERR_UNKNOWN_LEVEL;
1114 break;
1115 }
1116
1117 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1118
1119 return status;
1120}
1121
1122/*******************************************************************
1123 _srvsvc_NetSrvSetInfo
1124********************************************************************/
1125
1126WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1127 struct srvsvc_NetSrvSetInfo *r)
1128{
1129 WERROR status = WERR_OK;
1130
1131 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1132
1133 /* Set up the net server set info structure. */
1134
1135 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1136
1137 return status;
1138}
1139
1140/*******************************************************************
1141 _srvsvc_NetConnEnum
1142********************************************************************/
1143
1144WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1145 struct srvsvc_NetConnEnum *r)
1146{
1147 WERROR werr;
1148
1149 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1150
1151 switch (r->in.info_ctr->level) {
1152 case 0:
1153 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1154 r->in.resume_handle,
1155 r->out.totalentries);
1156 break;
1157 case 1:
1158 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1159 r->in.resume_handle,
1160 r->out.totalentries);
1161 break;
1162 default:
1163 return WERR_UNKNOWN_LEVEL;
1164 }
1165
1166 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1167
1168 return werr;
1169}
1170
1171/*******************************************************************
1172 _srvsvc_NetSessEnum
1173********************************************************************/
1174
1175WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1176 struct srvsvc_NetSessEnum *r)
1177{
1178 WERROR werr;
1179
1180 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1181
1182 switch (r->in.info_ctr->level) {
1183 case 0:
1184 werr = init_srv_sess_info_0(p,
1185 r->in.info_ctr->ctr.ctr0,
1186 r->in.resume_handle,
1187 r->out.totalentries);
1188 break;
1189 case 1:
1190 werr = init_srv_sess_info_1(p,
1191 r->in.info_ctr->ctr.ctr1,
1192 r->in.resume_handle,
1193 r->out.totalentries);
1194 break;
1195 default:
1196 return WERR_UNKNOWN_LEVEL;
1197 }
1198
1199 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1200
1201 return werr;
1202}
1203
1204/*******************************************************************
1205 _srvsvc_NetSessDel
1206********************************************************************/
1207
1208WERROR _srvsvc_NetSessDel(pipes_struct *p,
1209 struct srvsvc_NetSessDel *r)
1210{
1211 struct sessionid *session_list;
1212 struct current_user user;
1213 int num_sessions, snum;
1214 const char *username;
1215 const char *machine;
1216 bool not_root = False;
1217 WERROR werr;
1218
1219 username = r->in.user;
1220 machine = r->in.client;
1221
1222 /* strip leading backslashes if any */
1223 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1224 machine += 2;
1225 }
1226
1227 num_sessions = list_sessions(p->mem_ctx, &session_list);
1228
1229 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1230
1231 werr = WERR_ACCESS_DENIED;
1232
1233 get_current_user(&user, p);
1234
1235 /* fail out now if you are not root or not a domain admin */
1236
1237 if ((user.ut.uid != sec_initial_uid()) &&
1238 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1239
1240 goto done;
1241 }
1242
1243 for (snum = 0; snum < num_sessions; snum++) {
1244
1245 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1246 strequal(session_list[snum].remote_machine, machine)) {
1247
1248 NTSTATUS ntstat;
1249
1250 if (user.ut.uid != sec_initial_uid()) {
1251 not_root = True;
1252 become_root();
1253 }
1254
1255 ntstat = messaging_send(smbd_messaging_context(),
1256 session_list[snum].pid,
1257 MSG_SHUTDOWN, &data_blob_null);
1258
1259 if (NT_STATUS_IS_OK(ntstat))
1260 werr = WERR_OK;
1261
1262 if (not_root)
1263 unbecome_root();
1264 }
1265 }
1266
1267 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1268
1269done:
1270
1271 return werr;
1272}
1273
1274/*******************************************************************
1275 _srvsvc_NetShareEnumAll
1276********************************************************************/
1277
1278WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1279 struct srvsvc_NetShareEnumAll *r)
1280{
1281 WERROR werr;
1282
1283 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1284
1285 if (!pipe_access_check(p)) {
1286 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1287 return WERR_ACCESS_DENIED;
1288 }
1289
1290 /* Create the list of shares for the response. */
1291 werr = init_srv_share_info_ctr(p,
1292 r->in.info_ctr,
1293 r->in.resume_handle,
1294 r->out.totalentries,
1295 true);
1296
1297 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1298
1299 return werr;
1300}
1301
1302/*******************************************************************
1303 _srvsvc_NetShareEnum
1304********************************************************************/
1305
1306WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1307 struct srvsvc_NetShareEnum *r)
1308{
1309 WERROR werr;
1310
1311 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1312
1313 if (!pipe_access_check(p)) {
1314 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1315 return WERR_ACCESS_DENIED;
1316 }
1317
1318 /* Create the list of shares for the response. */
1319 werr = init_srv_share_info_ctr(p,
1320 r->in.info_ctr,
1321 r->in.resume_handle,
1322 r->out.totalentries,
1323 false);
1324
1325 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1326
1327 return werr;
1328}
1329
1330/*******************************************************************
1331 _srvsvc_NetShareGetInfo
1332********************************************************************/
1333
1334WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1335 struct srvsvc_NetShareGetInfo *r)
1336{
1337 WERROR status = WERR_OK;
1338 fstring share_name;
1339 int snum;
1340 union srvsvc_NetShareInfo *info = r->out.info;
1341
1342 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1343
1344 fstrcpy(share_name, r->in.share_name);
1345
1346 snum = find_service(share_name);
1347 if (snum < 0) {
1348 return WERR_INVALID_NAME;
1349 }
1350
1351 switch (r->in.level) {
1352 case 0:
1353 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1354 W_ERROR_HAVE_NO_MEMORY(info->info0);
1355 init_srv_share_info_0(p, info->info0, snum);
1356 break;
1357 case 1:
1358 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1359 W_ERROR_HAVE_NO_MEMORY(info->info1);
1360 init_srv_share_info_1(p, info->info1, snum);
1361 break;
1362 case 2:
1363 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1364 W_ERROR_HAVE_NO_MEMORY(info->info2);
1365 init_srv_share_info_2(p, info->info2, snum);
1366 break;
1367 case 501:
1368 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1369 W_ERROR_HAVE_NO_MEMORY(info->info501);
1370 init_srv_share_info_501(p, info->info501, snum);
1371 break;
1372 case 502:
1373 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1374 W_ERROR_HAVE_NO_MEMORY(info->info502);
1375 init_srv_share_info_502(p, info->info502, snum);
1376 break;
1377 case 1004:
1378 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1379 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1380 init_srv_share_info_1004(p, info->info1004, snum);
1381 break;
1382 case 1005:
1383 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1384 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1385 init_srv_share_info_1005(p, info->info1005, snum);
1386 break;
1387 case 1006:
1388 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1389 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1390 init_srv_share_info_1006(p, info->info1006, snum);
1391 break;
1392 case 1007:
1393 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1394 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1395 init_srv_share_info_1007(p, info->info1007, snum);
1396 break;
1397 case 1501:
1398 init_srv_share_info_1501(p, info->info1501, snum);
1399 break;
1400 default:
1401 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1402 r->in.level));
1403 status = WERR_UNKNOWN_LEVEL;
1404 break;
1405 }
1406
1407 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1408
1409 return status;
1410}
1411
1412/*******************************************************************
1413 Check a given DOS pathname is valid for a share.
1414********************************************************************/
1415
1416char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1417{
1418 char *ptr = NULL;
1419
1420 if (!dos_pathname) {
1421 return NULL;
1422 }
1423
1424 ptr = talloc_strdup(ctx, dos_pathname);
1425 if (!ptr) {
1426 return NULL;
1427 }
1428 /* Convert any '\' paths to '/' */
1429 unix_format(ptr);
1430 ptr = unix_clean_name(ctx, ptr);
1431 if (!ptr) {
1432 return NULL;
1433 }
1434
1435#ifndef __OS2__
1436 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1437 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1438 ptr += 2;
1439
1440 /* Only absolute paths allowed. */
1441 if (*ptr != '/')
1442 return NULL;
1443#else
1444 /* Only absolute paths allowed. */
1445 if (strlen(ptr) < 2 || ptr[1] != ':')
1446 return NULL;
1447#endif
1448 return ptr;
1449}
1450
1451/*******************************************************************
1452 _srvsvc_NetShareSetInfo. Modify share details.
1453********************************************************************/
1454
1455WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1456 struct srvsvc_NetShareSetInfo *r)
1457{
1458 struct current_user user;
1459 char *command = NULL;
1460 char *share_name = NULL;
1461 char *comment = NULL;
1462 const char *pathname = NULL;
1463 int type;
1464 int snum;
1465 int ret;
1466 char *path = NULL;
1467 SEC_DESC *psd = NULL;
1468 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1469 bool is_disk_op = False;
1470 int max_connections = 0;
1471 TALLOC_CTX *ctx = p->mem_ctx;
1472 union srvsvc_NetShareInfo *info = r->in.info;
1473
1474 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1475
1476 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1477 if (!share_name) {
1478 return WERR_NOMEM;
1479 }
1480
1481 if (r->out.parm_error) {
1482 *r->out.parm_error = 0;
1483 }
1484
1485 if ( strequal(share_name,"IPC$")
1486 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1487 || strequal(share_name,"global") )
1488 {
1489 return WERR_ACCESS_DENIED;
1490 }
1491
1492 snum = find_service(share_name);
1493
1494 /* Does this share exist ? */
1495 if (snum < 0)
1496 return WERR_NET_NAME_NOT_FOUND;
1497
1498 /* No change to printer shares. */
1499 if (lp_print_ok(snum))
1500 return WERR_ACCESS_DENIED;
1501
1502 get_current_user(&user,p);
1503
1504 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1505
1506 /* fail out now if you are not root and not a disk op */
1507
1508 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1509 return WERR_ACCESS_DENIED;
1510
1511 switch (r->in.level) {
1512 case 1:
1513 pathname = talloc_strdup(ctx, lp_pathname(snum));
1514 comment = talloc_strdup(ctx, info->info1->comment);
1515 type = info->info1->type;
1516 psd = NULL;
1517 break;
1518 case 2:
1519 comment = talloc_strdup(ctx, info->info2->comment);
1520 pathname = info->info2->path;
1521 type = info->info2->type;
1522 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1523 0 : info->info2->max_users;
1524 psd = NULL;
1525 break;
1526#if 0
1527 /* not supported on set but here for completeness */
1528 case 501:
1529 comment = talloc_strdup(ctx, info->info501->comment);
1530 type = info->info501->type;
1531 psd = NULL;
1532 break;
1533#endif
1534 case 502:
1535 comment = talloc_strdup(ctx, info->info502->comment);
1536 pathname = info->info502->path;
1537 type = info->info502->type;
1538 psd = info->info502->sd_buf.sd;
1539 map_generic_share_sd_bits(psd);
1540 break;
1541 case 1004:
1542 pathname = talloc_strdup(ctx, lp_pathname(snum));
1543 comment = talloc_strdup(ctx, info->info1004->comment);
1544 type = STYPE_DISKTREE;
1545 break;
1546 case 1005:
1547 /* XP re-sets the csc policy even if it wasn't changed by the
1548 user, so we must compare it to see if it's what is set in
1549 smb.conf, so that we can contine other ops like setting
1550 ACLs on a share */
1551 if (((info->info1005->dfs_flags &
1552 SHARE_1005_CSC_POLICY_MASK) >>
1553 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1554 return WERR_OK;
1555 else {
1556 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1557 return WERR_ACCESS_DENIED;
1558 }
1559 case 1006:
1560 case 1007:
1561 return WERR_ACCESS_DENIED;
1562 case 1501:
1563 pathname = talloc_strdup(ctx, lp_pathname(snum));
1564 comment = talloc_strdup(ctx, lp_comment(snum));
1565 psd = info->info1501->sd;
1566 map_generic_share_sd_bits(psd);
1567 type = STYPE_DISKTREE;
1568 break;
1569 default:
1570 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1571 r->in.level));
1572 return WERR_UNKNOWN_LEVEL;
1573 }
1574
1575 /* We can only modify disk shares. */
1576 if (type != STYPE_DISKTREE)
1577 return WERR_ACCESS_DENIED;
1578
1579 if (comment == NULL) {
1580 return WERR_NOMEM;
1581 }
1582
1583 /* Check if the pathname is valid. */
1584 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1585 return WERR_OBJECT_PATH_INVALID;
1586
1587 /* Ensure share name, pathname and comment don't contain '"' characters. */
1588 string_replace(share_name, '"', ' ');
1589 string_replace(path, '"', ' ');
1590 string_replace(comment, '"', ' ');
1591
1592 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1593 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1594
1595 /* Only call modify function if something changed. */
1596
1597 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1598 || (lp_max_connections(snum) != max_connections)) {
1599 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1600 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1601 return WERR_ACCESS_DENIED;
1602 }
1603
1604 command = talloc_asprintf(p->mem_ctx,
1605 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1606 lp_change_share_cmd(),
1607 get_dyn_CONFIGFILE(),
1608 share_name,
1609 path,
1610 comment ? comment : "",
1611 max_connections);
1612 if (!command) {
1613 return WERR_NOMEM;
1614 }
1615
1616 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1617
1618 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1619
1620 if (is_disk_op)
1621 become_root();
1622
1623 if ( (ret = smbrun(command, NULL)) == 0 ) {
1624 /* Tell everyone we updated smb.conf. */
1625 message_send_all(smbd_messaging_context(),
1626 MSG_SMB_CONF_UPDATED, NULL, 0,
1627 NULL);
1628 }
1629
1630 if ( is_disk_op )
1631 unbecome_root();
1632
1633 /********* END SeDiskOperatorPrivilege BLOCK *********/
1634
1635 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1636 command, ret ));
1637
1638 TALLOC_FREE(command);
1639
1640 if ( ret != 0 )
1641 return WERR_ACCESS_DENIED;
1642 } else {
1643 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1644 share_name ));
1645 }
1646
1647 /* Replace SD if changed. */
1648 if (psd) {
1649 SEC_DESC *old_sd;
1650 size_t sd_size;
1651
1652 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1653
1654 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1655 if (!set_share_security(share_name, psd))
1656 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1657 share_name ));
1658 }
1659 }
1660
1661 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1662
1663 return WERR_OK;
1664}
1665
1666/*******************************************************************
1667 _srvsvc_NetShareAdd.
1668 Call 'add_share_command "sharename" "pathname"
1669 "comment" "max connections = "
1670********************************************************************/
1671
1672WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1673 struct srvsvc_NetShareAdd *r)
1674{
1675 struct current_user user;
1676 char *command = NULL;
1677 char *share_name = NULL;
1678 char *comment = NULL;
1679 char *pathname = NULL;
1680 int type;
1681 int snum;
1682 int ret;
1683 char *path;
1684 SEC_DESC *psd = NULL;
1685 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1686 bool is_disk_op;
1687 int max_connections = 0;
1688 TALLOC_CTX *ctx = p->mem_ctx;
1689
1690 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1691
1692 if (r->out.parm_error) {
1693 *r->out.parm_error = 0;
1694 }
1695
1696 get_current_user(&user,p);
1697
1698 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1699
1700 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1701 return WERR_ACCESS_DENIED;
1702
1703 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1704 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1705 return WERR_ACCESS_DENIED;
1706 }
1707
1708 switch (r->in.level) {
1709 case 0:
1710 /* No path. Not enough info in a level 0 to do anything. */
1711 return WERR_ACCESS_DENIED;
1712 case 1:
1713 /* Not enough info in a level 1 to do anything. */
1714 return WERR_ACCESS_DENIED;
1715 case 2:
1716 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1717 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1718 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1719 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1720 0 : r->in.info->info2->max_users;
1721 type = r->in.info->info2->type;
1722 break;
1723 case 501:
1724 /* No path. Not enough info in a level 501 to do anything. */
1725 return WERR_ACCESS_DENIED;
1726 case 502:
1727 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1728 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1729 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1730 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1731 0 : r->in.info->info502->max_users;
1732 type = r->in.info->info502->type;
1733 psd = r->in.info->info502->sd_buf.sd;
1734 map_generic_share_sd_bits(psd);
1735 break;
1736
1737 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1738
1739 case 1004:
1740 case 1005:
1741 case 1006:
1742 case 1007:
1743 return WERR_ACCESS_DENIED;
1744 case 1501:
1745 /* DFS only level. */
1746 return WERR_ACCESS_DENIED;
1747 default:
1748 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1749 r->in.level));
1750 return WERR_UNKNOWN_LEVEL;
1751 }
1752
1753 /* check for invalid share names */
1754
1755 if (!share_name || !validate_net_name(share_name,
1756 INVALID_SHARENAME_CHARS,
1757 strlen(share_name))) {
1758 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1759 share_name ? share_name : ""));
1760 return WERR_INVALID_NAME;
1761 }
1762
1763 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1764 || (lp_enable_asu_support() &&
1765 strequal(share_name,"ADMIN$"))) {
1766 return WERR_ACCESS_DENIED;
1767 }
1768
1769 snum = find_service(share_name);
1770
1771 /* Share already exists. */
1772 if (snum >= 0) {
1773 return WERR_ALREADY_EXISTS;
1774 }
1775
1776 /* We can only add disk shares. */
1777 if (type != STYPE_DISKTREE) {
1778 return WERR_ACCESS_DENIED;
1779 }
1780
1781 /* Check if the pathname is valid. */
1782 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1783 return WERR_OBJECT_PATH_INVALID;
1784 }
1785
1786 /* Ensure share name, pathname and comment don't contain '"' characters. */
1787 string_replace(share_name, '"', ' ');
1788 string_replace(path, '"', ' ');
1789 if (comment) {
1790 string_replace(comment, '"', ' ');
1791 }
1792
1793 command = talloc_asprintf(ctx,
1794 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1795 lp_add_share_cmd(),
1796 get_dyn_CONFIGFILE(),
1797 share_name,
1798 path,
1799 comment ? comment : "",
1800 max_connections);
1801 if (!command) {
1802 return WERR_NOMEM;
1803 }
1804
1805 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1806
1807 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1808
1809 if ( is_disk_op )
1810 become_root();
1811
1812 /* FIXME: use libnetconf here - gd */
1813
1814 if ( (ret = smbrun(command, NULL)) == 0 ) {
1815 /* Tell everyone we updated smb.conf. */
1816 message_send_all(smbd_messaging_context(),
1817 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1818 }
1819
1820 if ( is_disk_op )
1821 unbecome_root();
1822
1823 /********* END SeDiskOperatorPrivilege BLOCK *********/
1824
1825 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1826 command, ret ));
1827
1828 TALLOC_FREE(command);
1829
1830 if ( ret != 0 )
1831 return WERR_ACCESS_DENIED;
1832
1833 if (psd) {
1834 if (!set_share_security(share_name, psd)) {
1835 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1836 share_name ));
1837 }
1838 }
1839
1840 /*
1841 * We don't call reload_services() here, the message will
1842 * cause this to be done before the next packet is read
1843 * from the client. JRA.
1844 */
1845
1846 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1847
1848 return WERR_OK;
1849}
1850
1851/*******************************************************************
1852 _srvsvc_NetShareDel
1853 Call "delete share command" with the share name as
1854 a parameter.
1855********************************************************************/
1856
1857WERROR _srvsvc_NetShareDel(pipes_struct *p,
1858 struct srvsvc_NetShareDel *r)
1859{
1860 struct current_user user;
1861 char *command = NULL;
1862 char *share_name = NULL;
1863 int ret;
1864 int snum;
1865 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1866 bool is_disk_op;
1867 struct share_params *params;
1868 TALLOC_CTX *ctx = p->mem_ctx;
1869
1870 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1871
1872 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1873 if (!share_name) {
1874 return WERR_NET_NAME_NOT_FOUND;
1875 }
1876 if ( strequal(share_name,"IPC$")
1877 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1878 || strequal(share_name,"global") )
1879 {
1880 return WERR_ACCESS_DENIED;
1881 }
1882
1883 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1884 return WERR_NO_SUCH_SHARE;
1885 }
1886
1887 snum = find_service(share_name);
1888
1889 /* No change to printer shares. */
1890 if (lp_print_ok(snum))
1891 return WERR_ACCESS_DENIED;
1892
1893 get_current_user(&user,p);
1894
1895 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1896
1897 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1898 return WERR_ACCESS_DENIED;
1899
1900 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1901 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1902 return WERR_ACCESS_DENIED;
1903 }
1904
1905 command = talloc_asprintf(ctx,
1906 "%s \"%s\" \"%s\"",
1907 lp_delete_share_cmd(),
1908 get_dyn_CONFIGFILE(),
1909 lp_servicename(snum));
1910 if (!command) {
1911 return WERR_NOMEM;
1912 }
1913
1914 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1915
1916 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1917
1918 if ( is_disk_op )
1919 become_root();
1920
1921 if ( (ret = smbrun(command, NULL)) == 0 ) {
1922 /* Tell everyone we updated smb.conf. */
1923 message_send_all(smbd_messaging_context(),
1924 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1925 }
1926
1927 if ( is_disk_op )
1928 unbecome_root();
1929
1930 /********* END SeDiskOperatorPrivilege BLOCK *********/
1931
1932 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1933
1934 if ( ret != 0 )
1935 return WERR_ACCESS_DENIED;
1936
1937 /* Delete the SD in the database. */
1938 delete_share_security(lp_servicename(params->service));
1939
1940 lp_killservice(params->service);
1941
1942 return WERR_OK;
1943}
1944
1945/*******************************************************************
1946 _srvsvc_NetShareDelSticky
1947********************************************************************/
1948
1949WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1950 struct srvsvc_NetShareDelSticky *r)
1951{
1952 struct srvsvc_NetShareDel q;
1953
1954 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1955
1956 q.in.server_unc = r->in.server_unc;
1957 q.in.share_name = r->in.share_name;
1958 q.in.reserved = r->in.reserved;
1959
1960 return _srvsvc_NetShareDel(p, &q);
1961}
1962
1963/*******************************************************************
1964 _srvsvc_NetRemoteTOD
1965********************************************************************/
1966
1967WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1968 struct srvsvc_NetRemoteTOD *r)
1969{
1970 struct srvsvc_NetRemoteTODInfo *tod;
1971 struct tm *t;
1972 time_t unixdate = time(NULL);
1973
1974 /* We do this call first as if we do it *after* the gmtime call
1975 it overwrites the pointed-to values. JRA */
1976
1977 uint32 zone = get_time_zone(unixdate)/60;
1978
1979 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1980
1981 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1982 return WERR_NOMEM;
1983
1984 *r->out.info = tod;
1985
1986 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1987
1988 t = gmtime(&unixdate);
1989
1990 /* set up the */
1991 init_srvsvc_NetRemoteTODInfo(tod,
1992 unixdate,
1993 0,
1994 t->tm_hour,
1995 t->tm_min,
1996 t->tm_sec,
1997 0,
1998 zone,
1999 10000,
2000 t->tm_mday,
2001 t->tm_mon + 1,
2002 1900+t->tm_year,
2003 t->tm_wday);
2004
2005 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2006
2007 return WERR_OK;
2008}
2009
2010/***********************************************************************************
2011 _srvsvc_NetGetFileSecurity
2012 Win9x NT tools get security descriptor.
2013***********************************************************************************/
2014
2015WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2016 struct srvsvc_NetGetFileSecurity *r)
2017{
2018 SEC_DESC *psd = NULL;
2019 size_t sd_size;
2020 DATA_BLOB null_pw;
2021 char *filename_in = NULL;
2022 char *filename = NULL;
2023 char *qualname = NULL;
2024 SMB_STRUCT_STAT st;
2025 NTSTATUS nt_status;
2026 WERROR werr;
2027 struct current_user user;
2028 connection_struct *conn = NULL;
2029 bool became_user = False;
2030 TALLOC_CTX *ctx = p->mem_ctx;
2031 struct sec_desc_buf *sd_buf;
2032
2033 ZERO_STRUCT(st);
2034
2035 werr = WERR_OK;
2036
2037 qualname = talloc_strdup(ctx, r->in.share);
2038 if (!qualname) {
2039 werr = WERR_ACCESS_DENIED;
2040 goto error_exit;
2041 }
2042
2043 /* Null password is ok - we are already an authenticated user... */
2044 null_pw = data_blob_null;
2045
2046 get_current_user(&user, p);
2047
2048 become_root();
2049 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2050 unbecome_root();
2051
2052 if (conn == NULL) {
2053 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2054 qualname));
2055 werr = ntstatus_to_werror(nt_status);
2056 goto error_exit;
2057 }
2058
2059 if (!become_user(conn, conn->vuid)) {
2060 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2061 werr = WERR_ACCESS_DENIED;
2062 goto error_exit;
2063 }
2064 became_user = True;
2065
2066 filename_in = talloc_strdup(ctx, r->in.file);
2067 if (!filename_in) {
2068 werr = WERR_ACCESS_DENIED;
2069 goto error_exit;
2070 }
2071
2072 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2073 if (!NT_STATUS_IS_OK(nt_status)) {
2074 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2075 filename));
2076 werr = WERR_ACCESS_DENIED;
2077 goto error_exit;
2078 }
2079
2080 nt_status = check_name(conn, filename);
2081 if (!NT_STATUS_IS_OK(nt_status)) {
2082 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2083 filename));
2084 werr = WERR_ACCESS_DENIED;
2085 goto error_exit;
2086 }
2087
2088 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2089 (OWNER_SECURITY_INFORMATION
2090 |GROUP_SECURITY_INFORMATION
2091 |DACL_SECURITY_INFORMATION), &psd);
2092
2093 if (!NT_STATUS_IS_OK(nt_status)) {
2094 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2095 filename));
2096 werr = ntstatus_to_werror(nt_status);
2097 goto error_exit;
2098 }
2099
2100 sd_size = ndr_size_security_descriptor(psd, 0);
2101
2102 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2103 if (!sd_buf) {
2104 werr = WERR_NOMEM;
2105 goto error_exit;
2106 }
2107
2108 sd_buf->sd_size = sd_size;
2109 sd_buf->sd = psd;
2110
2111 *r->out.sd_buf = sd_buf;
2112
2113 psd->dacl->revision = NT4_ACL_REVISION;
2114
2115 unbecome_user();
2116 close_cnum(conn, user.vuid);
2117 return werr;
2118
2119error_exit:
2120
2121 if (became_user)
2122 unbecome_user();
2123
2124 if (conn)
2125 close_cnum(conn, user.vuid);
2126
2127 return werr;
2128}
2129
2130/***********************************************************************************
2131 _srvsvc_NetSetFileSecurity
2132 Win9x NT tools set security descriptor.
2133***********************************************************************************/
2134
2135WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2136 struct srvsvc_NetSetFileSecurity *r)
2137{
2138 char *filename_in = NULL;
2139 char *filename = NULL;
2140 char *qualname = NULL;
2141 DATA_BLOB null_pw;
2142 files_struct *fsp = NULL;
2143 SMB_STRUCT_STAT st;
2144 NTSTATUS nt_status;
2145 WERROR werr;
2146 struct current_user user;
2147 connection_struct *conn = NULL;
2148 bool became_user = False;
2149 TALLOC_CTX *ctx = p->mem_ctx;
2150
2151 ZERO_STRUCT(st);
2152
2153 werr = WERR_OK;
2154
2155 qualname = talloc_strdup(ctx, r->in.share);
2156 if (!qualname) {
2157 werr = WERR_ACCESS_DENIED;
2158 goto error_exit;
2159 }
2160
2161 /* Null password is ok - we are already an authenticated user... */
2162 null_pw = data_blob_null;
2163
2164 get_current_user(&user, p);
2165
2166 become_root();
2167 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2168 unbecome_root();
2169
2170 if (conn == NULL) {
2171 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2172 werr = ntstatus_to_werror(nt_status);
2173 goto error_exit;
2174 }
2175
2176 if (!become_user(conn, conn->vuid)) {
2177 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2178 werr = WERR_ACCESS_DENIED;
2179 goto error_exit;
2180 }
2181 became_user = True;
2182
2183 filename_in = talloc_strdup(ctx, r->in.file);
2184 if (!filename_in) {
2185 werr = WERR_ACCESS_DENIED;
2186 goto error_exit;
2187 }
2188
2189 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2190 if (!NT_STATUS_IS_OK(nt_status)) {
2191 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2192 werr = WERR_ACCESS_DENIED;
2193 goto error_exit;
2194 }
2195
2196 nt_status = check_name(conn, filename);
2197 if (!NT_STATUS_IS_OK(nt_status)) {
2198 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2199 werr = WERR_ACCESS_DENIED;
2200 goto error_exit;
2201 }
2202
2203 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2204
2205 if ( !NT_STATUS_IS_OK(nt_status) ) {
2206 /* Perhaps it is a directory */
2207 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2208 nt_status = open_directory(conn, NULL, filename, &st,
2209 FILE_READ_ATTRIBUTES,
2210 FILE_SHARE_READ|FILE_SHARE_WRITE,
2211 FILE_OPEN,
2212 0,
2213 FILE_ATTRIBUTE_DIRECTORY,
2214 NULL, &fsp);
2215
2216 if ( !NT_STATUS_IS_OK(nt_status) ) {
2217 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2218 werr = ntstatus_to_werror(nt_status);
2219 goto error_exit;
2220 }
2221 }
2222
2223 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2224 r->in.securityinformation,
2225 r->in.sd_buf->sd);
2226
2227 if (!NT_STATUS_IS_OK(nt_status) ) {
2228 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2229 werr = WERR_ACCESS_DENIED;
2230 goto error_exit;
2231 }
2232
2233 close_file(fsp, NORMAL_CLOSE);
2234 unbecome_user();
2235 close_cnum(conn, user.vuid);
2236 return werr;
2237
2238error_exit:
2239
2240 if(fsp) {
2241 close_file(fsp, NORMAL_CLOSE);
2242 }
2243
2244 if (became_user) {
2245 unbecome_user();
2246 }
2247
2248 if (conn) {
2249 close_cnum(conn, user.vuid);
2250 }
2251
2252 return werr;
2253}
2254
2255/***********************************************************************************
2256 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2257 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2258 These disks would the disks listed by this function.
2259 Users could then create shares relative to these disks. Watch out for moving these disks around.
2260 "Nigel Williams" <[email protected]>.
2261***********************************************************************************/
2262
2263static const char *server_disks[] = {"C:"
2264#ifdef __OS2__
2265 // YD we can use a better implementation (real time scan or above idea)
2266 ,"D:","E:","F:","G:","H:","I:","J:","K:","L:","M:","N:","O:"
2267 ,"P:","Q:","R:","S:","T:","U:","V:","W:","X:","Y:","Z:"
2268#endif
2269};
2270
2271
2272static uint32 get_server_disk_count(void)
2273{
2274 return sizeof(server_disks)/sizeof(server_disks[0]);
2275}
2276
2277static uint32 init_server_disk_enum(uint32 *resume)
2278{
2279 uint32 server_disk_count = get_server_disk_count();
2280
2281 /*resume can be an offset into the list for now*/
2282
2283 if(*resume & 0x80000000)
2284 *resume = 0;
2285
2286 if(*resume > server_disk_count)
2287 *resume = server_disk_count;
2288
2289 return server_disk_count - *resume;
2290}
2291
2292static const char *next_server_disk_enum(uint32 *resume)
2293{
2294 const char *disk;
2295
2296 if(init_server_disk_enum(resume) == 0)
2297 return NULL;
2298
2299 disk = server_disks[*resume];
2300
2301 (*resume)++;
2302
2303 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2304
2305 return disk;
2306}
2307
2308/********************************************************************
2309 _srvsvc_NetDiskEnum
2310********************************************************************/
2311
2312WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2313 struct srvsvc_NetDiskEnum *r)
2314{
2315 uint32 i;
2316 const char *disk_name;
2317 TALLOC_CTX *ctx = p->mem_ctx;
2318 WERROR werr;
2319 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2320
2321 werr = WERR_OK;
2322
2323 *r->out.totalentries = init_server_disk_enum(&resume);
2324
2325 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2326 MAX_SERVER_DISK_ENTRIES);
2327 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2328
2329 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2330
2331 r->out.info->count = 0;
2332
2333 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2334
2335 r->out.info->count++;
2336
2337 /*copy disk name into a unicode string*/
2338
2339 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2340 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2341 }
2342
2343 /* add a terminating null string. Is this there if there is more data to come? */
2344
2345 r->out.info->count++;
2346
2347 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2348 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2349
2350 if (r->out.resume_handle) {
2351 *r->out.resume_handle = resume;
2352 }
2353
2354 return werr;
2355}
2356
2357/********************************************************************
2358 _srvsvc_NetNameValidate
2359********************************************************************/
2360
2361WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2362 struct srvsvc_NetNameValidate *r)
2363{
2364 switch (r->in.name_type) {
2365 case 0x9:
2366 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2367 strlen_m(r->in.name)))
2368 {
2369 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2370 r->in.name));
2371 return WERR_INVALID_NAME;
2372 }
2373 break;
2374
2375 default:
2376 return WERR_UNKNOWN_LEVEL;
2377 }
2378
2379 return WERR_OK;
2380}
2381
2382/*******************************************************************
2383********************************************************************/
2384
2385static void enum_file_close_fn( const struct share_mode_entry *e,
2386 const char *sharepath, const char *fname,
2387 void *private_data )
2388{
2389 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2390 struct srvsvc_NetFileClose *r =
2391 (struct srvsvc_NetFileClose *)private_data;
2392 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2393
2394 if (fid != r->in.fid) {
2395 return; /* Not this file. */
2396 }
2397
2398 if (!process_exists(e->pid) ) {
2399 return;
2400 }
2401
2402 /* Ok - send the close message. */
2403 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2404 sharepath,
2405 share_mode_str(talloc_tos(), 0, e) ));
2406
2407 share_mode_entry_to_message(msg, e);
2408
2409 r->out.result = ntstatus_to_werror(
2410 messaging_send_buf(smbd_messaging_context(),
2411 e->pid, MSG_SMB_CLOSE_FILE,
2412 (uint8 *)msg,
2413 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2414}
2415
2416/********************************************************************
2417 Close a file given a 32-bit file id.
2418********************************************************************/
2419
2420WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2421{
2422 struct current_user user;
2423 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2424 bool is_disk_op;
2425
2426 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2427
2428 get_current_user(&user,p);
2429
2430 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
2431
2432 if (user.ut.uid != sec_initial_uid() && !is_disk_op) {
2433 return WERR_ACCESS_DENIED;
2434 }
2435
2436 /* enum_file_close_fn sends the close message to
2437 * the relevent smbd process. */
2438
2439 r->out.result = WERR_BADFILE;
2440 share_mode_forall( enum_file_close_fn, (void *)r);
2441 return r->out.result;
2442}
2443
2444/********************************************************************
2445********************************************************************/
2446
2447WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2448{
2449 p->rng_fault_state = True;
2450 return WERR_NOT_SUPPORTED;
2451}
2452
2453WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2454{
2455 p->rng_fault_state = True;
2456 return WERR_NOT_SUPPORTED;
2457}
2458
2459WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2460{
2461 p->rng_fault_state = True;
2462 return WERR_NOT_SUPPORTED;
2463}
2464
2465WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2466{
2467 p->rng_fault_state = True;
2468 return WERR_NOT_SUPPORTED;
2469}
2470
2471WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2472{
2473 p->rng_fault_state = True;
2474 return WERR_NOT_SUPPORTED;
2475}
2476
2477WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2478{
2479 p->rng_fault_state = True;
2480 return WERR_NOT_SUPPORTED;
2481}
2482
2483WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2484{
2485 p->rng_fault_state = True;
2486 return WERR_NOT_SUPPORTED;
2487}
2488
2489WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2490{
2491 p->rng_fault_state = True;
2492 return WERR_NOT_SUPPORTED;
2493}
2494
2495WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2496{
2497 p->rng_fault_state = True;
2498 return WERR_NOT_SUPPORTED;
2499}
2500
2501WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2502{
2503 p->rng_fault_state = True;
2504 return WERR_NOT_SUPPORTED;
2505}
2506
2507WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2508{
2509 p->rng_fault_state = True;
2510 return WERR_NOT_SUPPORTED;
2511}
2512
2513WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2514{
2515 p->rng_fault_state = True;
2516 return WERR_NOT_SUPPORTED;
2517}
2518
2519WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2520{
2521 p->rng_fault_state = True;
2522 return WERR_NOT_SUPPORTED;
2523}
2524
2525WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2526{
2527 p->rng_fault_state = True;
2528 return WERR_NOT_SUPPORTED;
2529}
2530
2531WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2532{
2533 p->rng_fault_state = True;
2534 return WERR_NOT_SUPPORTED;
2535}
2536
2537WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2538{
2539 p->rng_fault_state = True;
2540 return WERR_NOT_SUPPORTED;
2541}
2542
2543WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2544{
2545 p->rng_fault_state = True;
2546 return WERR_NOT_SUPPORTED;
2547}
2548
2549WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2550{
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2553}
2554
2555WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2556{
2557 p->rng_fault_state = True;
2558 return WERR_NOT_SUPPORTED;
2559}
2560
2561WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2562{
2563 p->rng_fault_state = True;
2564 return WERR_NOT_SUPPORTED;
2565}
2566
2567WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2568{
2569 p->rng_fault_state = True;
2570 return WERR_NOT_SUPPORTED;
2571}
2572
2573WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2574{
2575 p->rng_fault_state = True;
2576 return WERR_NOT_SUPPORTED;
2577}
2578
2579WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2580{
2581 p->rng_fault_state = True;
2582 return WERR_NOT_SUPPORTED;
2583}
2584
2585WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2586{
2587 p->rng_fault_state = True;
2588 return WERR_NOT_SUPPORTED;
2589}
2590
2591WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2592{
2593 p->rng_fault_state = True;
2594 return WERR_NOT_SUPPORTED;
2595}
2596
2597WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2598{
2599 p->rng_fault_state = True;
2600 return WERR_NOT_SUPPORTED;
2601}
2602
2603WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2604{
2605 p->rng_fault_state = True;
2606 return WERR_NOT_SUPPORTED;
2607}
2608
2609WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2610{
2611 p->rng_fault_state = True;
2612 return WERR_NOT_SUPPORTED;
2613}
2614
2615WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2616{
2617 p->rng_fault_state = True;
2618 return WERR_NOT_SUPPORTED;
2619}
2620
2621WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2622{
2623 p->rng_fault_state = True;
2624 return WERR_NOT_SUPPORTED;
2625}
2626
2627WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2628{
2629 p->rng_fault_state = True;
2630 return WERR_NOT_SUPPORTED;
2631}
2632
2633WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2634{
2635 p->rng_fault_state = True;
2636 return WERR_NOT_SUPPORTED;
2637}
2638
2639WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2640{
2641 p->rng_fault_state = True;
2642 return WERR_NOT_SUPPORTED;
2643}
2644
2645WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2646{
2647 p->rng_fault_state = True;
2648 return WERR_NOT_SUPPORTED;
2649}
2650
2651WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2652{
2653 p->rng_fault_state = True;
2654 return WERR_NOT_SUPPORTED;
2655}
2656
Note: See TracBrowser for help on using the repository browser.