s3:smbd/msdfs: let create_conn_struct() also fake the 'smbd_server_connection'
[Samba/gebeck_regimport.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob38f272c55a4a434a91a351240b6bcaf79bb2d77d
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 "system/passwd.h"
28 #include "ntdomain.h"
29 #include "../librpc/gen_ndr/srv_srvsvc.h"
30 #include "../libcli/security/security.h"
31 #include "../librpc/gen_ndr/ndr_security.h"
32 #include "../librpc/gen_ndr/open_files.h"
33 #include "dbwrap/dbwrap.h"
34 #include "session.h"
35 #include "../lib/util/util_pw.h"
36 #include "smbd/smbd.h"
37 #include "smbd/globals.h"
38 #include "auth.h"
39 #include "messages.h"
41 extern const struct generic_mapping file_generic_mapping;
43 #undef DBGC_CLASS
44 #define DBGC_CLASS DBGC_RPC_SRV
46 #define MAX_SERVER_DISK_ENTRIES 15
48 /* Use for enumerating connections, pipes, & files */
50 struct file_enum_count {
51 TALLOC_CTX *ctx;
52 const char *username;
53 struct srvsvc_NetFileCtr3 *ctr3;
56 struct sess_file_count {
57 struct server_id pid;
58 uid_t uid;
59 int count;
62 /* Used to store pipe open records for NetFileEnum() */
64 struct pipe_open_rec {
65 struct server_id pid;
66 uid_t uid;
67 int pnum;
68 fstring name;
71 /****************************************************************************
72 Count the entries belonging to a service in the connection db.
73 ****************************************************************************/
75 static int pipe_enum_fn( struct db_record *rec, void *p)
77 struct pipe_open_rec prec;
78 struct file_enum_count *fenum = (struct file_enum_count *)p;
79 struct srvsvc_NetFileInfo3 *f;
80 int i = fenum->ctr3->count;
81 char *fullpath = NULL;
82 const char *username;
83 TDB_DATA value;
85 value = dbwrap_record_get_value(rec);
87 if (value.dsize != sizeof(struct pipe_open_rec))
88 return 0;
90 memcpy(&prec, value.dptr, sizeof(struct pipe_open_rec));
92 if ( !process_exists(prec.pid) ) {
93 return 0;
96 username = uidtoname(prec.uid);
98 if ((fenum->username != NULL)
99 && !strequal(username, fenum->username)) {
100 return 0;
103 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
104 if (!fullpath) {
105 return 1;
108 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
109 struct srvsvc_NetFileInfo3, i+1);
110 if ( !f ) {
111 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
112 return 1;
114 fenum->ctr3->array = f;
116 fenum->ctr3->array[i].fid =
117 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
118 fenum->ctr3->array[i].permissions =
119 (FILE_READ_DATA|FILE_WRITE_DATA);
120 fenum->ctr3->array[i].num_locks = 0;
121 fenum->ctr3->array[i].path = fullpath;
122 fenum->ctr3->array[i].user = username;
124 fenum->ctr3->count++;
126 return 0;
129 /*******************************************************************
130 ********************************************************************/
132 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
133 const char *username,
134 struct srvsvc_NetFileCtr3 **ctr3,
135 uint32_t resume )
137 struct file_enum_count fenum;
139 fenum.ctx = ctx;
140 fenum.username = username;
141 fenum.ctr3 = *ctr3;
143 if (connections_traverse(pipe_enum_fn, &fenum) < 0) {
144 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
145 "failed\n"));
146 return WERR_NOMEM;
149 *ctr3 = fenum.ctr3;
151 return WERR_OK;
154 /*******************************************************************
155 ********************************************************************/
157 static void enum_file_fn( const struct share_mode_entry *e,
158 const char *sharepath, const char *fname,
159 void *private_data )
161 struct file_enum_count *fenum =
162 (struct file_enum_count *)private_data;
164 struct srvsvc_NetFileInfo3 *f;
165 int i = fenum->ctr3->count;
166 files_struct fsp;
167 struct byte_range_lock *brl;
168 int num_locks = 0;
169 char *fullpath = NULL;
170 uint32 permissions;
171 const char *username;
173 /* If the pid was not found delete the entry from connections.tdb */
175 if ( !process_exists(e->pid) ) {
176 return;
179 username = uidtoname(e->uid);
181 if ((fenum->username != NULL)
182 && !strequal(username, fenum->username)) {
183 return;
186 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
187 struct srvsvc_NetFileInfo3, i+1);
188 if ( !f ) {
189 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
190 return;
192 fenum->ctr3->array = f;
194 /* need to count the number of locks on a file */
196 ZERO_STRUCT( fsp );
197 fsp.file_id = e->id;
199 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
200 num_locks = brl->num_locks;
201 TALLOC_FREE(brl);
204 if ( strcmp( fname, "." ) == 0 ) {
205 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
206 } else {
207 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
208 sharepath, fname );
210 if (!fullpath) {
211 return;
213 string_replace( fullpath, '/', '\\' );
215 /* mask out create (what ever that is) */
216 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
218 /* now fill in the srvsvc_NetFileInfo3 struct */
220 fenum->ctr3->array[i].fid =
221 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
222 fenum->ctr3->array[i].permissions = permissions;
223 fenum->ctr3->array[i].num_locks = num_locks;
224 fenum->ctr3->array[i].path = fullpath;
225 fenum->ctr3->array[i].user = username;
227 fenum->ctr3->count++;
230 /*******************************************************************
231 ********************************************************************/
233 static WERROR net_enum_files(TALLOC_CTX *ctx,
234 const char *username,
235 struct srvsvc_NetFileCtr3 **ctr3,
236 uint32_t resume)
238 struct file_enum_count f_enum_cnt;
240 f_enum_cnt.ctx = ctx;
241 f_enum_cnt.username = username;
242 f_enum_cnt.ctr3 = *ctr3;
244 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
246 *ctr3 = f_enum_cnt.ctr3;
248 return WERR_OK;
251 /*******************************************************************
252 Utility function to get the 'type' of a share from an snum.
253 ********************************************************************/
254 static enum srvsvc_ShareType get_share_type(int snum)
256 /* work out the share type */
257 enum srvsvc_ShareType type = STYPE_DISKTREE;
259 if (lp_print_ok(snum)) {
260 type = lp_administrative_share(snum)
261 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
263 if (strequal(lp_fstype(snum), "IPC")) {
264 type = lp_administrative_share(snum)
265 ? STYPE_IPC_HIDDEN : STYPE_IPC;
267 return type;
270 /*******************************************************************
271 Fill in a share info level 0 structure.
272 ********************************************************************/
274 static void init_srv_share_info_0(struct pipes_struct *p,
275 struct srvsvc_NetShareInfo0 *r, int snum)
277 r->name = lp_servicename(snum);
280 /*******************************************************************
281 Fill in a share info level 1 structure.
282 ********************************************************************/
284 static void init_srv_share_info_1(struct pipes_struct *p,
285 struct srvsvc_NetShareInfo1 *r,
286 int snum)
288 char *net_name = lp_servicename(snum);
289 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
291 if (remark) {
292 remark = talloc_sub_advanced(
293 p->mem_ctx, lp_servicename(snum),
294 get_current_username(), lp_pathname(snum),
295 p->session_info->unix_token->uid, get_current_username(),
296 "", remark);
299 r->name = net_name;
300 r->type = get_share_type(snum);
301 r->comment = remark ? remark : "";
304 /*******************************************************************
305 Fill in a share info level 2 structure.
306 ********************************************************************/
308 static void init_srv_share_info_2(struct pipes_struct *p,
309 struct srvsvc_NetShareInfo2 *r,
310 int snum)
312 char *remark = NULL;
313 char *path = NULL;
314 int max_connections = lp_max_connections(snum);
315 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
316 char *net_name = lp_servicename(snum);
318 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
319 if (remark) {
320 remark = talloc_sub_advanced(
321 p->mem_ctx, lp_servicename(snum),
322 get_current_username(), lp_pathname(snum),
323 p->session_info->unix_token->uid, get_current_username(),
324 "", remark);
326 path = talloc_asprintf(p->mem_ctx,
327 "C:%s", lp_pathname(snum));
329 if (path) {
331 * Change / to \\ so that win2k will see it as a valid path.
332 * This was added to enable use of browsing in win2k add
333 * share dialog.
336 string_replace(path, '/', '\\');
339 r->name = net_name;
340 r->type = get_share_type(snum);
341 r->comment = remark ? remark : "";
342 r->permissions = 0;
343 r->max_users = max_uses;
344 r->current_users = count_current_connections(net_name, false);
345 r->path = path ? path : "";
346 r->password = "";
349 /*******************************************************************
350 Map any generic bits to file specific bits.
351 ********************************************************************/
353 static void map_generic_share_sd_bits(struct security_descriptor *psd)
355 int i;
356 struct security_acl *ps_dacl = NULL;
358 if (!psd)
359 return;
361 ps_dacl = psd->dacl;
362 if (!ps_dacl)
363 return;
365 for (i = 0; i < ps_dacl->num_aces; i++) {
366 struct security_ace *psa = &ps_dacl->aces[i];
367 uint32 orig_mask = psa->access_mask;
369 se_map_generic(&psa->access_mask, &file_generic_mapping);
370 psa->access_mask |= orig_mask;
374 /*******************************************************************
375 Fill in a share info level 501 structure.
376 ********************************************************************/
378 static void init_srv_share_info_501(struct pipes_struct *p,
379 struct srvsvc_NetShareInfo501 *r, int snum)
381 const char *net_name = lp_servicename(snum);
382 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
384 if (remark) {
385 remark = talloc_sub_advanced(
386 p->mem_ctx, lp_servicename(snum),
387 get_current_username(), lp_pathname(snum),
388 p->session_info->unix_token->uid, get_current_username(),
389 "", remark);
392 r->name = net_name;
393 r->type = get_share_type(snum);
394 r->comment = remark ? remark : "";
395 r->csc_policy = (lp_csc_policy(snum) << 4);
398 /*******************************************************************
399 Fill in a share info level 502 structure.
400 ********************************************************************/
402 static void init_srv_share_info_502(struct pipes_struct *p,
403 struct srvsvc_NetShareInfo502 *r, int snum)
405 const char *net_name = lp_servicename(snum);
406 char *path = NULL;
407 struct security_descriptor *sd = NULL;
408 struct sec_desc_buf *sd_buf = NULL;
409 size_t sd_size = 0;
410 TALLOC_CTX *ctx = p->mem_ctx;
411 char *remark = talloc_strdup(ctx, lp_comment(snum));
413 if (remark) {
414 remark = talloc_sub_advanced(
415 p->mem_ctx, lp_servicename(snum),
416 get_current_username(), lp_pathname(snum),
417 p->session_info->unix_token->uid, get_current_username(),
418 "", remark);
420 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
421 if (path) {
423 * Change / to \\ so that win2k will see it as a valid path. This was added to
424 * enable use of browsing in win2k add share dialog.
426 string_replace(path, '/', '\\');
429 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
431 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
433 r->name = net_name;
434 r->type = get_share_type(snum);
435 r->comment = remark ? remark : "";
436 r->permissions = 0;
437 r->max_users = (uint32_t)-1;
438 r->current_users = 1; /* ??? */
439 r->path = path ? path : "";
440 r->password = "";
441 r->sd_buf = *sd_buf;
444 /***************************************************************************
445 Fill in a share info level 1004 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1004(struct pipes_struct *p,
449 struct srvsvc_NetShareInfo1004 *r,
450 int snum)
452 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
454 if (remark) {
455 remark = talloc_sub_advanced(
456 p->mem_ctx, lp_servicename(snum),
457 get_current_username(), lp_pathname(snum),
458 p->session_info->unix_token->uid, get_current_username(),
459 "", remark);
462 r->comment = remark ? remark : "";
465 /***************************************************************************
466 Fill in a share info level 1005 structure.
467 ***************************************************************************/
469 static void init_srv_share_info_1005(struct pipes_struct *p,
470 struct srvsvc_NetShareInfo1005 *r,
471 int snum)
473 uint32_t dfs_flags = 0;
475 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
476 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
479 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
481 r->dfs_flags = dfs_flags;
484 /***************************************************************************
485 Fill in a share info level 1006 structure.
486 ***************************************************************************/
488 static void init_srv_share_info_1006(struct pipes_struct *p,
489 struct srvsvc_NetShareInfo1006 *r,
490 int snum)
492 r->max_users = (uint32_t)-1;
495 /***************************************************************************
496 Fill in a share info level 1007 structure.
497 ***************************************************************************/
499 static void init_srv_share_info_1007(struct pipes_struct *p,
500 struct srvsvc_NetShareInfo1007 *r,
501 int snum)
503 r->flags = 0;
504 r->alternate_directory_name = "";
507 /*******************************************************************
508 Fill in a share info level 1501 structure.
509 ********************************************************************/
511 static void init_srv_share_info_1501(struct pipes_struct *p,
512 struct sec_desc_buf **r,
513 int snum)
515 struct security_descriptor *sd;
516 struct sec_desc_buf *sd_buf = NULL;
517 size_t sd_size;
518 TALLOC_CTX *ctx = p->mem_ctx;
520 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
521 if (sd) {
522 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
525 *r = sd_buf;
528 /*******************************************************************
529 True if it ends in '$'.
530 ********************************************************************/
532 static bool is_hidden_share(int snum)
534 const char *net_name = lp_servicename(snum);
536 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
539 /*******************************************************************
540 Verify user is allowed to view share, access based enumeration
541 ********************************************************************/
542 static bool is_enumeration_allowed(struct pipes_struct *p,
543 int snum)
545 if (!lp_access_based_share_enum(snum))
546 return true;
548 return share_access_check(p->session_info->security_token,
549 lp_servicename(snum), FILE_READ_DATA, NULL);
552 /*******************************************************************
553 Fill in a share info structure.
554 ********************************************************************/
556 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
557 struct srvsvc_NetShareInfoCtr *info_ctr,
558 uint32_t *resume_handle_p,
559 uint32_t *total_entries,
560 bool all_shares)
562 int num_entries = 0;
563 int alloc_entries = 0;
564 int num_services = 0;
565 int snum;
566 TALLOC_CTX *ctx = p->mem_ctx;
567 int i = 0;
568 int valid_share_count = 0;
569 bool *allowed = 0;
570 union srvsvc_NetShareCtr ctr;
571 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
573 DEBUG(5,("init_srv_share_info_ctr\n"));
575 /* Ensure all the usershares are loaded. */
576 become_root();
577 load_usershare_shares(NULL, connections_snum_used);
578 load_registry_shares();
579 num_services = lp_numservices();
580 unbecome_root();
582 allowed = talloc_zero_array(ctx, bool, num_services);
583 W_ERROR_HAVE_NO_MEMORY(allowed);
585 /* Count the number of entries. */
586 for (snum = 0; snum < num_services; snum++) {
587 if (lp_browseable(snum) && lp_snum_ok(snum) &&
588 is_enumeration_allowed(p, snum) &&
589 (all_shares || !is_hidden_share(snum)) ) {
590 DEBUG(10, ("counting service %s\n",
591 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
592 allowed[snum] = true;
593 num_entries++;
594 } else {
595 DEBUG(10, ("NOT counting service %s\n",
596 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
600 if (!num_entries || (resume_handle >= num_entries)) {
601 return WERR_OK;
604 /* Calculate alloc entries. */
605 alloc_entries = num_entries - resume_handle;
606 switch (info_ctr->level) {
607 case 0:
608 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
609 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
611 ctr.ctr0->count = alloc_entries;
612 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
613 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
615 for (snum = 0; snum < num_services; snum++) {
616 if (allowed[snum] &&
617 (resume_handle <= (i + valid_share_count++)) ) {
618 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
622 break;
624 case 1:
625 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
626 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
628 ctr.ctr1->count = alloc_entries;
629 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
630 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
632 for (snum = 0; snum < num_services; snum++) {
633 if (allowed[snum] &&
634 (resume_handle <= (i + valid_share_count++)) ) {
635 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
639 break;
641 case 2:
642 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
643 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
645 ctr.ctr2->count = alloc_entries;
646 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
647 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
649 for (snum = 0; snum < num_services; snum++) {
650 if (allowed[snum] &&
651 (resume_handle <= (i + valid_share_count++)) ) {
652 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
656 break;
658 case 501:
659 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
660 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
662 ctr.ctr501->count = alloc_entries;
663 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
664 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
666 for (snum = 0; snum < num_services; snum++) {
667 if (allowed[snum] &&
668 (resume_handle <= (i + valid_share_count++)) ) {
669 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
673 break;
675 case 502:
676 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
677 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
679 ctr.ctr502->count = alloc_entries;
680 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
681 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
683 for (snum = 0; snum < num_services; snum++) {
684 if (allowed[snum] &&
685 (resume_handle <= (i + valid_share_count++)) ) {
686 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
690 break;
692 case 1004:
693 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
694 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
696 ctr.ctr1004->count = alloc_entries;
697 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
698 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
700 for (snum = 0; snum < num_services; snum++) {
701 if (allowed[snum] &&
702 (resume_handle <= (i + valid_share_count++)) ) {
703 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
707 break;
709 case 1005:
710 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
711 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
713 ctr.ctr1005->count = alloc_entries;
714 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
715 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
717 for (snum = 0; snum < num_services; snum++) {
718 if (allowed[snum] &&
719 (resume_handle <= (i + valid_share_count++)) ) {
720 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
724 break;
726 case 1006:
727 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
728 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
730 ctr.ctr1006->count = alloc_entries;
731 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
732 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
734 for (snum = 0; snum < num_services; snum++) {
735 if (allowed[snum] &&
736 (resume_handle <= (i + valid_share_count++)) ) {
737 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
741 break;
743 case 1007:
744 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
745 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
747 ctr.ctr1007->count = alloc_entries;
748 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
749 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
751 for (snum = 0; snum < num_services; snum++) {
752 if (allowed[snum] &&
753 (resume_handle <= (i + valid_share_count++)) ) {
754 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
758 break;
760 case 1501:
761 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
762 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
764 ctr.ctr1501->count = alloc_entries;
765 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
766 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
768 for (snum = 0; snum < num_services; snum++) {
769 if (allowed[snum] &&
770 (resume_handle <= (i + valid_share_count++)) ) {
771 struct sec_desc_buf *sd_buf = NULL;
772 init_srv_share_info_1501(p, &sd_buf, snum);
773 ctr.ctr1501->array[i++] = *sd_buf;
777 break;
779 default:
780 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
781 info_ctr->level));
782 return WERR_UNKNOWN_LEVEL;
785 *total_entries = alloc_entries;
786 if (resume_handle_p) {
787 if (all_shares) {
788 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
789 } else {
790 *resume_handle_p = num_entries;
794 info_ctr->ctr = ctr;
796 return WERR_OK;
799 /*******************************************************************
800 fill in a sess info level 0 structure.
801 ********************************************************************/
803 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
804 struct srvsvc_NetSessCtr0 *ctr0,
805 uint32_t *resume_handle_p,
806 uint32_t *total_entries)
808 struct sessionid *session_list;
809 uint32_t num_entries = 0;
810 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
811 *total_entries = list_sessions(p->mem_ctx, &session_list);
813 DEBUG(5,("init_srv_sess_info_0\n"));
815 if (ctr0 == NULL) {
816 if (resume_handle_p) {
817 *resume_handle_p = 0;
819 return WERR_OK;
822 for (; resume_handle < *total_entries; resume_handle++) {
824 ctr0->array = talloc_realloc(p->mem_ctx,
825 ctr0->array,
826 struct srvsvc_NetSessInfo0,
827 num_entries+1);
828 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
830 ctr0->array[num_entries].client =
831 session_list[resume_handle].remote_machine;
833 num_entries++;
836 ctr0->count = num_entries;
838 if (resume_handle_p) {
839 if (*resume_handle_p >= *total_entries) {
840 *resume_handle_p = 0;
841 } else {
842 *resume_handle_p = resume_handle;
846 return WERR_OK;
849 /*******************************************************************
850 ********************************************************************/
852 static void sess_file_fn( const struct share_mode_entry *e,
853 const char *sharepath, const char *fname,
854 void *data )
856 struct sess_file_count *sess = (struct sess_file_count *)data;
858 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
859 sess->count++;
862 return;
865 /*******************************************************************
866 ********************************************************************/
868 static int net_count_files( uid_t uid, struct server_id pid )
870 struct sess_file_count s_file_cnt;
872 s_file_cnt.count = 0;
873 s_file_cnt.uid = uid;
874 s_file_cnt.pid = pid;
876 share_mode_forall( sess_file_fn, &s_file_cnt );
878 return s_file_cnt.count;
881 /*******************************************************************
882 fill in a sess info level 1 structure.
883 ********************************************************************/
885 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
886 struct srvsvc_NetSessCtr1 *ctr1,
887 uint32_t *resume_handle_p,
888 uint32_t *total_entries)
890 struct sessionid *session_list;
891 uint32_t num_entries = 0;
892 time_t now = time(NULL);
893 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
895 ZERO_STRUCTP(ctr1);
897 if (ctr1 == NULL) {
898 if (resume_handle_p) {
899 *resume_handle_p = 0;
901 return WERR_OK;
904 *total_entries = list_sessions(p->mem_ctx, &session_list);
906 for (; resume_handle < *total_entries; resume_handle++) {
907 uint32 num_files;
908 uint32 connect_time;
909 struct passwd *pw = getpwnam(session_list[resume_handle].username);
910 bool guest;
912 if ( !pw ) {
913 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
914 session_list[resume_handle].username));
915 continue;
918 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
919 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
920 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
922 ctr1->array = talloc_realloc(p->mem_ctx,
923 ctr1->array,
924 struct srvsvc_NetSessInfo1,
925 num_entries+1);
926 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
928 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
929 ctr1->array[num_entries].user = session_list[resume_handle].username;
930 ctr1->array[num_entries].num_open = num_files;
931 ctr1->array[num_entries].time = connect_time;
932 ctr1->array[num_entries].idle_time = 0;
933 ctr1->array[num_entries].user_flags = guest;
935 num_entries++;
938 ctr1->count = num_entries;
940 if (resume_handle_p) {
941 if (*resume_handle_p >= *total_entries) {
942 *resume_handle_p = 0;
943 } else {
944 *resume_handle_p = resume_handle;
948 return WERR_OK;
951 /*******************************************************************
952 fill in a conn info level 0 structure.
953 ********************************************************************/
955 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
956 uint32_t *resume_handle_p,
957 uint32_t *total_entries)
959 uint32_t num_entries = 0;
960 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
962 DEBUG(5,("init_srv_conn_info_0\n"));
964 if (ctr0 == NULL) {
965 if (resume_handle_p) {
966 *resume_handle_p = 0;
968 return WERR_OK;
971 *total_entries = 1;
973 ZERO_STRUCTP(ctr0);
975 for (; resume_handle < *total_entries; resume_handle++) {
977 ctr0->array = talloc_realloc(talloc_tos(),
978 ctr0->array,
979 struct srvsvc_NetConnInfo0,
980 num_entries+1);
981 if (!ctr0->array) {
982 return WERR_NOMEM;
985 ctr0->array[num_entries].conn_id = *total_entries;
987 /* move on to creating next connection */
988 num_entries++;
991 ctr0->count = num_entries;
992 *total_entries = num_entries;
994 if (resume_handle_p) {
995 if (*resume_handle_p >= *total_entries) {
996 *resume_handle_p = 0;
997 } else {
998 *resume_handle_p = resume_handle;
1002 return WERR_OK;
1005 /*******************************************************************
1006 fill in a conn info level 1 structure.
1007 ********************************************************************/
1009 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
1010 uint32_t *resume_handle_p,
1011 uint32_t *total_entries)
1013 uint32_t num_entries = 0;
1014 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1016 DEBUG(5,("init_srv_conn_info_1\n"));
1018 if (ctr1 == NULL) {
1019 if (resume_handle_p) {
1020 *resume_handle_p = 0;
1022 return WERR_OK;
1025 *total_entries = 1;
1027 ZERO_STRUCTP(ctr1);
1029 for (; resume_handle < *total_entries; resume_handle++) {
1031 ctr1->array = talloc_realloc(talloc_tos(),
1032 ctr1->array,
1033 struct srvsvc_NetConnInfo1,
1034 num_entries+1);
1035 if (!ctr1->array) {
1036 return WERR_NOMEM;
1039 ctr1->array[num_entries].conn_id = *total_entries;
1040 ctr1->array[num_entries].conn_type = 0x3;
1041 ctr1->array[num_entries].num_open = 1;
1042 ctr1->array[num_entries].num_users = 1;
1043 ctr1->array[num_entries].conn_time = 3;
1044 ctr1->array[num_entries].user = "dummy_user";
1045 ctr1->array[num_entries].share = "IPC$";
1047 /* move on to creating next connection */
1048 num_entries++;
1051 ctr1->count = num_entries;
1052 *total_entries = num_entries;
1054 if (resume_handle_p) {
1055 if (*resume_handle_p >= *total_entries) {
1056 *resume_handle_p = 0;
1057 } else {
1058 *resume_handle_p = resume_handle;
1062 return WERR_OK;
1065 /*******************************************************************
1066 _srvsvc_NetFileEnum
1067 *******************************************************************/
1069 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1070 struct srvsvc_NetFileEnum *r)
1072 TALLOC_CTX *ctx = NULL;
1073 struct srvsvc_NetFileCtr3 *ctr3;
1074 uint32_t resume_hnd = 0;
1075 WERROR werr;
1077 switch (r->in.info_ctr->level) {
1078 case 3:
1079 break;
1080 default:
1081 return WERR_UNKNOWN_LEVEL;
1084 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1085 p->session_info->security_token)) {
1086 DEBUG(1, ("Enumerating files only allowed for "
1087 "administrators\n"));
1088 return WERR_ACCESS_DENIED;
1091 ctx = talloc_tos();
1092 ctr3 = r->in.info_ctr->ctr.ctr3;
1093 if (!ctr3) {
1094 werr = WERR_INVALID_PARAM;
1095 goto done;
1098 /* TODO -- Windows enumerates
1099 (b) active pipes
1100 (c) open directories and files */
1102 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1103 if (!W_ERROR_IS_OK(werr)) {
1104 goto done;
1107 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1108 if (!W_ERROR_IS_OK(werr)) {
1109 goto done;
1112 *r->out.totalentries = ctr3->count;
1113 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1114 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1116 werr = WERR_OK;
1118 done:
1119 return werr;
1122 /*******************************************************************
1123 _srvsvc_NetSrvGetInfo
1124 ********************************************************************/
1126 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1127 struct srvsvc_NetSrvGetInfo *r)
1129 WERROR status = WERR_OK;
1131 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1133 if (!pipe_access_check(p)) {
1134 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1135 return WERR_ACCESS_DENIED;
1138 switch (r->in.level) {
1140 /* Technically level 102 should only be available to
1141 Administrators but there isn't anything super-secret
1142 here, as most of it is made up. */
1144 case 102: {
1145 struct srvsvc_NetSrvInfo102 *info102;
1147 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1148 if (!info102) {
1149 return WERR_NOMEM;
1152 info102->platform_id = PLATFORM_ID_NT;
1153 info102->server_name = lp_netbios_name();
1154 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1155 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1156 info102->server_type = lp_default_server_announce();
1157 info102->comment = string_truncate(lp_serverstring(),
1158 MAX_SERVER_STRING_LENGTH);
1159 info102->users = 0xffffffff;
1160 info102->disc = 0xf;
1161 info102->hidden = 0;
1162 info102->announce = 240;
1163 info102->anndelta = 3000;
1164 info102->licenses = 100000;
1165 info102->userpath = "C:\\";
1167 r->out.info->info102 = info102;
1168 break;
1170 case 101: {
1171 struct srvsvc_NetSrvInfo101 *info101;
1173 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1174 if (!info101) {
1175 return WERR_NOMEM;
1178 info101->platform_id = PLATFORM_ID_NT;
1179 info101->server_name = lp_netbios_name();
1180 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1181 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1182 info101->server_type = lp_default_server_announce();
1183 info101->comment = string_truncate(lp_serverstring(),
1184 MAX_SERVER_STRING_LENGTH);
1186 r->out.info->info101 = info101;
1187 break;
1189 case 100: {
1190 struct srvsvc_NetSrvInfo100 *info100;
1192 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1193 if (!info100) {
1194 return WERR_NOMEM;
1197 info100->platform_id = PLATFORM_ID_NT;
1198 info100->server_name = lp_netbios_name();
1200 r->out.info->info100 = info100;
1202 break;
1204 default:
1205 status = WERR_UNKNOWN_LEVEL;
1206 break;
1209 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1211 return status;
1214 /*******************************************************************
1215 _srvsvc_NetSrvSetInfo
1216 ********************************************************************/
1218 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1219 struct srvsvc_NetSrvSetInfo *r)
1221 WERROR status = WERR_OK;
1223 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1225 /* Set up the net server set info structure. */
1227 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1229 return status;
1232 /*******************************************************************
1233 _srvsvc_NetConnEnum
1234 ********************************************************************/
1236 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1237 struct srvsvc_NetConnEnum *r)
1239 WERROR werr;
1241 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1243 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1244 p->session_info->security_token)) {
1245 DEBUG(1, ("Enumerating connections only allowed for "
1246 "administrators\n"));
1247 return WERR_ACCESS_DENIED;
1250 switch (r->in.info_ctr->level) {
1251 case 0:
1252 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1253 r->in.resume_handle,
1254 r->out.totalentries);
1255 break;
1256 case 1:
1257 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1258 r->in.resume_handle,
1259 r->out.totalentries);
1260 break;
1261 default:
1262 return WERR_UNKNOWN_LEVEL;
1265 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1267 return werr;
1270 /*******************************************************************
1271 _srvsvc_NetSessEnum
1272 ********************************************************************/
1274 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1275 struct srvsvc_NetSessEnum *r)
1277 WERROR werr;
1279 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1281 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1282 p->session_info->security_token)) {
1283 DEBUG(1, ("Enumerating sessions only allowed for "
1284 "administrators\n"));
1285 return WERR_ACCESS_DENIED;
1288 switch (r->in.info_ctr->level) {
1289 case 0:
1290 werr = init_srv_sess_info_0(p,
1291 r->in.info_ctr->ctr.ctr0,
1292 r->in.resume_handle,
1293 r->out.totalentries);
1294 break;
1295 case 1:
1296 werr = init_srv_sess_info_1(p,
1297 r->in.info_ctr->ctr.ctr1,
1298 r->in.resume_handle,
1299 r->out.totalentries);
1300 break;
1301 default:
1302 return WERR_UNKNOWN_LEVEL;
1305 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1307 return werr;
1310 /*******************************************************************
1311 _srvsvc_NetSessDel
1312 ********************************************************************/
1314 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1315 struct srvsvc_NetSessDel *r)
1317 struct sessionid *session_list;
1318 int num_sessions, snum;
1319 const char *username;
1320 const char *machine;
1321 bool not_root = False;
1322 WERROR werr;
1324 username = r->in.user;
1325 machine = r->in.client;
1327 /* strip leading backslashes if any */
1328 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1329 machine += 2;
1332 num_sessions = list_sessions(p->mem_ctx, &session_list);
1334 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1336 werr = WERR_ACCESS_DENIED;
1338 /* fail out now if you are not root or not a domain admin */
1340 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1341 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1342 DOMAIN_RID_ADMINS))) {
1344 goto done;
1347 for (snum = 0; snum < num_sessions; snum++) {
1349 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1350 strequal(session_list[snum].remote_machine, machine)) {
1352 NTSTATUS ntstat;
1354 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1355 not_root = True;
1356 become_root();
1359 ntstat = messaging_send(p->msg_ctx,
1360 session_list[snum].pid,
1361 MSG_SHUTDOWN, &data_blob_null);
1363 if (NT_STATUS_IS_OK(ntstat))
1364 werr = WERR_OK;
1366 if (not_root)
1367 unbecome_root();
1371 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1373 done:
1375 return werr;
1378 /*******************************************************************
1379 _srvsvc_NetShareEnumAll
1380 ********************************************************************/
1382 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1383 struct srvsvc_NetShareEnumAll *r)
1385 WERROR werr;
1387 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1389 if (!pipe_access_check(p)) {
1390 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1391 return WERR_ACCESS_DENIED;
1394 /* Create the list of shares for the response. */
1395 werr = init_srv_share_info_ctr(p,
1396 r->in.info_ctr,
1397 r->in.resume_handle,
1398 r->out.totalentries,
1399 true);
1401 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1403 return werr;
1406 /*******************************************************************
1407 _srvsvc_NetShareEnum
1408 ********************************************************************/
1410 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1411 struct srvsvc_NetShareEnum *r)
1413 WERROR werr;
1415 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1417 if (!pipe_access_check(p)) {
1418 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1419 return WERR_ACCESS_DENIED;
1422 /* Create the list of shares for the response. */
1423 werr = init_srv_share_info_ctr(p,
1424 r->in.info_ctr,
1425 r->in.resume_handle,
1426 r->out.totalentries,
1427 false);
1429 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1431 return werr;
1434 /*******************************************************************
1435 _srvsvc_NetShareGetInfo
1436 ********************************************************************/
1438 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1439 struct srvsvc_NetShareGetInfo *r)
1441 WERROR status = WERR_OK;
1442 char *share_name = NULL;
1443 int snum;
1444 union srvsvc_NetShareInfo *info = r->out.info;
1446 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1448 if (!r->in.share_name) {
1449 return WERR_INVALID_NAME;
1452 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1453 if (!share_name) {
1454 return WERR_NOMEM;
1456 if (snum < 0) {
1457 return WERR_INVALID_NAME;
1460 switch (r->in.level) {
1461 case 0:
1462 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1463 W_ERROR_HAVE_NO_MEMORY(info->info0);
1464 init_srv_share_info_0(p, info->info0, snum);
1465 break;
1466 case 1:
1467 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1468 W_ERROR_HAVE_NO_MEMORY(info->info1);
1469 init_srv_share_info_1(p, info->info1, snum);
1470 break;
1471 case 2:
1472 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1473 W_ERROR_HAVE_NO_MEMORY(info->info2);
1474 init_srv_share_info_2(p, info->info2, snum);
1475 break;
1476 case 501:
1477 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1478 W_ERROR_HAVE_NO_MEMORY(info->info501);
1479 init_srv_share_info_501(p, info->info501, snum);
1480 break;
1481 case 502:
1482 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1483 W_ERROR_HAVE_NO_MEMORY(info->info502);
1484 init_srv_share_info_502(p, info->info502, snum);
1485 break;
1486 case 1004:
1487 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1488 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1489 init_srv_share_info_1004(p, info->info1004, snum);
1490 break;
1491 case 1005:
1492 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1493 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1494 init_srv_share_info_1005(p, info->info1005, snum);
1495 break;
1496 case 1006:
1497 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1498 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1499 init_srv_share_info_1006(p, info->info1006, snum);
1500 break;
1501 case 1007:
1502 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1503 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1504 init_srv_share_info_1007(p, info->info1007, snum);
1505 break;
1506 case 1501:
1507 init_srv_share_info_1501(p, &info->info1501, snum);
1508 break;
1509 default:
1510 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1511 r->in.level));
1512 status = WERR_UNKNOWN_LEVEL;
1513 break;
1516 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1518 return status;
1521 /*******************************************************************
1522 _srvsvc_NetShareSetInfo. Modify share details.
1523 ********************************************************************/
1525 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1526 struct srvsvc_NetShareSetInfo *r)
1528 char *command = NULL;
1529 char *share_name = NULL;
1530 char *comment = NULL;
1531 const char *pathname = NULL;
1532 int type;
1533 int snum;
1534 int ret;
1535 char *path = NULL;
1536 struct security_descriptor *psd = NULL;
1537 bool is_disk_op = False;
1538 int max_connections = 0;
1539 TALLOC_CTX *ctx = p->mem_ctx;
1540 union srvsvc_NetShareInfo *info = r->in.info;
1542 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1544 if (!r->in.share_name) {
1545 return WERR_INVALID_NAME;
1548 if (r->out.parm_error) {
1549 *r->out.parm_error = 0;
1552 if ( strequal(r->in.share_name,"IPC$")
1553 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1554 || strequal(r->in.share_name,"global") )
1556 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1557 "modified by a remote user.\n",
1558 r->in.share_name ));
1559 return WERR_ACCESS_DENIED;
1562 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1563 if (!share_name) {
1564 return WERR_NOMEM;
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->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1577 /* fail out now if you are not root and not a disk op */
1579 if ( p->session_info->unix_token->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->session_info->unix_token->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_in = NULL;
1760 char *share_name = NULL;
1761 char *comment = NULL;
1762 char *pathname = NULL;
1763 int type;
1764 int snum;
1765 int ret;
1766 char *path;
1767 struct security_descriptor *psd = NULL;
1768 bool is_disk_op;
1769 int max_connections = 0;
1770 TALLOC_CTX *ctx = p->mem_ctx;
1772 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1774 if (r->out.parm_error) {
1775 *r->out.parm_error = 0;
1778 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1780 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1781 return WERR_ACCESS_DENIED;
1783 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1784 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1785 return WERR_ACCESS_DENIED;
1788 switch (r->in.level) {
1789 case 0:
1790 /* No path. Not enough info in a level 0 to do anything. */
1791 return WERR_ACCESS_DENIED;
1792 case 1:
1793 /* Not enough info in a level 1 to do anything. */
1794 return WERR_ACCESS_DENIED;
1795 case 2:
1796 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1797 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1798 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1799 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1800 0 : r->in.info->info2->max_users;
1801 type = r->in.info->info2->type;
1802 break;
1803 case 501:
1804 /* No path. Not enough info in a level 501 to do anything. */
1805 return WERR_ACCESS_DENIED;
1806 case 502:
1807 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1808 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1809 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1810 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1811 0 : r->in.info->info502->max_users;
1812 type = r->in.info->info502->type;
1813 psd = r->in.info->info502->sd_buf.sd;
1814 map_generic_share_sd_bits(psd);
1815 break;
1817 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1819 case 1004:
1820 case 1005:
1821 case 1006:
1822 case 1007:
1823 return WERR_ACCESS_DENIED;
1824 case 1501:
1825 /* DFS only level. */
1826 return WERR_ACCESS_DENIED;
1827 default:
1828 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1829 r->in.level));
1830 return WERR_UNKNOWN_LEVEL;
1833 /* check for invalid share names */
1835 if (!share_name_in || !validate_net_name(share_name_in,
1836 INVALID_SHARENAME_CHARS,
1837 strlen(share_name_in))) {
1838 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1839 share_name_in ? share_name_in : ""));
1840 return WERR_INVALID_NAME;
1843 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1844 || (lp_enable_asu_support() &&
1845 strequal(share_name_in,"ADMIN$"))) {
1846 return WERR_ACCESS_DENIED;
1849 snum = find_service(ctx, share_name_in, &share_name);
1850 if (!share_name) {
1851 return WERR_NOMEM;
1854 /* Share already exists. */
1855 if (snum >= 0) {
1856 return WERR_FILE_EXISTS;
1859 /* We can only add disk shares. */
1860 if (type != STYPE_DISKTREE) {
1861 return WERR_ACCESS_DENIED;
1864 /* Check if the pathname is valid. */
1865 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1866 return WERR_OBJECT_PATH_INVALID;
1869 /* Ensure share name, pathname and comment don't contain '"' characters. */
1870 string_replace(share_name_in, '"', ' ');
1871 string_replace(share_name, '"', ' ');
1872 string_replace(path, '"', ' ');
1873 if (comment) {
1874 string_replace(comment, '"', ' ');
1877 command = talloc_asprintf(ctx,
1878 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1879 lp_add_share_cmd(),
1880 get_dyn_CONFIGFILE(),
1881 share_name_in,
1882 path,
1883 comment ? comment : "",
1884 max_connections);
1885 if (!command) {
1886 return WERR_NOMEM;
1889 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1891 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1893 if ( is_disk_op )
1894 become_root();
1896 /* FIXME: use libnetconf here - gd */
1898 if ( (ret = smbrun(command, NULL)) == 0 ) {
1899 /* Tell everyone we updated smb.conf. */
1900 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1901 NULL);
1904 if ( is_disk_op )
1905 unbecome_root();
1907 /********* END SeDiskOperatorPrivilege BLOCK *********/
1909 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1910 command, ret ));
1912 TALLOC_FREE(command);
1914 if ( ret != 0 )
1915 return WERR_ACCESS_DENIED;
1917 if (psd) {
1918 /* Note we use share_name here, not share_name_in as
1919 we need a canonicalized name for setting security. */
1920 if (!set_share_security(share_name, psd)) {
1921 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1922 share_name ));
1927 * We don't call reload_services() here, the message will
1928 * cause this to be done before the next packet is read
1929 * from the client. JRA.
1932 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1934 return WERR_OK;
1937 /*******************************************************************
1938 _srvsvc_NetShareDel
1939 Call "delete share command" with the share name as
1940 a parameter.
1941 ********************************************************************/
1943 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
1944 struct srvsvc_NetShareDel *r)
1946 char *command = NULL;
1947 char *share_name = NULL;
1948 int ret;
1949 int snum;
1950 bool is_disk_op;
1951 struct share_params *params;
1952 TALLOC_CTX *ctx = p->mem_ctx;
1954 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1956 if (!r->in.share_name) {
1957 return WERR_NET_NAME_NOT_FOUND;
1960 if ( strequal(r->in.share_name,"IPC$")
1961 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1962 || strequal(r->in.share_name,"global") )
1964 return WERR_ACCESS_DENIED;
1967 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1968 if (!share_name) {
1969 return WERR_NOMEM;
1972 if (snum < 0) {
1973 return WERR_NO_SUCH_SHARE;
1976 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1977 return WERR_NO_SUCH_SHARE;
1980 /* No change to printer shares. */
1981 if (lp_print_ok(snum))
1982 return WERR_ACCESS_DENIED;
1984 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1986 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1987 return WERR_ACCESS_DENIED;
1989 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1990 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1991 return WERR_ACCESS_DENIED;
1994 command = talloc_asprintf(ctx,
1995 "%s \"%s\" \"%s\"",
1996 lp_delete_share_cmd(),
1997 get_dyn_CONFIGFILE(),
1998 lp_servicename(snum));
1999 if (!command) {
2000 return WERR_NOMEM;
2003 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2005 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2007 if ( is_disk_op )
2008 become_root();
2010 if ( (ret = smbrun(command, NULL)) == 0 ) {
2011 /* Tell everyone we updated smb.conf. */
2012 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2013 NULL);
2016 if ( is_disk_op )
2017 unbecome_root();
2019 /********* END SeDiskOperatorPrivilege BLOCK *********/
2021 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2023 if ( ret != 0 )
2024 return WERR_ACCESS_DENIED;
2026 /* Delete the SD in the database. */
2027 delete_share_security(lp_servicename(params->service));
2029 lp_killservice(params->service);
2031 return WERR_OK;
2034 /*******************************************************************
2035 _srvsvc_NetShareDelSticky
2036 ********************************************************************/
2038 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2039 struct srvsvc_NetShareDelSticky *r)
2041 struct srvsvc_NetShareDel q;
2043 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2045 q.in.server_unc = r->in.server_unc;
2046 q.in.share_name = r->in.share_name;
2047 q.in.reserved = r->in.reserved;
2049 return _srvsvc_NetShareDel(p, &q);
2052 /*******************************************************************
2053 _srvsvc_NetRemoteTOD
2054 ********************************************************************/
2056 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2057 struct srvsvc_NetRemoteTOD *r)
2059 struct srvsvc_NetRemoteTODInfo *tod;
2060 struct tm *t;
2061 time_t unixdate = time(NULL);
2063 /* We do this call first as if we do it *after* the gmtime call
2064 it overwrites the pointed-to values. JRA */
2066 uint32 zone = get_time_zone(unixdate)/60;
2068 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2070 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2071 return WERR_NOMEM;
2073 *r->out.info = tod;
2075 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2077 t = gmtime(&unixdate);
2079 /* set up the */
2080 tod->elapsed = unixdate;
2081 tod->msecs = 0;
2082 tod->hours = t->tm_hour;
2083 tod->mins = t->tm_min;
2084 tod->secs = t->tm_sec;
2085 tod->hunds = 0;
2086 tod->timezone = zone;
2087 tod->tinterval = 10000;
2088 tod->day = t->tm_mday;
2089 tod->month = t->tm_mon + 1;
2090 tod->year = 1900+t->tm_year;
2091 tod->weekday = t->tm_wday;
2093 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2095 return WERR_OK;
2098 /***********************************************************************************
2099 _srvsvc_NetGetFileSecurity
2100 Win9x NT tools get security descriptor.
2101 ***********************************************************************************/
2103 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2104 struct srvsvc_NetGetFileSecurity *r)
2106 struct smb_filename *smb_fname = NULL;
2107 struct security_descriptor *psd = NULL;
2108 size_t sd_size;
2109 char *servicename = NULL;
2110 SMB_STRUCT_STAT st;
2111 NTSTATUS nt_status;
2112 WERROR werr;
2113 connection_struct *conn = NULL;
2114 struct sec_desc_buf *sd_buf = NULL;
2115 files_struct *fsp = NULL;
2116 int snum;
2117 char *oldcwd = NULL;
2119 ZERO_STRUCT(st);
2121 if (!r->in.share) {
2122 werr = WERR_NET_NAME_NOT_FOUND;
2123 goto error_exit;
2125 snum = find_service(talloc_tos(), r->in.share, &servicename);
2126 if (!servicename) {
2127 werr = WERR_NOMEM;
2128 goto error_exit;
2130 if (snum == -1) {
2131 DEBUG(10, ("Could not find service %s\n", servicename));
2132 werr = WERR_NET_NAME_NOT_FOUND;
2133 goto error_exit;
2136 nt_status = create_conn_struct(talloc_tos(),
2137 server_event_context(),
2138 server_messaging_context(),
2139 &conn,
2140 snum, lp_pathname(snum),
2141 p->session_info, &oldcwd);
2142 if (!NT_STATUS_IS_OK(nt_status)) {
2143 DEBUG(10, ("create_conn_struct failed: %s\n",
2144 nt_errstr(nt_status)));
2145 werr = ntstatus_to_werror(nt_status);
2146 goto error_exit;
2149 nt_status = filename_convert(talloc_tos(),
2150 conn,
2151 false,
2152 r->in.file,
2154 NULL,
2155 &smb_fname);
2156 if (!NT_STATUS_IS_OK(nt_status)) {
2157 werr = ntstatus_to_werror(nt_status);
2158 goto error_exit;
2161 nt_status = SMB_VFS_CREATE_FILE(
2162 conn, /* conn */
2163 NULL, /* req */
2164 0, /* root_dir_fid */
2165 smb_fname, /* fname */
2166 FILE_READ_ATTRIBUTES, /* access_mask */
2167 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2168 FILE_OPEN, /* create_disposition*/
2169 0, /* create_options */
2170 0, /* file_attributes */
2171 INTERNAL_OPEN_ONLY, /* oplock_request */
2172 0, /* allocation_size */
2173 0, /* private_flags */
2174 NULL, /* sd */
2175 NULL, /* ea_list */
2176 &fsp, /* result */
2177 NULL); /* pinfo */
2179 if (!NT_STATUS_IS_OK(nt_status)) {
2180 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2181 smb_fname_str_dbg(smb_fname)));
2182 werr = ntstatus_to_werror(nt_status);
2183 goto error_exit;
2186 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2187 (SECINFO_OWNER
2188 |SECINFO_GROUP
2189 |SECINFO_DACL), &psd);
2191 if (!NT_STATUS_IS_OK(nt_status)) {
2192 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2193 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2194 werr = ntstatus_to_werror(nt_status);
2195 goto error_exit;
2198 sd_size = ndr_size_security_descriptor(psd, 0);
2200 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2201 if (!sd_buf) {
2202 werr = WERR_NOMEM;
2203 goto error_exit;
2206 sd_buf->sd_size = sd_size;
2207 sd_buf->sd = psd;
2209 *r->out.sd_buf = sd_buf;
2211 psd->dacl->revision = NT4_ACL_REVISION;
2213 close_file(NULL, fsp, NORMAL_CLOSE);
2214 vfs_ChDir(conn, oldcwd);
2215 SMB_VFS_DISCONNECT(conn);
2216 conn_free(conn);
2217 werr = WERR_OK;
2218 goto done;
2220 error_exit:
2222 if (fsp) {
2223 close_file(NULL, fsp, NORMAL_CLOSE);
2226 if (oldcwd) {
2227 vfs_ChDir(conn, oldcwd);
2230 if (conn) {
2231 SMB_VFS_DISCONNECT(conn);
2232 conn_free(conn);
2235 done:
2236 TALLOC_FREE(smb_fname);
2238 return werr;
2241 /***********************************************************************************
2242 _srvsvc_NetSetFileSecurity
2243 Win9x NT tools set security descriptor.
2244 ***********************************************************************************/
2246 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2247 struct srvsvc_NetSetFileSecurity *r)
2249 struct smb_filename *smb_fname = NULL;
2250 char *servicename = NULL;
2251 files_struct *fsp = NULL;
2252 SMB_STRUCT_STAT st;
2253 NTSTATUS nt_status;
2254 WERROR werr;
2255 connection_struct *conn = NULL;
2256 int snum;
2257 char *oldcwd = NULL;
2258 struct security_descriptor *psd = NULL;
2259 uint32_t security_info_sent = 0;
2261 ZERO_STRUCT(st);
2263 if (!r->in.share) {
2264 werr = WERR_NET_NAME_NOT_FOUND;
2265 goto error_exit;
2268 snum = find_service(talloc_tos(), r->in.share, &servicename);
2269 if (!servicename) {
2270 werr = WERR_NOMEM;
2271 goto error_exit;
2274 if (snum == -1) {
2275 DEBUG(10, ("Could not find service %s\n", servicename));
2276 werr = WERR_NET_NAME_NOT_FOUND;
2277 goto error_exit;
2280 nt_status = create_conn_struct(talloc_tos(),
2281 server_event_context(),
2282 server_messaging_context(),
2283 &conn,
2284 snum, lp_pathname(snum),
2285 p->session_info, &oldcwd);
2286 if (!NT_STATUS_IS_OK(nt_status)) {
2287 DEBUG(10, ("create_conn_struct failed: %s\n",
2288 nt_errstr(nt_status)));
2289 werr = ntstatus_to_werror(nt_status);
2290 goto error_exit;
2293 nt_status = filename_convert(talloc_tos(),
2294 conn,
2295 false,
2296 r->in.file,
2298 NULL,
2299 &smb_fname);
2300 if (!NT_STATUS_IS_OK(nt_status)) {
2301 werr = ntstatus_to_werror(nt_status);
2302 goto error_exit;
2305 nt_status = SMB_VFS_CREATE_FILE(
2306 conn, /* conn */
2307 NULL, /* req */
2308 0, /* root_dir_fid */
2309 smb_fname, /* fname */
2310 FILE_WRITE_ATTRIBUTES, /* access_mask */
2311 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2312 FILE_OPEN, /* create_disposition*/
2313 0, /* create_options */
2314 0, /* file_attributes */
2315 INTERNAL_OPEN_ONLY, /* oplock_request */
2316 0, /* allocation_size */
2317 0, /* private_flags */
2318 NULL, /* sd */
2319 NULL, /* ea_list */
2320 &fsp, /* result */
2321 NULL); /* pinfo */
2323 if (!NT_STATUS_IS_OK(nt_status)) {
2324 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2325 smb_fname_str_dbg(smb_fname)));
2326 werr = ntstatus_to_werror(nt_status);
2327 goto error_exit;
2330 psd = r->in.sd_buf->sd;
2331 security_info_sent = r->in.securityinformation;
2333 if (psd->owner_sid==0) {
2334 security_info_sent &= ~SECINFO_OWNER;
2336 if (psd->group_sid==0) {
2337 security_info_sent &= ~SECINFO_GROUP;
2339 if (psd->sacl==0) {
2340 security_info_sent &= ~SECINFO_SACL;
2342 if (psd->dacl==0) {
2343 security_info_sent &= ~SECINFO_DACL;
2346 /* Convert all the generic bits. */
2347 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2348 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2350 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2351 security_info_sent,
2352 psd);
2354 if (!NT_STATUS_IS_OK(nt_status) ) {
2355 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2356 "on file %s\n", r->in.share));
2357 werr = WERR_ACCESS_DENIED;
2358 goto error_exit;
2361 close_file(NULL, fsp, NORMAL_CLOSE);
2362 vfs_ChDir(conn, oldcwd);
2363 SMB_VFS_DISCONNECT(conn);
2364 conn_free(conn);
2365 werr = WERR_OK;
2366 goto done;
2368 error_exit:
2370 if (fsp) {
2371 close_file(NULL, fsp, NORMAL_CLOSE);
2374 if (oldcwd) {
2375 vfs_ChDir(conn, oldcwd);
2378 if (conn) {
2379 SMB_VFS_DISCONNECT(conn);
2380 conn_free(conn);
2383 done:
2384 TALLOC_FREE(smb_fname);
2386 return werr;
2389 /***********************************************************************************
2390 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2391 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2392 These disks would the disks listed by this function.
2393 Users could then create shares relative to these disks. Watch out for moving these disks around.
2394 "Nigel Williams" <nigel@veritas.com>.
2395 ***********************************************************************************/
2397 static const char *server_disks[] = {"C:"};
2399 static uint32 get_server_disk_count(void)
2401 return sizeof(server_disks)/sizeof(server_disks[0]);
2404 static uint32 init_server_disk_enum(uint32 *resume)
2406 uint32 server_disk_count = get_server_disk_count();
2408 /*resume can be an offset into the list for now*/
2410 if(*resume & 0x80000000)
2411 *resume = 0;
2413 if(*resume > server_disk_count)
2414 *resume = server_disk_count;
2416 return server_disk_count - *resume;
2419 static const char *next_server_disk_enum(uint32 *resume)
2421 const char *disk;
2423 if(init_server_disk_enum(resume) == 0)
2424 return NULL;
2426 disk = server_disks[*resume];
2428 (*resume)++;
2430 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2432 return disk;
2435 /********************************************************************
2436 _srvsvc_NetDiskEnum
2437 ********************************************************************/
2439 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2440 struct srvsvc_NetDiskEnum *r)
2442 uint32 i;
2443 const char *disk_name;
2444 TALLOC_CTX *ctx = p->mem_ctx;
2445 WERROR werr;
2446 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2448 werr = WERR_OK;
2450 *r->out.totalentries = init_server_disk_enum(&resume);
2452 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2453 MAX_SERVER_DISK_ENTRIES);
2454 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2456 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2458 r->out.info->count = 0;
2460 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2462 r->out.info->count++;
2464 /*copy disk name into a unicode string*/
2466 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2467 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2470 /* add a terminating null string. Is this there if there is more data to come? */
2472 r->out.info->count++;
2474 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2475 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2477 if (r->out.resume_handle) {
2478 *r->out.resume_handle = resume;
2481 return werr;
2484 /********************************************************************
2485 _srvsvc_NetNameValidate
2486 ********************************************************************/
2488 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2489 struct srvsvc_NetNameValidate *r)
2491 switch (r->in.name_type) {
2492 case 0x9:
2493 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2494 strlen_m(r->in.name)))
2496 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2497 r->in.name));
2498 return WERR_INVALID_NAME;
2500 break;
2502 default:
2503 return WERR_UNKNOWN_LEVEL;
2506 return WERR_OK;
2509 /*******************************************************************
2510 ********************************************************************/
2512 struct enum_file_close_state {
2513 struct srvsvc_NetFileClose *r;
2514 struct messaging_context *msg_ctx;
2517 static void enum_file_close_fn( const struct share_mode_entry *e,
2518 const char *sharepath, const char *fname,
2519 void *private_data )
2521 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2522 struct enum_file_close_state *state =
2523 (struct enum_file_close_state *)private_data;
2524 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2526 if (fid != state->r->in.fid) {
2527 return; /* Not this file. */
2530 if (!process_exists(e->pid) ) {
2531 return;
2534 /* Ok - send the close message. */
2535 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2536 sharepath,
2537 share_mode_str(talloc_tos(), 0, e) ));
2539 share_mode_entry_to_message(msg, e);
2541 state->r->out.result = ntstatus_to_werror(
2542 messaging_send_buf(state->msg_ctx,
2543 e->pid, MSG_SMB_CLOSE_FILE,
2544 (uint8 *)msg,
2545 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2548 /********************************************************************
2549 Close a file given a 32-bit file id.
2550 ********************************************************************/
2552 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2553 struct srvsvc_NetFileClose *r)
2555 struct enum_file_close_state state;
2556 bool is_disk_op;
2558 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2560 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2562 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2563 return WERR_ACCESS_DENIED;
2566 /* enum_file_close_fn sends the close message to
2567 * the relevent smbd process. */
2569 r->out.result = WERR_BADFILE;
2570 state.r = r;
2571 state.msg_ctx = p->msg_ctx;
2572 share_mode_forall(enum_file_close_fn, &state);
2573 return r->out.result;
2576 /********************************************************************
2577 ********************************************************************/
2579 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2580 struct srvsvc_NetCharDevEnum *r)
2582 p->rng_fault_state = True;
2583 return WERR_NOT_SUPPORTED;
2586 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2587 struct srvsvc_NetCharDevGetInfo *r)
2589 p->rng_fault_state = True;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2594 struct srvsvc_NetCharDevControl *r)
2596 p->rng_fault_state = True;
2597 return WERR_NOT_SUPPORTED;
2600 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2601 struct srvsvc_NetCharDevQEnum *r)
2603 p->rng_fault_state = True;
2604 return WERR_NOT_SUPPORTED;
2607 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2608 struct srvsvc_NetCharDevQGetInfo *r)
2610 p->rng_fault_state = True;
2611 return WERR_NOT_SUPPORTED;
2614 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2615 struct srvsvc_NetCharDevQSetInfo *r)
2617 p->rng_fault_state = True;
2618 return WERR_NOT_SUPPORTED;
2621 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2622 struct srvsvc_NetCharDevQPurge *r)
2624 p->rng_fault_state = True;
2625 return WERR_NOT_SUPPORTED;
2628 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2629 struct srvsvc_NetCharDevQPurgeSelf *r)
2631 p->rng_fault_state = True;
2632 return WERR_NOT_SUPPORTED;
2635 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2636 struct srvsvc_NetFileGetInfo *r)
2638 p->rng_fault_state = True;
2639 return WERR_NOT_SUPPORTED;
2642 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2643 struct srvsvc_NetShareCheck *r)
2645 p->rng_fault_state = True;
2646 return WERR_NOT_SUPPORTED;
2649 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2650 struct srvsvc_NetServerStatisticsGet *r)
2652 p->rng_fault_state = True;
2653 return WERR_NOT_SUPPORTED;
2656 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2657 struct srvsvc_NetTransportAdd *r)
2659 p->rng_fault_state = True;
2660 return WERR_NOT_SUPPORTED;
2663 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2664 struct srvsvc_NetTransportEnum *r)
2666 p->rng_fault_state = True;
2667 return WERR_NOT_SUPPORTED;
2670 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2671 struct srvsvc_NetTransportDel *r)
2673 p->rng_fault_state = True;
2674 return WERR_NOT_SUPPORTED;
2677 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2678 struct srvsvc_NetSetServiceBits *r)
2680 p->rng_fault_state = True;
2681 return WERR_NOT_SUPPORTED;
2684 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2685 struct srvsvc_NetPathType *r)
2687 p->rng_fault_state = True;
2688 return WERR_NOT_SUPPORTED;
2691 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2692 struct srvsvc_NetPathCanonicalize *r)
2694 p->rng_fault_state = True;
2695 return WERR_NOT_SUPPORTED;
2698 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2699 struct srvsvc_NetPathCompare *r)
2701 p->rng_fault_state = True;
2702 return WERR_NOT_SUPPORTED;
2705 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2706 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2708 p->rng_fault_state = True;
2709 return WERR_NOT_SUPPORTED;
2712 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2713 struct srvsvc_NetPRNameCompare *r)
2715 p->rng_fault_state = True;
2716 return WERR_NOT_SUPPORTED;
2719 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2720 struct srvsvc_NetShareDelStart *r)
2722 p->rng_fault_state = True;
2723 return WERR_NOT_SUPPORTED;
2726 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2727 struct srvsvc_NetShareDelCommit *r)
2729 p->rng_fault_state = True;
2730 return WERR_NOT_SUPPORTED;
2733 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2734 struct srvsvc_NetServerTransportAddEx *r)
2736 p->rng_fault_state = True;
2737 return WERR_NOT_SUPPORTED;
2740 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2741 struct srvsvc_NetServerSetServiceBitsEx *r)
2743 p->rng_fault_state = True;
2744 return WERR_NOT_SUPPORTED;
2747 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2748 struct srvsvc_NETRDFSGETVERSION *r)
2750 p->rng_fault_state = True;
2751 return WERR_NOT_SUPPORTED;
2754 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2755 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2757 p->rng_fault_state = True;
2758 return WERR_NOT_SUPPORTED;
2761 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2762 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2764 p->rng_fault_state = True;
2765 return WERR_NOT_SUPPORTED;
2768 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2769 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2771 p->rng_fault_state = True;
2772 return WERR_NOT_SUPPORTED;
2775 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2776 struct srvsvc_NETRDFSSETSERVERINFO *r)
2778 p->rng_fault_state = True;
2779 return WERR_NOT_SUPPORTED;
2782 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2783 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2785 p->rng_fault_state = True;
2786 return WERR_NOT_SUPPORTED;
2789 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2790 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2792 p->rng_fault_state = True;
2793 return WERR_NOT_SUPPORTED;
2796 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2797 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2799 p->rng_fault_state = True;
2800 return WERR_NOT_SUPPORTED;
2803 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2804 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2806 p->rng_fault_state = True;
2807 return WERR_NOT_SUPPORTED;
2810 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2811 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2813 p->rng_fault_state = True;
2814 return WERR_NOT_SUPPORTED;
2817 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2818 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2820 p->rng_fault_state = True;
2821 return WERR_NOT_SUPPORTED;