unit tests: allow make test to correctly and quickly exit in case of problem while...
[Samba.git] / source3 / rpc_server / srv_srvsvc_nt.c
blobf59b972861b276db590cbf09b0749bca736cda7a
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.
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.
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.
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/>.
24 /* This is the implementation of the srvsvc pipe. */
26 #include "includes.h"
27 #include "../librpc/gen_ndr/srv_srvsvc.h"
28 #include "librpc/gen_ndr/messaging.h"
29 #include "../libcli/security/security.h"
30 #include "../librpc/gen_ndr/ndr_security.h"
31 #include "dbwrap.h"
33 extern const struct generic_mapping file_generic_mapping;
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_RPC_SRV
38 #define MAX_SERVER_DISK_ENTRIES 15
40 /* Use for enumerating connections, pipes, & files */
42 struct file_enum_count {
43 TALLOC_CTX *ctx;
44 const char *username;
45 struct srvsvc_NetFileCtr3 *ctr3;
48 struct sess_file_count {
49 struct server_id pid;
50 uid_t uid;
51 int count;
54 /****************************************************************************
55 Count the entries belonging to a service in the connection db.
56 ****************************************************************************/
58 static int pipe_enum_fn( struct db_record *rec, void *p)
60 struct pipe_open_rec prec;
61 struct file_enum_count *fenum = (struct file_enum_count *)p;
62 struct srvsvc_NetFileInfo3 *f;
63 int i = fenum->ctr3->count;
64 char *fullpath = NULL;
65 const char *username;
67 if (rec->value.dsize != sizeof(struct pipe_open_rec))
68 return 0;
70 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
72 if ( !process_exists(prec.pid) ) {
73 return 0;
76 username = uidtoname(prec.uid);
78 if ((fenum->username != NULL)
79 && !strequal(username, fenum->username)) {
80 return 0;
83 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
84 if (!fullpath) {
85 return 1;
88 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
89 struct srvsvc_NetFileInfo3, i+1);
90 if ( !f ) {
91 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
92 return 1;
94 fenum->ctr3->array = f;
96 fenum->ctr3->array[i].fid =
97 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
98 fenum->ctr3->array[i].permissions =
99 (FILE_READ_DATA|FILE_WRITE_DATA);
100 fenum->ctr3->array[i].num_locks = 0;
101 fenum->ctr3->array[i].path = fullpath;
102 fenum->ctr3->array[i].user = username;
104 fenum->ctr3->count++;
106 return 0;
109 /*******************************************************************
110 ********************************************************************/
112 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
113 const char *username,
114 struct srvsvc_NetFileCtr3 **ctr3,
115 uint32_t resume )
117 struct file_enum_count fenum;
119 fenum.ctx = ctx;
120 fenum.username = username;
121 fenum.ctr3 = *ctr3;
123 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
124 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
125 "failed\n"));
126 return WERR_NOMEM;
129 *ctr3 = fenum.ctr3;
131 return WERR_OK;
134 /*******************************************************************
135 ********************************************************************/
137 static void enum_file_fn( const struct share_mode_entry *e,
138 const char *sharepath, const char *fname,
139 void *private_data )
141 struct file_enum_count *fenum =
142 (struct file_enum_count *)private_data;
144 struct srvsvc_NetFileInfo3 *f;
145 int i = fenum->ctr3->count;
146 files_struct fsp;
147 struct byte_range_lock *brl;
148 int num_locks = 0;
149 char *fullpath = NULL;
150 uint32 permissions;
151 const char *username;
153 /* If the pid was not found delete the entry from connections.tdb */
155 if ( !process_exists(e->pid) ) {
156 return;
159 username = uidtoname(e->uid);
161 if ((fenum->username != NULL)
162 && !strequal(username, fenum->username)) {
163 return;
166 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
167 struct srvsvc_NetFileInfo3, i+1);
168 if ( !f ) {
169 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
170 return;
172 fenum->ctr3->array = f;
174 /* need to count the number of locks on a file */
176 ZERO_STRUCT( fsp );
177 fsp.file_id = e->id;
179 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
180 num_locks = brl->num_locks;
181 TALLOC_FREE(brl);
184 if ( strcmp( fname, "." ) == 0 ) {
185 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
186 } else {
187 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
188 sharepath, fname );
190 if (!fullpath) {
191 return;
193 string_replace( fullpath, '/', '\\' );
195 /* mask out create (what ever that is) */
196 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
198 /* now fill in the srvsvc_NetFileInfo3 struct */
200 fenum->ctr3->array[i].fid =
201 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
202 fenum->ctr3->array[i].permissions = permissions;
203 fenum->ctr3->array[i].num_locks = num_locks;
204 fenum->ctr3->array[i].path = fullpath;
205 fenum->ctr3->array[i].user = username;
207 fenum->ctr3->count++;
210 /*******************************************************************
211 ********************************************************************/
213 static WERROR net_enum_files(TALLOC_CTX *ctx,
214 const char *username,
215 struct srvsvc_NetFileCtr3 **ctr3,
216 uint32_t resume)
218 struct file_enum_count f_enum_cnt;
220 f_enum_cnt.ctx = ctx;
221 f_enum_cnt.username = username;
222 f_enum_cnt.ctr3 = *ctr3;
224 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
226 *ctr3 = f_enum_cnt.ctr3;
228 return WERR_OK;
231 /*******************************************************************
232 Utility function to get the 'type' of a share from an snum.
233 ********************************************************************/
234 static uint32 get_share_type(int snum)
236 /* work out the share type */
237 uint32 type = STYPE_DISKTREE;
239 if (lp_print_ok(snum))
240 type = STYPE_PRINTQ;
241 if (strequal(lp_fstype(snum), "IPC"))
242 type = STYPE_IPC;
243 if (lp_administrative_share(snum))
244 type |= STYPE_HIDDEN;
246 return type;
249 /*******************************************************************
250 Fill in a share info level 0 structure.
251 ********************************************************************/
253 static void init_srv_share_info_0(struct pipes_struct *p,
254 struct srvsvc_NetShareInfo0 *r, int snum)
256 r->name = lp_servicename(snum);
259 /*******************************************************************
260 Fill in a share info level 1 structure.
261 ********************************************************************/
263 static void init_srv_share_info_1(struct pipes_struct *p,
264 struct srvsvc_NetShareInfo1 *r,
265 int snum)
267 char *net_name = lp_servicename(snum);
268 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
270 if (remark) {
271 remark = talloc_sub_advanced(
272 p->mem_ctx, lp_servicename(snum),
273 get_current_username(), lp_pathname(snum),
274 p->server_info->utok.uid, get_current_username(),
275 "", remark);
278 r->name = net_name;
279 r->type = get_share_type(snum);
280 r->comment = remark ? remark : "";
283 /*******************************************************************
284 Fill in a share info level 2 structure.
285 ********************************************************************/
287 static void init_srv_share_info_2(struct pipes_struct *p,
288 struct srvsvc_NetShareInfo2 *r,
289 int snum)
291 char *remark = NULL;
292 char *path = NULL;
293 int max_connections = lp_max_connections(snum);
294 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
295 char *net_name = lp_servicename(snum);
297 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
298 if (remark) {
299 remark = talloc_sub_advanced(
300 p->mem_ctx, lp_servicename(snum),
301 get_current_username(), lp_pathname(snum),
302 p->server_info->utok.uid, get_current_username(),
303 "", remark);
305 path = talloc_asprintf(p->mem_ctx,
306 "C:%s", lp_pathname(snum));
308 if (path) {
310 * Change / to \\ so that win2k will see it as a valid path.
311 * This was added to enable use of browsing in win2k add
312 * share dialog.
315 string_replace(path, '/', '\\');
318 r->name = net_name;
319 r->type = get_share_type(snum);
320 r->comment = remark ? remark : "";
321 r->permissions = 0;
322 r->max_users = max_uses;
323 r->current_users = count_current_connections(net_name, false);
324 r->path = path ? path : "";
325 r->password = "";
328 /*******************************************************************
329 Map any generic bits to file specific bits.
330 ********************************************************************/
332 static void map_generic_share_sd_bits(struct security_descriptor *psd)
334 int i;
335 struct security_acl *ps_dacl = NULL;
337 if (!psd)
338 return;
340 ps_dacl = psd->dacl;
341 if (!ps_dacl)
342 return;
344 for (i = 0; i < ps_dacl->num_aces; i++) {
345 struct security_ace *psa = &ps_dacl->aces[i];
346 uint32 orig_mask = psa->access_mask;
348 se_map_generic(&psa->access_mask, &file_generic_mapping);
349 psa->access_mask |= orig_mask;
353 /*******************************************************************
354 Fill in a share info level 501 structure.
355 ********************************************************************/
357 static void init_srv_share_info_501(struct pipes_struct *p,
358 struct srvsvc_NetShareInfo501 *r, int snum)
360 const char *net_name = lp_servicename(snum);
361 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
363 if (remark) {
364 remark = talloc_sub_advanced(
365 p->mem_ctx, lp_servicename(snum),
366 get_current_username(), lp_pathname(snum),
367 p->server_info->utok.uid, get_current_username(),
368 "", remark);
371 r->name = net_name;
372 r->type = get_share_type(snum);
373 r->comment = remark ? remark : "";
374 r->csc_policy = (lp_csc_policy(snum) << 4);
377 /*******************************************************************
378 Fill in a share info level 502 structure.
379 ********************************************************************/
381 static void init_srv_share_info_502(struct pipes_struct *p,
382 struct srvsvc_NetShareInfo502 *r, int snum)
384 const char *net_name = lp_servicename(snum);
385 char *path = NULL;
386 struct security_descriptor *sd = NULL;
387 struct sec_desc_buf *sd_buf = NULL;
388 size_t sd_size = 0;
389 TALLOC_CTX *ctx = p->mem_ctx;
390 char *remark = talloc_strdup(ctx, lp_comment(snum));;
392 if (remark) {
393 remark = talloc_sub_advanced(
394 p->mem_ctx, lp_servicename(snum),
395 get_current_username(), lp_pathname(snum),
396 p->server_info->utok.uid, get_current_username(),
397 "", remark);
399 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
400 if (path) {
402 * Change / to \\ so that win2k will see it as a valid path. This was added to
403 * enable use of browsing in win2k add share dialog.
405 string_replace(path, '/', '\\');
408 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
410 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
412 r->name = net_name;
413 r->type = get_share_type(snum);
414 r->comment = remark ? remark : "";
415 r->permissions = 0;
416 r->max_users = (uint32_t)-1;
417 r->current_users = 1; /* ??? */
418 r->path = path ? path : "";
419 r->password = "";
420 r->sd_buf = *sd_buf;
423 /***************************************************************************
424 Fill in a share info level 1004 structure.
425 ***************************************************************************/
427 static void init_srv_share_info_1004(struct pipes_struct *p,
428 struct srvsvc_NetShareInfo1004 *r,
429 int snum)
431 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
433 if (remark) {
434 remark = talloc_sub_advanced(
435 p->mem_ctx, lp_servicename(snum),
436 get_current_username(), lp_pathname(snum),
437 p->server_info->utok.uid, get_current_username(),
438 "", remark);
441 r->comment = remark ? remark : "";
444 /***************************************************************************
445 Fill in a share info level 1005 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1005(struct pipes_struct *p,
449 struct srvsvc_NetShareInfo1005 *r,
450 int snum)
452 uint32_t dfs_flags = 0;
454 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
455 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
458 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
460 r->dfs_flags = dfs_flags;
463 /***************************************************************************
464 Fill in a share info level 1006 structure.
465 ***************************************************************************/
467 static void init_srv_share_info_1006(struct pipes_struct *p,
468 struct srvsvc_NetShareInfo1006 *r,
469 int snum)
471 r->max_users = (uint32_t)-1;
474 /***************************************************************************
475 Fill in a share info level 1007 structure.
476 ***************************************************************************/
478 static void init_srv_share_info_1007(struct pipes_struct *p,
479 struct srvsvc_NetShareInfo1007 *r,
480 int snum)
482 r->flags = 0;
483 r->alternate_directory_name = "";
486 /*******************************************************************
487 Fill in a share info level 1501 structure.
488 ********************************************************************/
490 static void init_srv_share_info_1501(struct pipes_struct *p,
491 struct sec_desc_buf *r,
492 int snum)
494 struct security_descriptor *sd;
495 size_t sd_size;
496 TALLOC_CTX *ctx = p->mem_ctx;
498 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
500 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
503 /*******************************************************************
504 True if it ends in '$'.
505 ********************************************************************/
507 static bool is_hidden_share(int snum)
509 const char *net_name = lp_servicename(snum);
511 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
514 /*******************************************************************
515 Verify user is allowed to view share, access based enumeration
516 ********************************************************************/
517 static bool is_enumeration_allowed(struct pipes_struct *p,
518 int snum)
520 if (!lp_access_based_share_enum(snum))
521 return true;
523 return share_access_check(p->server_info->ptok, lp_servicename(snum),
524 FILE_READ_DATA);
527 /*******************************************************************
528 Fill in a share info structure.
529 ********************************************************************/
531 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
532 struct srvsvc_NetShareInfoCtr *info_ctr,
533 uint32_t *resume_handle_p,
534 uint32_t *total_entries,
535 bool all_shares)
537 int num_entries = 0;
538 int alloc_entries = 0;
539 int num_services = 0;
540 int snum;
541 TALLOC_CTX *ctx = p->mem_ctx;
542 int i = 0;
543 int valid_share_count = 0;
544 bool *allowed = 0;
545 union srvsvc_NetShareCtr ctr;
546 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
548 DEBUG(5,("init_srv_share_info_ctr\n"));
550 /* Ensure all the usershares are loaded. */
551 become_root();
552 load_usershare_shares();
553 load_registry_shares();
554 num_services = lp_numservices();
555 unbecome_root();
557 allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
558 W_ERROR_HAVE_NO_MEMORY(allowed);
560 /* Count the number of entries. */
561 for (snum = 0; snum < num_services; snum++) {
562 if (lp_browseable(snum) && lp_snum_ok(snum) &&
563 is_enumeration_allowed(p, snum) &&
564 (all_shares || !is_hidden_share(snum)) ) {
565 DEBUG(10, ("counting service %s\n",
566 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
567 allowed[snum] = true;
568 num_entries++;
569 } else {
570 DEBUG(10, ("NOT counting service %s\n",
571 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
575 if (!num_entries || (resume_handle >= num_entries)) {
576 return WERR_OK;
579 /* Calculate alloc entries. */
580 alloc_entries = num_entries - resume_handle;
581 switch (info_ctr->level) {
582 case 0:
583 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
584 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
586 ctr.ctr0->count = alloc_entries;
587 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
588 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
590 for (snum = 0; snum < num_services; snum++) {
591 if (allowed[snum] &&
592 (resume_handle <= (i + valid_share_count++)) ) {
593 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
597 break;
599 case 1:
600 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
601 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
603 ctr.ctr1->count = alloc_entries;
604 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
605 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
607 for (snum = 0; snum < num_services; snum++) {
608 if (allowed[snum] &&
609 (resume_handle <= (i + valid_share_count++)) ) {
610 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
614 break;
616 case 2:
617 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
618 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
620 ctr.ctr2->count = alloc_entries;
621 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
622 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
624 for (snum = 0; snum < num_services; snum++) {
625 if (allowed[snum] &&
626 (resume_handle <= (i + valid_share_count++)) ) {
627 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
631 break;
633 case 501:
634 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
635 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
637 ctr.ctr501->count = alloc_entries;
638 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
639 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
641 for (snum = 0; snum < num_services; snum++) {
642 if (allowed[snum] &&
643 (resume_handle <= (i + valid_share_count++)) ) {
644 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
648 break;
650 case 502:
651 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
652 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
654 ctr.ctr502->count = alloc_entries;
655 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
656 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
658 for (snum = 0; snum < num_services; snum++) {
659 if (allowed[snum] &&
660 (resume_handle <= (i + valid_share_count++)) ) {
661 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
665 break;
667 case 1004:
668 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
669 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
671 ctr.ctr1004->count = alloc_entries;
672 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
673 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
675 for (snum = 0; snum < num_services; snum++) {
676 if (allowed[snum] &&
677 (resume_handle <= (i + valid_share_count++)) ) {
678 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
682 break;
684 case 1005:
685 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
686 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
688 ctr.ctr1005->count = alloc_entries;
689 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
690 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
692 for (snum = 0; snum < num_services; snum++) {
693 if (allowed[snum] &&
694 (resume_handle <= (i + valid_share_count++)) ) {
695 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
699 break;
701 case 1006:
702 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
703 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
705 ctr.ctr1006->count = alloc_entries;
706 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
707 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
709 for (snum = 0; snum < num_services; snum++) {
710 if (allowed[snum] &&
711 (resume_handle <= (i + valid_share_count++)) ) {
712 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
716 break;
718 case 1007:
719 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
720 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
722 ctr.ctr1007->count = alloc_entries;
723 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
724 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
726 for (snum = 0; snum < num_services; snum++) {
727 if (allowed[snum] &&
728 (resume_handle <= (i + valid_share_count++)) ) {
729 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
733 break;
735 case 1501:
736 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
737 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
739 ctr.ctr1501->count = alloc_entries;
740 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
741 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
743 for (snum = 0; snum < num_services; snum++) {
744 if (allowed[snum] &&
745 (resume_handle <= (i + valid_share_count++)) ) {
746 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
750 break;
752 default:
753 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
754 info_ctr->level));
755 return WERR_UNKNOWN_LEVEL;
758 *total_entries = alloc_entries;
759 if (resume_handle_p) {
760 if (all_shares) {
761 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
762 } else {
763 *resume_handle_p = num_entries;
767 info_ctr->ctr = ctr;
769 return WERR_OK;
772 /*******************************************************************
773 fill in a sess info level 0 structure.
774 ********************************************************************/
776 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
777 struct srvsvc_NetSessCtr0 *ctr0,
778 uint32_t *resume_handle_p,
779 uint32_t *total_entries)
781 struct sessionid *session_list;
782 uint32_t num_entries = 0;
783 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
784 *total_entries = list_sessions(p->mem_ctx, &session_list);
786 DEBUG(5,("init_srv_sess_info_0\n"));
788 if (ctr0 == NULL) {
789 if (resume_handle_p) {
790 *resume_handle_p = 0;
792 return WERR_OK;
795 for (; resume_handle < *total_entries; resume_handle++) {
797 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
798 ctr0->array,
799 struct srvsvc_NetSessInfo0,
800 num_entries+1);
801 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
803 ctr0->array[num_entries].client =
804 session_list[resume_handle].remote_machine;
806 num_entries++;
809 ctr0->count = num_entries;
811 if (resume_handle_p) {
812 if (*resume_handle_p >= *total_entries) {
813 *resume_handle_p = 0;
814 } else {
815 *resume_handle_p = resume_handle;
819 return WERR_OK;
822 /*******************************************************************
823 ********************************************************************/
825 static void sess_file_fn( const struct share_mode_entry *e,
826 const char *sharepath, const char *fname,
827 void *data )
829 struct sess_file_count *sess = (struct sess_file_count *)data;
831 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
832 sess->count++;
835 return;
838 /*******************************************************************
839 ********************************************************************/
841 static int net_count_files( uid_t uid, struct server_id pid )
843 struct sess_file_count s_file_cnt;
845 s_file_cnt.count = 0;
846 s_file_cnt.uid = uid;
847 s_file_cnt.pid = pid;
849 share_mode_forall( sess_file_fn, &s_file_cnt );
851 return s_file_cnt.count;
854 /*******************************************************************
855 fill in a sess info level 1 structure.
856 ********************************************************************/
858 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
859 struct srvsvc_NetSessCtr1 *ctr1,
860 uint32_t *resume_handle_p,
861 uint32_t *total_entries)
863 struct sessionid *session_list;
864 uint32_t num_entries = 0;
865 time_t now = time(NULL);
866 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
868 ZERO_STRUCTP(ctr1);
870 if (ctr1 == NULL) {
871 if (resume_handle_p) {
872 *resume_handle_p = 0;
874 return WERR_OK;
877 *total_entries = list_sessions(p->mem_ctx, &session_list);
879 for (; resume_handle < *total_entries; resume_handle++) {
880 uint32 num_files;
881 uint32 connect_time;
882 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
883 bool guest;
885 if ( !pw ) {
886 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
887 session_list[resume_handle].username));
888 continue;
891 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
892 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
893 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
895 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
896 ctr1->array,
897 struct srvsvc_NetSessInfo1,
898 num_entries+1);
899 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
901 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
902 ctr1->array[num_entries].user = session_list[resume_handle].username;
903 ctr1->array[num_entries].num_open = num_files;
904 ctr1->array[num_entries].time = connect_time;
905 ctr1->array[num_entries].idle_time = 0;
906 ctr1->array[num_entries].user_flags = guest;
908 num_entries++;
911 ctr1->count = num_entries;
913 if (resume_handle_p) {
914 if (*resume_handle_p >= *total_entries) {
915 *resume_handle_p = 0;
916 } else {
917 *resume_handle_p = resume_handle;
921 return WERR_OK;
924 /*******************************************************************
925 fill in a conn info level 0 structure.
926 ********************************************************************/
928 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
929 uint32_t *resume_handle_p,
930 uint32_t *total_entries)
932 uint32_t num_entries = 0;
933 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
935 DEBUG(5,("init_srv_conn_info_0\n"));
937 if (ctr0 == NULL) {
938 if (resume_handle_p) {
939 *resume_handle_p = 0;
941 return WERR_OK;
944 *total_entries = 1;
946 ZERO_STRUCTP(ctr0);
948 for (; resume_handle < *total_entries; resume_handle++) {
950 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
951 ctr0->array,
952 struct srvsvc_NetConnInfo0,
953 num_entries+1);
954 if (!ctr0->array) {
955 return WERR_NOMEM;
958 ctr0->array[num_entries].conn_id = *total_entries;
960 /* move on to creating next connection */
961 num_entries++;
964 ctr0->count = num_entries;
965 *total_entries = num_entries;
967 if (resume_handle_p) {
968 if (*resume_handle_p >= *total_entries) {
969 *resume_handle_p = 0;
970 } else {
971 *resume_handle_p = resume_handle;
975 return WERR_OK;
978 /*******************************************************************
979 fill in a conn info level 1 structure.
980 ********************************************************************/
982 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
983 uint32_t *resume_handle_p,
984 uint32_t *total_entries)
986 uint32_t num_entries = 0;
987 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
989 DEBUG(5,("init_srv_conn_info_1\n"));
991 if (ctr1 == NULL) {
992 if (resume_handle_p) {
993 *resume_handle_p = 0;
995 return WERR_OK;
998 *total_entries = 1;
1000 ZERO_STRUCTP(ctr1);
1002 for (; resume_handle < *total_entries; resume_handle++) {
1004 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
1005 ctr1->array,
1006 struct srvsvc_NetConnInfo1,
1007 num_entries+1);
1008 if (!ctr1->array) {
1009 return WERR_NOMEM;
1012 ctr1->array[num_entries].conn_id = *total_entries;
1013 ctr1->array[num_entries].conn_type = 0x3;
1014 ctr1->array[num_entries].num_open = 1;
1015 ctr1->array[num_entries].num_users = 1;
1016 ctr1->array[num_entries].conn_time = 3;
1017 ctr1->array[num_entries].user = "dummy_user";
1018 ctr1->array[num_entries].share = "IPC$";
1020 /* move on to creating next connection */
1021 num_entries++;
1024 ctr1->count = num_entries;
1025 *total_entries = num_entries;
1027 if (resume_handle_p) {
1028 if (*resume_handle_p >= *total_entries) {
1029 *resume_handle_p = 0;
1030 } else {
1031 *resume_handle_p = resume_handle;
1035 return WERR_OK;
1038 /*******************************************************************
1039 _srvsvc_NetFileEnum
1040 *******************************************************************/
1042 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1043 struct srvsvc_NetFileEnum *r)
1045 TALLOC_CTX *ctx = NULL;
1046 struct srvsvc_NetFileCtr3 *ctr3;
1047 uint32_t resume_hnd = 0;
1048 WERROR werr;
1050 switch (r->in.info_ctr->level) {
1051 case 3:
1052 break;
1053 default:
1054 return WERR_UNKNOWN_LEVEL;
1057 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1058 p->server_info->ptok)) {
1059 DEBUG(1, ("Enumerating files only allowed for "
1060 "administrators\n"));
1061 return WERR_ACCESS_DENIED;
1064 ctx = talloc_tos();
1065 ctr3 = r->in.info_ctr->ctr.ctr3;
1066 if (!ctr3) {
1067 werr = WERR_INVALID_PARAM;
1068 goto done;
1071 /* TODO -- Windows enumerates
1072 (b) active pipes
1073 (c) open directories and files */
1075 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1076 if (!W_ERROR_IS_OK(werr)) {
1077 goto done;
1080 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1081 if (!W_ERROR_IS_OK(werr)) {
1082 goto done;
1085 *r->out.totalentries = ctr3->count;
1086 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1087 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1089 werr = WERR_OK;
1091 done:
1092 return werr;
1095 /*******************************************************************
1096 _srvsvc_NetSrvGetInfo
1097 ********************************************************************/
1099 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1100 struct srvsvc_NetSrvGetInfo *r)
1102 WERROR status = WERR_OK;
1104 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1106 if (!pipe_access_check(p)) {
1107 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1108 return WERR_ACCESS_DENIED;
1111 switch (r->in.level) {
1113 /* Technically level 102 should only be available to
1114 Administrators but there isn't anything super-secret
1115 here, as most of it is made up. */
1117 case 102: {
1118 struct srvsvc_NetSrvInfo102 *info102;
1120 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1121 if (!info102) {
1122 return WERR_NOMEM;
1125 info102->platform_id = PLATFORM_ID_NT;
1126 info102->server_name = global_myname();
1127 info102->version_major = lp_major_announce_version();
1128 info102->version_minor = lp_minor_announce_version();
1129 info102->server_type = lp_default_server_announce();
1130 info102->comment = string_truncate(lp_serverstring(),
1131 MAX_SERVER_STRING_LENGTH);
1132 info102->users = 0xffffffff;
1133 info102->disc = 0xf;
1134 info102->hidden = 0;
1135 info102->announce = 240;
1136 info102->anndelta = 3000;
1137 info102->licenses = 100000;
1138 info102->userpath = "C:\\";
1140 r->out.info->info102 = info102;
1141 break;
1143 case 101: {
1144 struct srvsvc_NetSrvInfo101 *info101;
1146 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1147 if (!info101) {
1148 return WERR_NOMEM;
1151 info101->platform_id = PLATFORM_ID_NT;
1152 info101->server_name = global_myname();
1153 info101->version_major = lp_major_announce_version();
1154 info101->version_minor = lp_minor_announce_version();
1155 info101->server_type = lp_default_server_announce();
1156 info101->comment = string_truncate(lp_serverstring(),
1157 MAX_SERVER_STRING_LENGTH);
1159 r->out.info->info101 = info101;
1160 break;
1162 case 100: {
1163 struct srvsvc_NetSrvInfo100 *info100;
1165 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1166 if (!info100) {
1167 return WERR_NOMEM;
1170 info100->platform_id = PLATFORM_ID_NT;
1171 info100->server_name = global_myname();
1173 r->out.info->info100 = info100;
1175 break;
1177 default:
1178 status = WERR_UNKNOWN_LEVEL;
1179 break;
1182 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1184 return status;
1187 /*******************************************************************
1188 _srvsvc_NetSrvSetInfo
1189 ********************************************************************/
1191 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1192 struct srvsvc_NetSrvSetInfo *r)
1194 WERROR status = WERR_OK;
1196 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1198 /* Set up the net server set info structure. */
1200 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1202 return status;
1205 /*******************************************************************
1206 _srvsvc_NetConnEnum
1207 ********************************************************************/
1209 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1210 struct srvsvc_NetConnEnum *r)
1212 WERROR werr;
1214 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1216 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1217 p->server_info->ptok)) {
1218 DEBUG(1, ("Enumerating connections only allowed for "
1219 "administrators\n"));
1220 return WERR_ACCESS_DENIED;
1223 switch (r->in.info_ctr->level) {
1224 case 0:
1225 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1226 r->in.resume_handle,
1227 r->out.totalentries);
1228 break;
1229 case 1:
1230 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1231 r->in.resume_handle,
1232 r->out.totalentries);
1233 break;
1234 default:
1235 return WERR_UNKNOWN_LEVEL;
1238 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1240 return werr;
1243 /*******************************************************************
1244 _srvsvc_NetSessEnum
1245 ********************************************************************/
1247 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1248 struct srvsvc_NetSessEnum *r)
1250 WERROR werr;
1252 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1254 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1255 p->server_info->ptok)) {
1256 DEBUG(1, ("Enumerating sessions only allowed for "
1257 "administrators\n"));
1258 return WERR_ACCESS_DENIED;
1261 switch (r->in.info_ctr->level) {
1262 case 0:
1263 werr = init_srv_sess_info_0(p,
1264 r->in.info_ctr->ctr.ctr0,
1265 r->in.resume_handle,
1266 r->out.totalentries);
1267 break;
1268 case 1:
1269 werr = init_srv_sess_info_1(p,
1270 r->in.info_ctr->ctr.ctr1,
1271 r->in.resume_handle,
1272 r->out.totalentries);
1273 break;
1274 default:
1275 return WERR_UNKNOWN_LEVEL;
1278 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1280 return werr;
1283 /*******************************************************************
1284 _srvsvc_NetSessDel
1285 ********************************************************************/
1287 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1288 struct srvsvc_NetSessDel *r)
1290 struct sessionid *session_list;
1291 int num_sessions, snum;
1292 const char *username;
1293 const char *machine;
1294 bool not_root = False;
1295 WERROR werr;
1297 username = r->in.user;
1298 machine = r->in.client;
1300 /* strip leading backslashes if any */
1301 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1302 machine += 2;
1305 num_sessions = list_sessions(p->mem_ctx, &session_list);
1307 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1309 werr = WERR_ACCESS_DENIED;
1311 /* fail out now if you are not root or not a domain admin */
1313 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1314 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1315 DOMAIN_RID_ADMINS))) {
1317 goto done;
1320 for (snum = 0; snum < num_sessions; snum++) {
1322 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1323 strequal(session_list[snum].remote_machine, machine)) {
1325 NTSTATUS ntstat;
1327 if (p->server_info->utok.uid != sec_initial_uid()) {
1328 not_root = True;
1329 become_root();
1332 ntstat = messaging_send(p->msg_ctx,
1333 session_list[snum].pid,
1334 MSG_SHUTDOWN, &data_blob_null);
1336 if (NT_STATUS_IS_OK(ntstat))
1337 werr = WERR_OK;
1339 if (not_root)
1340 unbecome_root();
1344 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1346 done:
1348 return werr;
1351 /*******************************************************************
1352 _srvsvc_NetShareEnumAll
1353 ********************************************************************/
1355 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1356 struct srvsvc_NetShareEnumAll *r)
1358 WERROR werr;
1360 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1362 if (!pipe_access_check(p)) {
1363 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1364 return WERR_ACCESS_DENIED;
1367 /* Create the list of shares for the response. */
1368 werr = init_srv_share_info_ctr(p,
1369 r->in.info_ctr,
1370 r->in.resume_handle,
1371 r->out.totalentries,
1372 true);
1374 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1376 return werr;
1379 /*******************************************************************
1380 _srvsvc_NetShareEnum
1381 ********************************************************************/
1383 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1384 struct srvsvc_NetShareEnum *r)
1386 WERROR werr;
1388 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1390 if (!pipe_access_check(p)) {
1391 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1392 return WERR_ACCESS_DENIED;
1395 /* Create the list of shares for the response. */
1396 werr = init_srv_share_info_ctr(p,
1397 r->in.info_ctr,
1398 r->in.resume_handle,
1399 r->out.totalentries,
1400 false);
1402 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1404 return werr;
1407 /*******************************************************************
1408 _srvsvc_NetShareGetInfo
1409 ********************************************************************/
1411 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1412 struct srvsvc_NetShareGetInfo *r)
1414 WERROR status = WERR_OK;
1415 fstring share_name;
1416 int snum;
1417 union srvsvc_NetShareInfo *info = r->out.info;
1419 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1421 fstrcpy(share_name, r->in.share_name);
1423 snum = find_service(share_name);
1424 if (snum < 0) {
1425 return WERR_INVALID_NAME;
1428 switch (r->in.level) {
1429 case 0:
1430 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1431 W_ERROR_HAVE_NO_MEMORY(info->info0);
1432 init_srv_share_info_0(p, info->info0, snum);
1433 break;
1434 case 1:
1435 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1436 W_ERROR_HAVE_NO_MEMORY(info->info1);
1437 init_srv_share_info_1(p, info->info1, snum);
1438 break;
1439 case 2:
1440 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1441 W_ERROR_HAVE_NO_MEMORY(info->info2);
1442 init_srv_share_info_2(p, info->info2, snum);
1443 break;
1444 case 501:
1445 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1446 W_ERROR_HAVE_NO_MEMORY(info->info501);
1447 init_srv_share_info_501(p, info->info501, snum);
1448 break;
1449 case 502:
1450 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1451 W_ERROR_HAVE_NO_MEMORY(info->info502);
1452 init_srv_share_info_502(p, info->info502, snum);
1453 break;
1454 case 1004:
1455 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1456 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1457 init_srv_share_info_1004(p, info->info1004, snum);
1458 break;
1459 case 1005:
1460 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1461 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1462 init_srv_share_info_1005(p, info->info1005, snum);
1463 break;
1464 case 1006:
1465 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1466 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1467 init_srv_share_info_1006(p, info->info1006, snum);
1468 break;
1469 case 1007:
1470 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1471 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1472 init_srv_share_info_1007(p, info->info1007, snum);
1473 break;
1474 case 1501:
1475 init_srv_share_info_1501(p, info->info1501, snum);
1476 break;
1477 default:
1478 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1479 r->in.level));
1480 status = WERR_UNKNOWN_LEVEL;
1481 break;
1484 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1486 return status;
1489 /*******************************************************************
1490 Check a given DOS pathname is valid for a share.
1491 ********************************************************************/
1493 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1495 char *ptr = NULL;
1497 if (!dos_pathname) {
1498 return NULL;
1501 ptr = talloc_strdup(ctx, dos_pathname);
1502 if (!ptr) {
1503 return NULL;
1505 /* Convert any '\' paths to '/' */
1506 unix_format(ptr);
1507 ptr = unix_clean_name(ctx, ptr);
1508 if (!ptr) {
1509 return NULL;
1512 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1513 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1514 ptr += 2;
1516 /* Only absolute paths allowed. */
1517 if (*ptr != '/')
1518 return NULL;
1520 return ptr;
1523 /*******************************************************************
1524 _srvsvc_NetShareSetInfo. Modify share details.
1525 ********************************************************************/
1527 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1528 struct srvsvc_NetShareSetInfo *r)
1530 char *command = NULL;
1531 char *share_name = NULL;
1532 char *comment = NULL;
1533 const char *pathname = NULL;
1534 int type;
1535 int snum;
1536 int ret;
1537 char *path = NULL;
1538 struct security_descriptor *psd = NULL;
1539 bool is_disk_op = False;
1540 int max_connections = 0;
1541 TALLOC_CTX *ctx = p->mem_ctx;
1542 union srvsvc_NetShareInfo *info = r->in.info;
1544 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1546 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1547 if (!share_name) {
1548 return WERR_NOMEM;
1551 if (r->out.parm_error) {
1552 *r->out.parm_error = 0;
1555 if ( strequal(share_name,"IPC$")
1556 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1557 || strequal(share_name,"global") )
1559 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1560 "modified by a remote user.\n",
1561 share_name ));
1562 return WERR_ACCESS_DENIED;
1565 snum = find_service(share_name);
1567 /* Does this share exist ? */
1568 if (snum < 0)
1569 return WERR_NET_NAME_NOT_FOUND;
1571 /* No change to printer shares. */
1572 if (lp_print_ok(snum))
1573 return WERR_ACCESS_DENIED;
1575 is_disk_op = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_DISK_OPERATOR);
1577 /* fail out now if you are not root and not a disk op */
1579 if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1580 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1581 "SeDiskOperatorPrivilege privilege needed to modify "
1582 "share %s\n",
1583 (unsigned int)p->server_info->utok.uid,
1584 share_name ));
1585 return WERR_ACCESS_DENIED;
1588 switch (r->in.level) {
1589 case 1:
1590 pathname = talloc_strdup(ctx, lp_pathname(snum));
1591 comment = talloc_strdup(ctx, info->info1->comment);
1592 type = info->info1->type;
1593 psd = NULL;
1594 break;
1595 case 2:
1596 comment = talloc_strdup(ctx, info->info2->comment);
1597 pathname = info->info2->path;
1598 type = info->info2->type;
1599 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1600 0 : info->info2->max_users;
1601 psd = NULL;
1602 break;
1603 #if 0
1604 /* not supported on set but here for completeness */
1605 case 501:
1606 comment = talloc_strdup(ctx, info->info501->comment);
1607 type = info->info501->type;
1608 psd = NULL;
1609 break;
1610 #endif
1611 case 502:
1612 comment = talloc_strdup(ctx, info->info502->comment);
1613 pathname = info->info502->path;
1614 type = info->info502->type;
1615 psd = info->info502->sd_buf.sd;
1616 map_generic_share_sd_bits(psd);
1617 break;
1618 case 1004:
1619 pathname = talloc_strdup(ctx, lp_pathname(snum));
1620 comment = talloc_strdup(ctx, info->info1004->comment);
1621 type = STYPE_DISKTREE;
1622 break;
1623 case 1005:
1624 /* XP re-sets the csc policy even if it wasn't changed by the
1625 user, so we must compare it to see if it's what is set in
1626 smb.conf, so that we can contine other ops like setting
1627 ACLs on a share */
1628 if (((info->info1005->dfs_flags &
1629 SHARE_1005_CSC_POLICY_MASK) >>
1630 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1631 return WERR_OK;
1632 else {
1633 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1634 return WERR_ACCESS_DENIED;
1636 case 1006:
1637 case 1007:
1638 return WERR_ACCESS_DENIED;
1639 case 1501:
1640 pathname = talloc_strdup(ctx, lp_pathname(snum));
1641 comment = talloc_strdup(ctx, lp_comment(snum));
1642 psd = info->info1501->sd;
1643 map_generic_share_sd_bits(psd);
1644 type = STYPE_DISKTREE;
1645 break;
1646 default:
1647 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1648 r->in.level));
1649 return WERR_UNKNOWN_LEVEL;
1652 /* We can only modify disk shares. */
1653 if (type != STYPE_DISKTREE) {
1654 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1655 "disk share\n",
1656 share_name ));
1657 return WERR_ACCESS_DENIED;
1660 if (comment == NULL) {
1661 return WERR_NOMEM;
1664 /* Check if the pathname is valid. */
1665 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1666 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1667 pathname ));
1668 return WERR_OBJECT_PATH_INVALID;
1671 /* Ensure share name, pathname and comment don't contain '"' characters. */
1672 string_replace(share_name, '"', ' ');
1673 string_replace(path, '"', ' ');
1674 string_replace(comment, '"', ' ');
1676 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1677 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1679 /* Only call modify function if something changed. */
1681 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1682 || (lp_max_connections(snum) != max_connections)) {
1683 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1684 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1685 return WERR_ACCESS_DENIED;
1688 command = talloc_asprintf(p->mem_ctx,
1689 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1690 lp_change_share_cmd(),
1691 get_dyn_CONFIGFILE(),
1692 share_name,
1693 path,
1694 comment ? comment : "",
1695 max_connections);
1696 if (!command) {
1697 return WERR_NOMEM;
1700 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1702 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1704 if (is_disk_op)
1705 become_root();
1707 if ( (ret = smbrun(command, NULL)) == 0 ) {
1708 /* Tell everyone we updated smb.conf. */
1709 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1710 NULL, 0, NULL);
1713 if ( is_disk_op )
1714 unbecome_root();
1716 /********* END SeDiskOperatorPrivilege BLOCK *********/
1718 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1719 command, ret ));
1721 TALLOC_FREE(command);
1723 if ( ret != 0 )
1724 return WERR_ACCESS_DENIED;
1725 } else {
1726 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1727 share_name ));
1730 /* Replace SD if changed. */
1731 if (psd) {
1732 struct security_descriptor *old_sd;
1733 size_t sd_size;
1735 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1737 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1738 if (!set_share_security(share_name, psd))
1739 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1740 share_name ));
1744 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1746 return WERR_OK;
1749 /*******************************************************************
1750 _srvsvc_NetShareAdd.
1751 Call 'add_share_command "sharename" "pathname"
1752 "comment" "max connections = "
1753 ********************************************************************/
1755 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1756 struct srvsvc_NetShareAdd *r)
1758 char *command = NULL;
1759 char *share_name = NULL;
1760 char *comment = NULL;
1761 char *pathname = NULL;
1762 int type;
1763 int snum;
1764 int ret;
1765 char *path;
1766 struct security_descriptor *psd = NULL;
1767 bool is_disk_op;
1768 int max_connections = 0;
1769 TALLOC_CTX *ctx = p->mem_ctx;
1771 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1773 if (r->out.parm_error) {
1774 *r->out.parm_error = 0;
1777 is_disk_op = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_DISK_OPERATOR);
1779 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1780 return WERR_ACCESS_DENIED;
1782 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1783 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1784 return WERR_ACCESS_DENIED;
1787 switch (r->in.level) {
1788 case 0:
1789 /* No path. Not enough info in a level 0 to do anything. */
1790 return WERR_ACCESS_DENIED;
1791 case 1:
1792 /* Not enough info in a level 1 to do anything. */
1793 return WERR_ACCESS_DENIED;
1794 case 2:
1795 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1796 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1797 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1798 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1799 0 : r->in.info->info2->max_users;
1800 type = r->in.info->info2->type;
1801 break;
1802 case 501:
1803 /* No path. Not enough info in a level 501 to do anything. */
1804 return WERR_ACCESS_DENIED;
1805 case 502:
1806 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1807 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1808 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1809 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1810 0 : r->in.info->info502->max_users;
1811 type = r->in.info->info502->type;
1812 psd = r->in.info->info502->sd_buf.sd;
1813 map_generic_share_sd_bits(psd);
1814 break;
1816 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1818 case 1004:
1819 case 1005:
1820 case 1006:
1821 case 1007:
1822 return WERR_ACCESS_DENIED;
1823 case 1501:
1824 /* DFS only level. */
1825 return WERR_ACCESS_DENIED;
1826 default:
1827 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1828 r->in.level));
1829 return WERR_UNKNOWN_LEVEL;
1832 /* check for invalid share names */
1834 if (!share_name || !validate_net_name(share_name,
1835 INVALID_SHARENAME_CHARS,
1836 strlen(share_name))) {
1837 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1838 share_name ? share_name : ""));
1839 return WERR_INVALID_NAME;
1842 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1843 || (lp_enable_asu_support() &&
1844 strequal(share_name,"ADMIN$"))) {
1845 return WERR_ACCESS_DENIED;
1848 snum = find_service(share_name);
1850 /* Share already exists. */
1851 if (snum >= 0) {
1852 return WERR_FILE_EXISTS;
1855 /* We can only add disk shares. */
1856 if (type != STYPE_DISKTREE) {
1857 return WERR_ACCESS_DENIED;
1860 /* Check if the pathname is valid. */
1861 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1862 return WERR_OBJECT_PATH_INVALID;
1865 /* Ensure share name, pathname and comment don't contain '"' characters. */
1866 string_replace(share_name, '"', ' ');
1867 string_replace(path, '"', ' ');
1868 if (comment) {
1869 string_replace(comment, '"', ' ');
1872 command = talloc_asprintf(ctx,
1873 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1874 lp_add_share_cmd(),
1875 get_dyn_CONFIGFILE(),
1876 share_name,
1877 path,
1878 comment ? comment : "",
1879 max_connections);
1880 if (!command) {
1881 return WERR_NOMEM;
1884 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1886 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1888 if ( is_disk_op )
1889 become_root();
1891 /* FIXME: use libnetconf here - gd */
1893 if ( (ret = smbrun(command, NULL)) == 0 ) {
1894 /* Tell everyone we updated smb.conf. */
1895 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1896 NULL);
1899 if ( is_disk_op )
1900 unbecome_root();
1902 /********* END SeDiskOperatorPrivilege BLOCK *********/
1904 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1905 command, ret ));
1907 TALLOC_FREE(command);
1909 if ( ret != 0 )
1910 return WERR_ACCESS_DENIED;
1912 if (psd) {
1913 if (!set_share_security(share_name, psd)) {
1914 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1915 share_name ));
1920 * We don't call reload_services() here, the message will
1921 * cause this to be done before the next packet is read
1922 * from the client. JRA.
1925 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1927 return WERR_OK;
1930 /*******************************************************************
1931 _srvsvc_NetShareDel
1932 Call "delete share command" with the share name as
1933 a parameter.
1934 ********************************************************************/
1936 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
1937 struct srvsvc_NetShareDel *r)
1939 char *command = NULL;
1940 char *share_name = NULL;
1941 int ret;
1942 int snum;
1943 bool is_disk_op;
1944 struct share_params *params;
1945 TALLOC_CTX *ctx = p->mem_ctx;
1947 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1949 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1950 if (!share_name) {
1951 return WERR_NET_NAME_NOT_FOUND;
1953 if ( strequal(share_name,"IPC$")
1954 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1955 || strequal(share_name,"global") )
1957 return WERR_ACCESS_DENIED;
1960 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1961 return WERR_NO_SUCH_SHARE;
1964 snum = find_service(share_name);
1966 /* No change to printer shares. */
1967 if (lp_print_ok(snum))
1968 return WERR_ACCESS_DENIED;
1970 is_disk_op = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_DISK_OPERATOR);
1972 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1973 return WERR_ACCESS_DENIED;
1975 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1976 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1977 return WERR_ACCESS_DENIED;
1980 command = talloc_asprintf(ctx,
1981 "%s \"%s\" \"%s\"",
1982 lp_delete_share_cmd(),
1983 get_dyn_CONFIGFILE(),
1984 lp_servicename(snum));
1985 if (!command) {
1986 return WERR_NOMEM;
1989 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1991 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1993 if ( is_disk_op )
1994 become_root();
1996 if ( (ret = smbrun(command, NULL)) == 0 ) {
1997 /* Tell everyone we updated smb.conf. */
1998 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1999 NULL);
2002 if ( is_disk_op )
2003 unbecome_root();
2005 /********* END SeDiskOperatorPrivilege BLOCK *********/
2007 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2009 if ( ret != 0 )
2010 return WERR_ACCESS_DENIED;
2012 /* Delete the SD in the database. */
2013 delete_share_security(lp_servicename(params->service));
2015 lp_killservice(params->service);
2017 return WERR_OK;
2020 /*******************************************************************
2021 _srvsvc_NetShareDelSticky
2022 ********************************************************************/
2024 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2025 struct srvsvc_NetShareDelSticky *r)
2027 struct srvsvc_NetShareDel q;
2029 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2031 q.in.server_unc = r->in.server_unc;
2032 q.in.share_name = r->in.share_name;
2033 q.in.reserved = r->in.reserved;
2035 return _srvsvc_NetShareDel(p, &q);
2038 /*******************************************************************
2039 _srvsvc_NetRemoteTOD
2040 ********************************************************************/
2042 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2043 struct srvsvc_NetRemoteTOD *r)
2045 struct srvsvc_NetRemoteTODInfo *tod;
2046 struct tm *t;
2047 time_t unixdate = time(NULL);
2049 /* We do this call first as if we do it *after* the gmtime call
2050 it overwrites the pointed-to values. JRA */
2052 uint32 zone = get_time_zone(unixdate)/60;
2054 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2056 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2057 return WERR_NOMEM;
2059 *r->out.info = tod;
2061 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2063 t = gmtime(&unixdate);
2065 /* set up the */
2066 tod->elapsed = unixdate;
2067 tod->msecs = 0;
2068 tod->hours = t->tm_hour;
2069 tod->mins = t->tm_min;
2070 tod->secs = t->tm_sec;
2071 tod->hunds = 0;
2072 tod->timezone = zone;
2073 tod->tinterval = 10000;
2074 tod->day = t->tm_mday;
2075 tod->month = t->tm_mon + 1;
2076 tod->year = 1900+t->tm_year;
2077 tod->weekday = t->tm_wday;
2079 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2081 return WERR_OK;
2084 /***********************************************************************************
2085 _srvsvc_NetGetFileSecurity
2086 Win9x NT tools get security descriptor.
2087 ***********************************************************************************/
2089 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2090 struct srvsvc_NetGetFileSecurity *r)
2092 struct smb_filename *smb_fname = NULL;
2093 struct security_descriptor *psd = NULL;
2094 size_t sd_size;
2095 fstring servicename;
2096 SMB_STRUCT_STAT st;
2097 NTSTATUS nt_status;
2098 WERROR werr;
2099 connection_struct *conn = NULL;
2100 struct sec_desc_buf *sd_buf = NULL;
2101 files_struct *fsp = NULL;
2102 int snum;
2103 char *oldcwd = NULL;
2105 ZERO_STRUCT(st);
2107 fstrcpy(servicename, r->in.share);
2109 snum = find_service(servicename);
2110 if (snum == -1) {
2111 DEBUG(10, ("Could not find service %s\n", servicename));
2112 werr = WERR_NET_NAME_NOT_FOUND;
2113 goto error_exit;
2116 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2117 lp_pathname(snum), p->server_info,
2118 &oldcwd);
2119 if (!NT_STATUS_IS_OK(nt_status)) {
2120 DEBUG(10, ("create_conn_struct failed: %s\n",
2121 nt_errstr(nt_status)));
2122 werr = ntstatus_to_werror(nt_status);
2123 goto error_exit;
2126 nt_status = filename_convert(talloc_tos(),
2127 conn,
2128 false,
2129 r->in.file,
2131 NULL,
2132 &smb_fname);
2133 if (!NT_STATUS_IS_OK(nt_status)) {
2134 werr = ntstatus_to_werror(nt_status);
2135 goto error_exit;
2138 nt_status = SMB_VFS_CREATE_FILE(
2139 conn, /* conn */
2140 NULL, /* req */
2141 0, /* root_dir_fid */
2142 smb_fname, /* fname */
2143 FILE_READ_ATTRIBUTES, /* access_mask */
2144 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2145 FILE_OPEN, /* create_disposition*/
2146 0, /* create_options */
2147 0, /* file_attributes */
2148 INTERNAL_OPEN_ONLY, /* oplock_request */
2149 0, /* allocation_size */
2150 0, /* private_flags */
2151 NULL, /* sd */
2152 NULL, /* ea_list */
2153 &fsp, /* result */
2154 NULL); /* pinfo */
2156 if (!NT_STATUS_IS_OK(nt_status)) {
2157 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2158 smb_fname_str_dbg(smb_fname)));
2159 werr = ntstatus_to_werror(nt_status);
2160 goto error_exit;
2163 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2164 (SECINFO_OWNER
2165 |SECINFO_GROUP
2166 |SECINFO_DACL), &psd);
2168 if (!NT_STATUS_IS_OK(nt_status)) {
2169 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2170 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2171 werr = ntstatus_to_werror(nt_status);
2172 goto error_exit;
2175 sd_size = ndr_size_security_descriptor(psd, 0);
2177 sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2178 if (!sd_buf) {
2179 werr = WERR_NOMEM;
2180 goto error_exit;
2183 sd_buf->sd_size = sd_size;
2184 sd_buf->sd = psd;
2186 *r->out.sd_buf = sd_buf;
2188 psd->dacl->revision = NT4_ACL_REVISION;
2190 close_file(NULL, fsp, NORMAL_CLOSE);
2191 vfs_ChDir(conn, oldcwd);
2192 conn_free(conn);
2193 werr = WERR_OK;
2194 goto done;
2196 error_exit:
2198 if (fsp) {
2199 close_file(NULL, fsp, NORMAL_CLOSE);
2202 if (oldcwd) {
2203 vfs_ChDir(conn, oldcwd);
2206 if (conn) {
2207 conn_free(conn);
2210 done:
2211 TALLOC_FREE(smb_fname);
2213 return werr;
2216 /***********************************************************************************
2217 _srvsvc_NetSetFileSecurity
2218 Win9x NT tools set security descriptor.
2219 ***********************************************************************************/
2221 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2222 struct srvsvc_NetSetFileSecurity *r)
2224 struct smb_filename *smb_fname = NULL;
2225 fstring servicename;
2226 files_struct *fsp = NULL;
2227 SMB_STRUCT_STAT st;
2228 NTSTATUS nt_status;
2229 WERROR werr;
2230 connection_struct *conn = NULL;
2231 int snum;
2232 char *oldcwd = NULL;
2233 struct security_descriptor *psd = NULL;
2234 uint32_t security_info_sent = 0;
2236 ZERO_STRUCT(st);
2238 fstrcpy(servicename, r->in.share);
2240 snum = find_service(servicename);
2241 if (snum == -1) {
2242 DEBUG(10, ("Could not find service %s\n", servicename));
2243 werr = WERR_NET_NAME_NOT_FOUND;
2244 goto error_exit;
2247 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2248 lp_pathname(snum), p->server_info,
2249 &oldcwd);
2250 if (!NT_STATUS_IS_OK(nt_status)) {
2251 DEBUG(10, ("create_conn_struct failed: %s\n",
2252 nt_errstr(nt_status)));
2253 werr = ntstatus_to_werror(nt_status);
2254 goto error_exit;
2257 nt_status = filename_convert(talloc_tos(),
2258 conn,
2259 false,
2260 r->in.file,
2262 NULL,
2263 &smb_fname);
2264 if (!NT_STATUS_IS_OK(nt_status)) {
2265 werr = ntstatus_to_werror(nt_status);
2266 goto error_exit;
2269 nt_status = SMB_VFS_CREATE_FILE(
2270 conn, /* conn */
2271 NULL, /* req */
2272 0, /* root_dir_fid */
2273 smb_fname, /* fname */
2274 FILE_WRITE_ATTRIBUTES, /* access_mask */
2275 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2276 FILE_OPEN, /* create_disposition*/
2277 0, /* create_options */
2278 0, /* file_attributes */
2279 INTERNAL_OPEN_ONLY, /* oplock_request */
2280 0, /* allocation_size */
2281 0, /* private_flags */
2282 NULL, /* sd */
2283 NULL, /* ea_list */
2284 &fsp, /* result */
2285 NULL); /* pinfo */
2287 if (!NT_STATUS_IS_OK(nt_status)) {
2288 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2289 smb_fname_str_dbg(smb_fname)));
2290 werr = ntstatus_to_werror(nt_status);
2291 goto error_exit;
2294 psd = r->in.sd_buf->sd;
2295 security_info_sent = r->in.securityinformation;
2297 if (psd->owner_sid==0) {
2298 security_info_sent &= ~SECINFO_OWNER;
2300 if (psd->group_sid==0) {
2301 security_info_sent &= ~SECINFO_GROUP;
2303 if (psd->sacl==0) {
2304 security_info_sent &= ~SECINFO_SACL;
2306 if (psd->dacl==0) {
2307 security_info_sent &= ~SECINFO_DACL;
2310 /* Convert all the generic bits. */
2311 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2312 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2314 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2315 security_info_sent,
2316 psd);
2318 if (!NT_STATUS_IS_OK(nt_status) ) {
2319 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2320 "on file %s\n", r->in.share));
2321 werr = WERR_ACCESS_DENIED;
2322 goto error_exit;
2325 close_file(NULL, fsp, NORMAL_CLOSE);
2326 vfs_ChDir(conn, oldcwd);
2327 conn_free(conn);
2328 werr = WERR_OK;
2329 goto done;
2331 error_exit:
2333 if (fsp) {
2334 close_file(NULL, fsp, NORMAL_CLOSE);
2337 if (oldcwd) {
2338 vfs_ChDir(conn, oldcwd);
2341 if (conn) {
2342 conn_free(conn);
2345 done:
2346 TALLOC_FREE(smb_fname);
2348 return werr;
2351 /***********************************************************************************
2352 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2353 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2354 These disks would the disks listed by this function.
2355 Users could then create shares relative to these disks. Watch out for moving these disks around.
2356 "Nigel Williams" <nigel@veritas.com>.
2357 ***********************************************************************************/
2359 static const char *server_disks[] = {"C:"};
2361 static uint32 get_server_disk_count(void)
2363 return sizeof(server_disks)/sizeof(server_disks[0]);
2366 static uint32 init_server_disk_enum(uint32 *resume)
2368 uint32 server_disk_count = get_server_disk_count();
2370 /*resume can be an offset into the list for now*/
2372 if(*resume & 0x80000000)
2373 *resume = 0;
2375 if(*resume > server_disk_count)
2376 *resume = server_disk_count;
2378 return server_disk_count - *resume;
2381 static const char *next_server_disk_enum(uint32 *resume)
2383 const char *disk;
2385 if(init_server_disk_enum(resume) == 0)
2386 return NULL;
2388 disk = server_disks[*resume];
2390 (*resume)++;
2392 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2394 return disk;
2397 /********************************************************************
2398 _srvsvc_NetDiskEnum
2399 ********************************************************************/
2401 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2402 struct srvsvc_NetDiskEnum *r)
2404 uint32 i;
2405 const char *disk_name;
2406 TALLOC_CTX *ctx = p->mem_ctx;
2407 WERROR werr;
2408 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2410 werr = WERR_OK;
2412 *r->out.totalentries = init_server_disk_enum(&resume);
2414 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2415 MAX_SERVER_DISK_ENTRIES);
2416 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2418 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2420 r->out.info->count = 0;
2422 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2424 r->out.info->count++;
2426 /*copy disk name into a unicode string*/
2428 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2429 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2432 /* add a terminating null string. Is this there if there is more data to come? */
2434 r->out.info->count++;
2436 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2437 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2439 if (r->out.resume_handle) {
2440 *r->out.resume_handle = resume;
2443 return werr;
2446 /********************************************************************
2447 _srvsvc_NetNameValidate
2448 ********************************************************************/
2450 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2451 struct srvsvc_NetNameValidate *r)
2453 switch (r->in.name_type) {
2454 case 0x9:
2455 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2456 strlen_m(r->in.name)))
2458 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2459 r->in.name));
2460 return WERR_INVALID_NAME;
2462 break;
2464 default:
2465 return WERR_UNKNOWN_LEVEL;
2468 return WERR_OK;
2471 /*******************************************************************
2472 ********************************************************************/
2474 struct enum_file_close_state {
2475 struct srvsvc_NetFileClose *r;
2476 struct messaging_context *msg_ctx;
2479 static void enum_file_close_fn( const struct share_mode_entry *e,
2480 const char *sharepath, const char *fname,
2481 void *private_data )
2483 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2484 struct enum_file_close_state *state =
2485 (struct enum_file_close_state *)private_data;
2486 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2488 if (fid != state->r->in.fid) {
2489 return; /* Not this file. */
2492 if (!process_exists(e->pid) ) {
2493 return;
2496 /* Ok - send the close message. */
2497 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2498 sharepath,
2499 share_mode_str(talloc_tos(), 0, e) ));
2501 share_mode_entry_to_message(msg, e);
2503 state->r->out.result = ntstatus_to_werror(
2504 messaging_send_buf(state->msg_ctx,
2505 e->pid, MSG_SMB_CLOSE_FILE,
2506 (uint8 *)msg,
2507 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2510 /********************************************************************
2511 Close a file given a 32-bit file id.
2512 ********************************************************************/
2514 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2515 struct srvsvc_NetFileClose *r)
2517 struct enum_file_close_state state;
2518 bool is_disk_op;
2520 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2522 is_disk_op = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_DISK_OPERATOR);
2524 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2525 return WERR_ACCESS_DENIED;
2528 /* enum_file_close_fn sends the close message to
2529 * the relevent smbd process. */
2531 r->out.result = WERR_BADFILE;
2532 state.r = r;
2533 state.msg_ctx = p->msg_ctx;
2534 share_mode_forall(enum_file_close_fn, &state);
2535 return r->out.result;
2538 /********************************************************************
2539 ********************************************************************/
2541 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2542 struct srvsvc_NetCharDevEnum *r)
2544 p->rng_fault_state = True;
2545 return WERR_NOT_SUPPORTED;
2548 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2549 struct srvsvc_NetCharDevGetInfo *r)
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2555 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2556 struct srvsvc_NetCharDevControl *r)
2558 p->rng_fault_state = True;
2559 return WERR_NOT_SUPPORTED;
2562 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2563 struct srvsvc_NetCharDevQEnum *r)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;
2569 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2570 struct srvsvc_NetCharDevQGetInfo *r)
2572 p->rng_fault_state = True;
2573 return WERR_NOT_SUPPORTED;
2576 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2577 struct srvsvc_NetCharDevQSetInfo *r)
2579 p->rng_fault_state = True;
2580 return WERR_NOT_SUPPORTED;
2583 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2584 struct srvsvc_NetCharDevQPurge *r)
2586 p->rng_fault_state = True;
2587 return WERR_NOT_SUPPORTED;
2590 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2591 struct srvsvc_NetCharDevQPurgeSelf *r)
2593 p->rng_fault_state = True;
2594 return WERR_NOT_SUPPORTED;
2597 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2598 struct srvsvc_NetFileGetInfo *r)
2600 p->rng_fault_state = True;
2601 return WERR_NOT_SUPPORTED;
2604 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2605 struct srvsvc_NetShareCheck *r)
2607 p->rng_fault_state = True;
2608 return WERR_NOT_SUPPORTED;
2611 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2612 struct srvsvc_NetServerStatisticsGet *r)
2614 p->rng_fault_state = True;
2615 return WERR_NOT_SUPPORTED;
2618 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2619 struct srvsvc_NetTransportAdd *r)
2621 p->rng_fault_state = True;
2622 return WERR_NOT_SUPPORTED;
2625 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2626 struct srvsvc_NetTransportEnum *r)
2628 p->rng_fault_state = True;
2629 return WERR_NOT_SUPPORTED;
2632 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2633 struct srvsvc_NetTransportDel *r)
2635 p->rng_fault_state = True;
2636 return WERR_NOT_SUPPORTED;
2639 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2640 struct srvsvc_NetSetServiceBits *r)
2642 p->rng_fault_state = True;
2643 return WERR_NOT_SUPPORTED;
2646 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2647 struct srvsvc_NetPathType *r)
2649 p->rng_fault_state = True;
2650 return WERR_NOT_SUPPORTED;
2653 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2654 struct srvsvc_NetPathCanonicalize *r)
2656 p->rng_fault_state = True;
2657 return WERR_NOT_SUPPORTED;
2660 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2661 struct srvsvc_NetPathCompare *r)
2663 p->rng_fault_state = True;
2664 return WERR_NOT_SUPPORTED;
2667 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2668 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2670 p->rng_fault_state = True;
2671 return WERR_NOT_SUPPORTED;
2674 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2675 struct srvsvc_NetPRNameCompare *r)
2677 p->rng_fault_state = True;
2678 return WERR_NOT_SUPPORTED;
2681 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2682 struct srvsvc_NetShareDelStart *r)
2684 p->rng_fault_state = True;
2685 return WERR_NOT_SUPPORTED;
2688 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2689 struct srvsvc_NetShareDelCommit *r)
2691 p->rng_fault_state = True;
2692 return WERR_NOT_SUPPORTED;
2695 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2696 struct srvsvc_NetServerTransportAddEx *r)
2698 p->rng_fault_state = True;
2699 return WERR_NOT_SUPPORTED;
2702 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2703 struct srvsvc_NetServerSetServiceBitsEx *r)
2705 p->rng_fault_state = True;
2706 return WERR_NOT_SUPPORTED;
2709 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2710 struct srvsvc_NETRDFSGETVERSION *r)
2712 p->rng_fault_state = True;
2713 return WERR_NOT_SUPPORTED;
2716 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2717 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2719 p->rng_fault_state = True;
2720 return WERR_NOT_SUPPORTED;
2723 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2724 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2726 p->rng_fault_state = True;
2727 return WERR_NOT_SUPPORTED;
2730 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2731 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2733 p->rng_fault_state = True;
2734 return WERR_NOT_SUPPORTED;
2737 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2738 struct srvsvc_NETRDFSSETSERVERINFO *r)
2740 p->rng_fault_state = True;
2741 return WERR_NOT_SUPPORTED;
2744 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2745 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2747 p->rng_fault_state = True;
2748 return WERR_NOT_SUPPORTED;
2751 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2752 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2754 p->rng_fault_state = True;
2755 return WERR_NOT_SUPPORTED;
2758 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2759 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2761 p->rng_fault_state = True;
2762 return WERR_NOT_SUPPORTED;
2765 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2766 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2768 p->rng_fault_state = True;
2769 return WERR_NOT_SUPPORTED;
2772 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2773 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2775 p->rng_fault_state = True;
2776 return WERR_NOT_SUPPORTED;
2779 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2780 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2782 p->rng_fault_state = True;
2783 return WERR_NOT_SUPPORTED;