s4:libcli/smb_composite: make use of smb1cli_session_set_session_key()
[Samba/gebeck_regimport.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob7f34ec28e03003d4b5d4afa89d18147b93d4177f
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"
40 #include "lib/conn_tdb.h"
42 extern const struct generic_mapping file_generic_mapping;
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define MAX_SERVER_DISK_ENTRIES 15
49 /* Use for enumerating connections, pipes, & files */
51 struct file_enum_count {
52 TALLOC_CTX *ctx;
53 const char *username;
54 struct srvsvc_NetFileCtr3 *ctr3;
57 struct sess_file_count {
58 struct server_id pid;
59 uid_t uid;
60 int count;
63 /* Used to store pipe open records for NetFileEnum() */
65 struct pipe_open_rec {
66 struct server_id pid;
67 uid_t uid;
68 int pnum;
69 fstring name;
72 /****************************************************************************
73 Count the entries belonging to a service in the connection db.
74 ****************************************************************************/
76 static int pipe_enum_fn( struct db_record *rec, void *p)
78 struct pipe_open_rec prec;
79 struct file_enum_count *fenum = (struct file_enum_count *)p;
80 struct srvsvc_NetFileInfo3 *f;
81 int i = fenum->ctr3->count;
82 char *fullpath = NULL;
83 const char *username;
84 TDB_DATA value;
86 value = dbwrap_record_get_value(rec);
88 if (value.dsize != sizeof(struct pipe_open_rec))
89 return 0;
91 memcpy(&prec, value.dptr, sizeof(struct pipe_open_rec));
93 if ( !process_exists(prec.pid) ) {
94 return 0;
97 username = uidtoname(prec.uid);
99 if ((fenum->username != NULL)
100 && !strequal(username, fenum->username)) {
101 return 0;
104 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
105 if (!fullpath) {
106 return 1;
109 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
110 struct srvsvc_NetFileInfo3, i+1);
111 if ( !f ) {
112 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
113 return 1;
115 fenum->ctr3->array = f;
117 fenum->ctr3->array[i].fid =
118 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
119 fenum->ctr3->array[i].permissions =
120 (FILE_READ_DATA|FILE_WRITE_DATA);
121 fenum->ctr3->array[i].num_locks = 0;
122 fenum->ctr3->array[i].path = fullpath;
123 fenum->ctr3->array[i].user = username;
125 fenum->ctr3->count++;
127 return 0;
130 /*******************************************************************
131 ********************************************************************/
133 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
134 const char *username,
135 struct srvsvc_NetFileCtr3 **ctr3,
136 uint32_t resume )
138 struct file_enum_count fenum;
140 fenum.ctx = ctx;
141 fenum.username = username;
142 fenum.ctr3 = *ctr3;
144 if (connections_traverse(pipe_enum_fn, &fenum) < 0) {
145 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
146 "failed\n"));
147 return WERR_NOMEM;
150 *ctr3 = fenum.ctr3;
152 return WERR_OK;
155 /*******************************************************************
156 ********************************************************************/
158 static void enum_file_fn( const struct share_mode_entry *e,
159 const char *sharepath, const char *fname,
160 void *private_data )
162 struct file_enum_count *fenum =
163 (struct file_enum_count *)private_data;
165 struct srvsvc_NetFileInfo3 *f;
166 int i = fenum->ctr3->count;
167 files_struct fsp;
168 struct byte_range_lock *brl;
169 int num_locks = 0;
170 char *fullpath = NULL;
171 uint32 permissions;
172 const char *username;
174 /* If the pid was not found delete the entry from connections.tdb */
176 if ( !process_exists(e->pid) ) {
177 return;
180 username = uidtoname(e->uid);
182 if ((fenum->username != NULL)
183 && !strequal(username, fenum->username)) {
184 return;
187 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
188 struct srvsvc_NetFileInfo3, i+1);
189 if ( !f ) {
190 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
191 return;
193 fenum->ctr3->array = f;
195 /* need to count the number of locks on a file */
197 ZERO_STRUCT( fsp );
198 fsp.file_id = e->id;
200 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
201 num_locks = brl->num_locks;
202 TALLOC_FREE(brl);
205 if ( strcmp( fname, "." ) == 0 ) {
206 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
207 } else {
208 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
209 sharepath, fname );
211 if (!fullpath) {
212 return;
214 string_replace( fullpath, '/', '\\' );
216 /* mask out create (what ever that is) */
217 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
219 /* now fill in the srvsvc_NetFileInfo3 struct */
221 fenum->ctr3->array[i].fid =
222 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
223 fenum->ctr3->array[i].permissions = permissions;
224 fenum->ctr3->array[i].num_locks = num_locks;
225 fenum->ctr3->array[i].path = fullpath;
226 fenum->ctr3->array[i].user = username;
228 fenum->ctr3->count++;
231 /*******************************************************************
232 ********************************************************************/
234 static WERROR net_enum_files(TALLOC_CTX *ctx,
235 const char *username,
236 struct srvsvc_NetFileCtr3 **ctr3,
237 uint32_t resume)
239 struct file_enum_count f_enum_cnt;
241 f_enum_cnt.ctx = ctx;
242 f_enum_cnt.username = username;
243 f_enum_cnt.ctr3 = *ctr3;
245 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
247 *ctr3 = f_enum_cnt.ctr3;
249 return WERR_OK;
252 /*******************************************************************
253 Utility function to get the 'type' of a share from an snum.
254 ********************************************************************/
255 static enum srvsvc_ShareType get_share_type(int snum)
257 /* work out the share type */
258 enum srvsvc_ShareType type = STYPE_DISKTREE;
260 if (lp_print_ok(snum)) {
261 type = lp_administrative_share(snum)
262 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
264 if (strequal(lp_fstype(talloc_tos(), snum), "IPC")) {
265 type = lp_administrative_share(snum)
266 ? STYPE_IPC_HIDDEN : STYPE_IPC;
268 return type;
271 /*******************************************************************
272 Fill in a share info level 0 structure.
273 ********************************************************************/
275 static void init_srv_share_info_0(struct pipes_struct *p,
276 struct srvsvc_NetShareInfo0 *r, int snum)
278 r->name = lp_servicename(talloc_tos(), snum);
281 /*******************************************************************
282 Fill in a share info level 1 structure.
283 ********************************************************************/
285 static void init_srv_share_info_1(struct pipes_struct *p,
286 struct srvsvc_NetShareInfo1 *r,
287 int snum)
289 char *net_name = lp_servicename(talloc_tos(), snum);
290 char *remark = lp_comment(p->mem_ctx, snum);
292 if (remark) {
293 remark = talloc_sub_advanced(
294 p->mem_ctx, lp_servicename(talloc_tos(), snum),
295 get_current_username(), lp_pathname(talloc_tos(), snum),
296 p->session_info->unix_token->uid, get_current_username(),
297 "", remark);
300 r->name = net_name;
301 r->type = get_share_type(snum);
302 r->comment = remark ? remark : "";
305 /*******************************************************************
306 Fill in a share info level 2 structure.
307 ********************************************************************/
309 static void init_srv_share_info_2(struct pipes_struct *p,
310 struct srvsvc_NetShareInfo2 *r,
311 int snum)
313 char *remark = NULL;
314 char *path = NULL;
315 int max_connections = lp_max_connections(snum);
316 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
317 char *net_name = lp_servicename(talloc_tos(), snum);
319 remark = lp_comment(p->mem_ctx, snum);
320 if (remark) {
321 remark = talloc_sub_advanced(
322 p->mem_ctx, lp_servicename(talloc_tos(), snum),
323 get_current_username(), lp_pathname(talloc_tos(), snum),
324 p->session_info->unix_token->uid, get_current_username(),
325 "", remark);
327 path = talloc_asprintf(p->mem_ctx,
328 "C:%s", lp_pathname(talloc_tos(), snum));
330 if (path) {
332 * Change / to \\ so that win2k will see it as a valid path.
333 * This was added to enable use of browsing in win2k add
334 * share dialog.
337 string_replace(path, '/', '\\');
340 r->name = net_name;
341 r->type = get_share_type(snum);
342 r->comment = remark ? remark : "";
343 r->permissions = 0;
344 r->max_users = max_uses;
345 r->current_users = count_current_connections(net_name, false);
346 r->path = path ? path : "";
347 r->password = "";
350 /*******************************************************************
351 Map any generic bits to file specific bits.
352 ********************************************************************/
354 static void map_generic_share_sd_bits(struct security_descriptor *psd)
356 int i;
357 struct security_acl *ps_dacl = NULL;
359 if (!psd)
360 return;
362 ps_dacl = psd->dacl;
363 if (!ps_dacl)
364 return;
366 for (i = 0; i < ps_dacl->num_aces; i++) {
367 struct security_ace *psa = &ps_dacl->aces[i];
368 uint32 orig_mask = psa->access_mask;
370 se_map_generic(&psa->access_mask, &file_generic_mapping);
371 psa->access_mask |= orig_mask;
375 /*******************************************************************
376 Fill in a share info level 501 structure.
377 ********************************************************************/
379 static void init_srv_share_info_501(struct pipes_struct *p,
380 struct srvsvc_NetShareInfo501 *r, int snum)
382 const char *net_name = lp_servicename(talloc_tos(), snum);
383 char *remark = lp_comment(p->mem_ctx, snum);
385 if (remark) {
386 remark = talloc_sub_advanced(
387 p->mem_ctx, lp_servicename(talloc_tos(), snum),
388 get_current_username(), lp_pathname(talloc_tos(), snum),
389 p->session_info->unix_token->uid, get_current_username(),
390 "", remark);
393 r->name = net_name;
394 r->type = get_share_type(snum);
395 r->comment = remark ? remark : "";
396 r->csc_policy = (lp_csc_policy(snum) << 4);
399 /*******************************************************************
400 Fill in a share info level 502 structure.
401 ********************************************************************/
403 static void init_srv_share_info_502(struct pipes_struct *p,
404 struct srvsvc_NetShareInfo502 *r, int snum)
406 const char *net_name = lp_servicename(talloc_tos(), snum);
407 char *path = NULL;
408 struct security_descriptor *sd = NULL;
409 struct sec_desc_buf *sd_buf = NULL;
410 size_t sd_size = 0;
411 TALLOC_CTX *ctx = p->mem_ctx;
412 char *remark = lp_comment(ctx, snum);
414 if (remark) {
415 remark = talloc_sub_advanced(
416 p->mem_ctx, lp_servicename(talloc_tos(), snum),
417 get_current_username(), lp_pathname(talloc_tos(), snum),
418 p->session_info->unix_token->uid, get_current_username(),
419 "", remark);
421 path = talloc_asprintf(ctx, "C:%s", lp_pathname(talloc_tos(), snum));
422 if (path) {
424 * Change / to \\ so that win2k will see it as a valid path. This was added to
425 * enable use of browsing in win2k add share dialog.
427 string_replace(path, '/', '\\');
430 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
432 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
434 r->name = net_name;
435 r->type = get_share_type(snum);
436 r->comment = remark ? remark : "";
437 r->permissions = 0;
438 r->max_users = (uint32_t)-1;
439 r->current_users = 1; /* ??? */
440 r->path = path ? path : "";
441 r->password = "";
442 r->sd_buf = *sd_buf;
445 /***************************************************************************
446 Fill in a share info level 1004 structure.
447 ***************************************************************************/
449 static void init_srv_share_info_1004(struct pipes_struct *p,
450 struct srvsvc_NetShareInfo1004 *r,
451 int snum)
453 char *remark = lp_comment(p->mem_ctx, snum);
455 if (remark) {
456 remark = talloc_sub_advanced(
457 p->mem_ctx, lp_servicename(talloc_tos(), snum),
458 get_current_username(), lp_pathname(talloc_tos(), snum),
459 p->session_info->unix_token->uid, get_current_username(),
460 "", remark);
463 r->comment = remark ? remark : "";
466 /***************************************************************************
467 Fill in a share info level 1005 structure.
468 ***************************************************************************/
470 static void init_srv_share_info_1005(struct pipes_struct *p,
471 struct srvsvc_NetShareInfo1005 *r,
472 int snum)
474 uint32_t dfs_flags = 0;
476 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
477 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
480 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
482 r->dfs_flags = dfs_flags;
485 /***************************************************************************
486 Fill in a share info level 1006 structure.
487 ***************************************************************************/
489 static void init_srv_share_info_1006(struct pipes_struct *p,
490 struct srvsvc_NetShareInfo1006 *r,
491 int snum)
493 r->max_users = (uint32_t)-1;
496 /***************************************************************************
497 Fill in a share info level 1007 structure.
498 ***************************************************************************/
500 static void init_srv_share_info_1007(struct pipes_struct *p,
501 struct srvsvc_NetShareInfo1007 *r,
502 int snum)
504 r->flags = 0;
505 r->alternate_directory_name = "";
508 /*******************************************************************
509 Fill in a share info level 1501 structure.
510 ********************************************************************/
512 static void init_srv_share_info_1501(struct pipes_struct *p,
513 struct sec_desc_buf **r,
514 int snum)
516 struct security_descriptor *sd;
517 struct sec_desc_buf *sd_buf = NULL;
518 size_t sd_size;
519 TALLOC_CTX *ctx = p->mem_ctx;
521 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
522 if (sd) {
523 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
526 *r = sd_buf;
529 /*******************************************************************
530 True if it ends in '$'.
531 ********************************************************************/
533 static bool is_hidden_share(int snum)
535 const char *net_name = lp_servicename(talloc_tos(), snum);
537 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
540 /*******************************************************************
541 Verify user is allowed to view share, access based enumeration
542 ********************************************************************/
543 static bool is_enumeration_allowed(struct pipes_struct *p,
544 int snum)
546 if (!lp_access_based_share_enum(snum))
547 return true;
549 return share_access_check(p->session_info->security_token,
550 lp_servicename(talloc_tos(), snum),
551 FILE_READ_DATA, NULL);
554 /*******************************************************************
555 Fill in a share info structure.
556 ********************************************************************/
558 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
559 struct srvsvc_NetShareInfoCtr *info_ctr,
560 uint32_t *resume_handle_p,
561 uint32_t *total_entries,
562 bool all_shares)
564 int num_entries = 0;
565 int alloc_entries = 0;
566 int num_services = 0;
567 int snum;
568 TALLOC_CTX *ctx = p->mem_ctx;
569 int i = 0;
570 int valid_share_count = 0;
571 bool *allowed = 0;
572 union srvsvc_NetShareCtr ctr;
573 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
575 DEBUG(5,("init_srv_share_info_ctr\n"));
577 /* Ensure all the usershares are loaded. */
578 become_root();
579 load_usershare_shares(NULL, connections_snum_used);
580 load_registry_shares();
581 num_services = lp_numservices();
582 unbecome_root();
584 allowed = talloc_zero_array(ctx, bool, num_services);
585 W_ERROR_HAVE_NO_MEMORY(allowed);
587 /* Count the number of entries. */
588 for (snum = 0; snum < num_services; snum++) {
589 if (lp_browseable(snum) && lp_snum_ok(snum) &&
590 is_enumeration_allowed(p, snum) &&
591 (all_shares || !is_hidden_share(snum)) ) {
592 DEBUG(10, ("counting service %s\n",
593 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
594 allowed[snum] = true;
595 num_entries++;
596 } else {
597 DEBUG(10, ("NOT counting service %s\n",
598 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
602 if (!num_entries || (resume_handle >= num_entries)) {
603 return WERR_OK;
606 /* Calculate alloc entries. */
607 alloc_entries = num_entries - resume_handle;
608 switch (info_ctr->level) {
609 case 0:
610 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
611 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
613 ctr.ctr0->count = alloc_entries;
614 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
615 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
617 for (snum = 0; snum < num_services; snum++) {
618 if (allowed[snum] &&
619 (resume_handle <= (i + valid_share_count++)) ) {
620 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
624 break;
626 case 1:
627 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
628 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
630 ctr.ctr1->count = alloc_entries;
631 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
632 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
634 for (snum = 0; snum < num_services; snum++) {
635 if (allowed[snum] &&
636 (resume_handle <= (i + valid_share_count++)) ) {
637 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
641 break;
643 case 2:
644 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
645 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
647 ctr.ctr2->count = alloc_entries;
648 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
649 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
651 for (snum = 0; snum < num_services; snum++) {
652 if (allowed[snum] &&
653 (resume_handle <= (i + valid_share_count++)) ) {
654 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
658 break;
660 case 501:
661 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
662 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
664 ctr.ctr501->count = alloc_entries;
665 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
666 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
668 for (snum = 0; snum < num_services; snum++) {
669 if (allowed[snum] &&
670 (resume_handle <= (i + valid_share_count++)) ) {
671 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
675 break;
677 case 502:
678 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
679 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
681 ctr.ctr502->count = alloc_entries;
682 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
683 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
685 for (snum = 0; snum < num_services; snum++) {
686 if (allowed[snum] &&
687 (resume_handle <= (i + valid_share_count++)) ) {
688 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
692 break;
694 case 1004:
695 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
696 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
698 ctr.ctr1004->count = alloc_entries;
699 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
700 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
702 for (snum = 0; snum < num_services; snum++) {
703 if (allowed[snum] &&
704 (resume_handle <= (i + valid_share_count++)) ) {
705 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
709 break;
711 case 1005:
712 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
713 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
715 ctr.ctr1005->count = alloc_entries;
716 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
717 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
719 for (snum = 0; snum < num_services; snum++) {
720 if (allowed[snum] &&
721 (resume_handle <= (i + valid_share_count++)) ) {
722 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
726 break;
728 case 1006:
729 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
730 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
732 ctr.ctr1006->count = alloc_entries;
733 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
734 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
736 for (snum = 0; snum < num_services; snum++) {
737 if (allowed[snum] &&
738 (resume_handle <= (i + valid_share_count++)) ) {
739 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
743 break;
745 case 1007:
746 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
747 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
749 ctr.ctr1007->count = alloc_entries;
750 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
751 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
753 for (snum = 0; snum < num_services; snum++) {
754 if (allowed[snum] &&
755 (resume_handle <= (i + valid_share_count++)) ) {
756 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
760 break;
762 case 1501:
763 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
764 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
766 ctr.ctr1501->count = alloc_entries;
767 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
768 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
770 for (snum = 0; snum < num_services; snum++) {
771 if (allowed[snum] &&
772 (resume_handle <= (i + valid_share_count++)) ) {
773 struct sec_desc_buf *sd_buf = NULL;
774 init_srv_share_info_1501(p, &sd_buf, snum);
775 ctr.ctr1501->array[i++] = *sd_buf;
779 break;
781 default:
782 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
783 info_ctr->level));
784 return WERR_UNKNOWN_LEVEL;
787 *total_entries = alloc_entries;
788 if (resume_handle_p) {
789 if (all_shares) {
790 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
791 } else {
792 *resume_handle_p = num_entries;
796 info_ctr->ctr = ctr;
798 return WERR_OK;
801 /*******************************************************************
802 fill in a sess info level 0 structure.
803 ********************************************************************/
805 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
806 struct srvsvc_NetSessCtr0 *ctr0,
807 uint32_t *resume_handle_p,
808 uint32_t *total_entries)
810 struct sessionid *session_list;
811 uint32_t num_entries = 0;
812 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
813 *total_entries = list_sessions(p->mem_ctx, &session_list);
815 DEBUG(5,("init_srv_sess_info_0\n"));
817 if (ctr0 == NULL) {
818 if (resume_handle_p) {
819 *resume_handle_p = 0;
821 return WERR_OK;
824 for (; resume_handle < *total_entries; resume_handle++) {
826 ctr0->array = talloc_realloc(p->mem_ctx,
827 ctr0->array,
828 struct srvsvc_NetSessInfo0,
829 num_entries+1);
830 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
832 ctr0->array[num_entries].client =
833 session_list[resume_handle].remote_machine;
835 num_entries++;
838 ctr0->count = num_entries;
840 if (resume_handle_p) {
841 if (*resume_handle_p >= *total_entries) {
842 *resume_handle_p = 0;
843 } else {
844 *resume_handle_p = resume_handle;
848 return WERR_OK;
851 /*******************************************************************
852 ********************************************************************/
854 static void sess_file_fn( const struct share_mode_entry *e,
855 const char *sharepath, const char *fname,
856 void *data )
858 struct sess_file_count *sess = (struct sess_file_count *)data;
860 if (serverid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid)) {
861 sess->count++;
864 return;
867 /*******************************************************************
868 ********************************************************************/
870 static int net_count_files( uid_t uid, struct server_id pid )
872 struct sess_file_count s_file_cnt;
874 s_file_cnt.count = 0;
875 s_file_cnt.uid = uid;
876 s_file_cnt.pid = pid;
878 share_mode_forall( sess_file_fn, &s_file_cnt );
880 return s_file_cnt.count;
883 /*******************************************************************
884 fill in a sess info level 1 structure.
885 ********************************************************************/
887 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
888 struct srvsvc_NetSessCtr1 *ctr1,
889 uint32_t *resume_handle_p,
890 uint32_t *total_entries)
892 struct sessionid *session_list;
893 uint32_t num_entries = 0;
894 time_t now = time(NULL);
895 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
897 ZERO_STRUCTP(ctr1);
899 if (ctr1 == NULL) {
900 if (resume_handle_p) {
901 *resume_handle_p = 0;
903 return WERR_OK;
906 *total_entries = list_sessions(p->mem_ctx, &session_list);
908 for (; resume_handle < *total_entries; resume_handle++) {
909 uint32 num_files;
910 uint32 connect_time;
911 struct passwd *pw = getpwnam(session_list[resume_handle].username);
912 bool guest;
914 if ( !pw ) {
915 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
916 session_list[resume_handle].username));
917 continue;
920 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
921 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
922 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
924 ctr1->array = talloc_realloc(p->mem_ctx,
925 ctr1->array,
926 struct srvsvc_NetSessInfo1,
927 num_entries+1);
928 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
930 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
931 ctr1->array[num_entries].user = session_list[resume_handle].username;
932 ctr1->array[num_entries].num_open = num_files;
933 ctr1->array[num_entries].time = connect_time;
934 ctr1->array[num_entries].idle_time = 0;
935 ctr1->array[num_entries].user_flags = guest;
937 num_entries++;
940 ctr1->count = num_entries;
942 if (resume_handle_p) {
943 if (*resume_handle_p >= *total_entries) {
944 *resume_handle_p = 0;
945 } else {
946 *resume_handle_p = resume_handle;
950 return WERR_OK;
953 /*******************************************************************
954 fill in a conn info level 0 structure.
955 ********************************************************************/
957 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
958 uint32_t *resume_handle_p,
959 uint32_t *total_entries)
961 uint32_t num_entries = 0;
962 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
964 DEBUG(5,("init_srv_conn_info_0\n"));
966 if (ctr0 == NULL) {
967 if (resume_handle_p) {
968 *resume_handle_p = 0;
970 return WERR_OK;
973 *total_entries = 1;
975 ZERO_STRUCTP(ctr0);
977 for (; resume_handle < *total_entries; resume_handle++) {
979 ctr0->array = talloc_realloc(talloc_tos(),
980 ctr0->array,
981 struct srvsvc_NetConnInfo0,
982 num_entries+1);
983 if (!ctr0->array) {
984 return WERR_NOMEM;
987 ctr0->array[num_entries].conn_id = *total_entries;
989 /* move on to creating next connection */
990 num_entries++;
993 ctr0->count = num_entries;
994 *total_entries = num_entries;
996 if (resume_handle_p) {
997 if (*resume_handle_p >= *total_entries) {
998 *resume_handle_p = 0;
999 } else {
1000 *resume_handle_p = resume_handle;
1004 return WERR_OK;
1007 /*******************************************************************
1008 fill in a conn info level 1 structure.
1009 ********************************************************************/
1011 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
1012 uint32_t *resume_handle_p,
1013 uint32_t *total_entries)
1015 uint32_t num_entries = 0;
1016 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1018 DEBUG(5,("init_srv_conn_info_1\n"));
1020 if (ctr1 == NULL) {
1021 if (resume_handle_p) {
1022 *resume_handle_p = 0;
1024 return WERR_OK;
1027 *total_entries = 1;
1029 ZERO_STRUCTP(ctr1);
1031 for (; resume_handle < *total_entries; resume_handle++) {
1033 ctr1->array = talloc_realloc(talloc_tos(),
1034 ctr1->array,
1035 struct srvsvc_NetConnInfo1,
1036 num_entries+1);
1037 if (!ctr1->array) {
1038 return WERR_NOMEM;
1041 ctr1->array[num_entries].conn_id = *total_entries;
1042 ctr1->array[num_entries].conn_type = 0x3;
1043 ctr1->array[num_entries].num_open = 1;
1044 ctr1->array[num_entries].num_users = 1;
1045 ctr1->array[num_entries].conn_time = 3;
1046 ctr1->array[num_entries].user = "dummy_user";
1047 ctr1->array[num_entries].share = "IPC$";
1049 /* move on to creating next connection */
1050 num_entries++;
1053 ctr1->count = num_entries;
1054 *total_entries = num_entries;
1056 if (resume_handle_p) {
1057 if (*resume_handle_p >= *total_entries) {
1058 *resume_handle_p = 0;
1059 } else {
1060 *resume_handle_p = resume_handle;
1064 return WERR_OK;
1067 /*******************************************************************
1068 _srvsvc_NetFileEnum
1069 *******************************************************************/
1071 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1072 struct srvsvc_NetFileEnum *r)
1074 TALLOC_CTX *ctx = NULL;
1075 struct srvsvc_NetFileCtr3 *ctr3;
1076 uint32_t resume_hnd = 0;
1077 WERROR werr;
1079 switch (r->in.info_ctr->level) {
1080 case 3:
1081 break;
1082 default:
1083 return WERR_UNKNOWN_LEVEL;
1086 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1087 p->session_info->security_token)) {
1088 DEBUG(1, ("Enumerating files only allowed for "
1089 "administrators\n"));
1090 return WERR_ACCESS_DENIED;
1093 ctx = talloc_tos();
1094 ctr3 = r->in.info_ctr->ctr.ctr3;
1095 if (!ctr3) {
1096 werr = WERR_INVALID_PARAM;
1097 goto done;
1100 /* TODO -- Windows enumerates
1101 (b) active pipes
1102 (c) open directories and files */
1104 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1105 if (!W_ERROR_IS_OK(werr)) {
1106 goto done;
1109 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1110 if (!W_ERROR_IS_OK(werr)) {
1111 goto done;
1114 *r->out.totalentries = ctr3->count;
1115 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1116 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1118 werr = WERR_OK;
1120 done:
1121 return werr;
1124 /*******************************************************************
1125 _srvsvc_NetSrvGetInfo
1126 ********************************************************************/
1128 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1129 struct srvsvc_NetSrvGetInfo *r)
1131 WERROR status = WERR_OK;
1133 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1135 if (!pipe_access_check(p)) {
1136 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1137 return WERR_ACCESS_DENIED;
1140 switch (r->in.level) {
1142 /* Technically level 102 should only be available to
1143 Administrators but there isn't anything super-secret
1144 here, as most of it is made up. */
1146 case 102: {
1147 struct srvsvc_NetSrvInfo102 *info102;
1149 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1150 if (!info102) {
1151 return WERR_NOMEM;
1154 info102->platform_id = PLATFORM_ID_NT;
1155 info102->server_name = lp_netbios_name();
1156 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1157 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1158 info102->server_type = lp_default_server_announce();
1159 info102->comment = string_truncate(lp_serverstring(talloc_tos()),
1160 MAX_SERVER_STRING_LENGTH);
1161 info102->users = 0xffffffff;
1162 info102->disc = 0xf;
1163 info102->hidden = 0;
1164 info102->announce = 240;
1165 info102->anndelta = 3000;
1166 info102->licenses = 100000;
1167 info102->userpath = "C:\\";
1169 r->out.info->info102 = info102;
1170 break;
1172 case 101: {
1173 struct srvsvc_NetSrvInfo101 *info101;
1175 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1176 if (!info101) {
1177 return WERR_NOMEM;
1180 info101->platform_id = PLATFORM_ID_NT;
1181 info101->server_name = lp_netbios_name();
1182 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1183 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1184 info101->server_type = lp_default_server_announce();
1185 info101->comment = string_truncate(lp_serverstring(talloc_tos()),
1186 MAX_SERVER_STRING_LENGTH);
1188 r->out.info->info101 = info101;
1189 break;
1191 case 100: {
1192 struct srvsvc_NetSrvInfo100 *info100;
1194 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1195 if (!info100) {
1196 return WERR_NOMEM;
1199 info100->platform_id = PLATFORM_ID_NT;
1200 info100->server_name = lp_netbios_name();
1202 r->out.info->info100 = info100;
1204 break;
1206 default:
1207 status = WERR_UNKNOWN_LEVEL;
1208 break;
1211 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1213 return status;
1216 /*******************************************************************
1217 _srvsvc_NetSrvSetInfo
1218 ********************************************************************/
1220 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1221 struct srvsvc_NetSrvSetInfo *r)
1223 WERROR status = WERR_OK;
1225 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1227 /* Set up the net server set info structure. */
1229 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1231 return status;
1234 /*******************************************************************
1235 _srvsvc_NetConnEnum
1236 ********************************************************************/
1238 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1239 struct srvsvc_NetConnEnum *r)
1241 WERROR werr;
1243 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1245 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1246 p->session_info->security_token)) {
1247 DEBUG(1, ("Enumerating connections only allowed for "
1248 "administrators\n"));
1249 return WERR_ACCESS_DENIED;
1252 switch (r->in.info_ctr->level) {
1253 case 0:
1254 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1255 r->in.resume_handle,
1256 r->out.totalentries);
1257 break;
1258 case 1:
1259 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1260 r->in.resume_handle,
1261 r->out.totalentries);
1262 break;
1263 default:
1264 return WERR_UNKNOWN_LEVEL;
1267 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1269 return werr;
1272 /*******************************************************************
1273 _srvsvc_NetSessEnum
1274 ********************************************************************/
1276 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1277 struct srvsvc_NetSessEnum *r)
1279 WERROR werr;
1281 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1283 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1284 p->session_info->security_token)) {
1285 DEBUG(1, ("Enumerating sessions only allowed for "
1286 "administrators\n"));
1287 return WERR_ACCESS_DENIED;
1290 switch (r->in.info_ctr->level) {
1291 case 0:
1292 werr = init_srv_sess_info_0(p,
1293 r->in.info_ctr->ctr.ctr0,
1294 r->in.resume_handle,
1295 r->out.totalentries);
1296 break;
1297 case 1:
1298 werr = init_srv_sess_info_1(p,
1299 r->in.info_ctr->ctr.ctr1,
1300 r->in.resume_handle,
1301 r->out.totalentries);
1302 break;
1303 default:
1304 return WERR_UNKNOWN_LEVEL;
1307 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1309 return werr;
1312 /*******************************************************************
1313 _srvsvc_NetSessDel
1314 ********************************************************************/
1316 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1317 struct srvsvc_NetSessDel *r)
1319 struct sessionid *session_list;
1320 int num_sessions, snum;
1321 const char *username;
1322 const char *machine;
1323 bool not_root = False;
1324 WERROR werr;
1326 username = r->in.user;
1327 machine = r->in.client;
1329 /* strip leading backslashes if any */
1330 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1331 machine += 2;
1334 num_sessions = list_sessions(p->mem_ctx, &session_list);
1336 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1338 werr = WERR_ACCESS_DENIED;
1340 /* fail out now if you are not root or not a domain admin */
1342 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1343 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1344 DOMAIN_RID_ADMINS))) {
1346 goto done;
1349 for (snum = 0; snum < num_sessions; snum++) {
1351 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1352 strequal(session_list[snum].remote_machine, machine)) {
1354 NTSTATUS ntstat;
1356 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1357 not_root = True;
1358 become_root();
1361 ntstat = messaging_send(p->msg_ctx,
1362 session_list[snum].pid,
1363 MSG_SHUTDOWN, &data_blob_null);
1365 if (NT_STATUS_IS_OK(ntstat))
1366 werr = WERR_OK;
1368 if (not_root)
1369 unbecome_root();
1373 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1375 done:
1377 return werr;
1380 /*******************************************************************
1381 _srvsvc_NetShareEnumAll
1382 ********************************************************************/
1384 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1385 struct srvsvc_NetShareEnumAll *r)
1387 WERROR werr;
1389 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1391 if (!pipe_access_check(p)) {
1392 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1393 return WERR_ACCESS_DENIED;
1396 /* Create the list of shares for the response. */
1397 werr = init_srv_share_info_ctr(p,
1398 r->in.info_ctr,
1399 r->in.resume_handle,
1400 r->out.totalentries,
1401 true);
1403 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1405 return werr;
1408 /*******************************************************************
1409 _srvsvc_NetShareEnum
1410 ********************************************************************/
1412 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1413 struct srvsvc_NetShareEnum *r)
1415 WERROR werr;
1417 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1419 if (!pipe_access_check(p)) {
1420 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1421 return WERR_ACCESS_DENIED;
1424 /* Create the list of shares for the response. */
1425 werr = init_srv_share_info_ctr(p,
1426 r->in.info_ctr,
1427 r->in.resume_handle,
1428 r->out.totalentries,
1429 false);
1431 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1433 return werr;
1436 /*******************************************************************
1437 _srvsvc_NetShareGetInfo
1438 ********************************************************************/
1440 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1441 struct srvsvc_NetShareGetInfo *r)
1443 WERROR status = WERR_OK;
1444 char *share_name = NULL;
1445 int snum;
1446 union srvsvc_NetShareInfo *info = r->out.info;
1448 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1450 if (!r->in.share_name) {
1451 return WERR_INVALID_NAME;
1454 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1455 if (!share_name) {
1456 return WERR_NOMEM;
1458 if (snum < 0) {
1459 return WERR_INVALID_NAME;
1462 switch (r->in.level) {
1463 case 0:
1464 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1465 W_ERROR_HAVE_NO_MEMORY(info->info0);
1466 init_srv_share_info_0(p, info->info0, snum);
1467 break;
1468 case 1:
1469 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1470 W_ERROR_HAVE_NO_MEMORY(info->info1);
1471 init_srv_share_info_1(p, info->info1, snum);
1472 break;
1473 case 2:
1474 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1475 W_ERROR_HAVE_NO_MEMORY(info->info2);
1476 init_srv_share_info_2(p, info->info2, snum);
1477 break;
1478 case 501:
1479 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1480 W_ERROR_HAVE_NO_MEMORY(info->info501);
1481 init_srv_share_info_501(p, info->info501, snum);
1482 break;
1483 case 502:
1484 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1485 W_ERROR_HAVE_NO_MEMORY(info->info502);
1486 init_srv_share_info_502(p, info->info502, snum);
1487 break;
1488 case 1004:
1489 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1490 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1491 init_srv_share_info_1004(p, info->info1004, snum);
1492 break;
1493 case 1005:
1494 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1495 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1496 init_srv_share_info_1005(p, info->info1005, snum);
1497 break;
1498 case 1006:
1499 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1500 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1501 init_srv_share_info_1006(p, info->info1006, snum);
1502 break;
1503 case 1007:
1504 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1505 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1506 init_srv_share_info_1007(p, info->info1007, snum);
1507 break;
1508 case 1501:
1509 init_srv_share_info_1501(p, &info->info1501, snum);
1510 break;
1511 default:
1512 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1513 r->in.level));
1514 status = WERR_UNKNOWN_LEVEL;
1515 break;
1518 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1520 return status;
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 if (!r->in.share_name) {
1547 return WERR_INVALID_NAME;
1550 if (r->out.parm_error) {
1551 *r->out.parm_error = 0;
1554 if ( strequal(r->in.share_name,"IPC$")
1555 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1556 || strequal(r->in.share_name,"global") )
1558 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1559 "modified by a remote user.\n",
1560 r->in.share_name ));
1561 return WERR_ACCESS_DENIED;
1564 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1565 if (!share_name) {
1566 return WERR_NOMEM;
1569 /* Does this share exist ? */
1570 if (snum < 0)
1571 return WERR_NET_NAME_NOT_FOUND;
1573 /* No change to printer shares. */
1574 if (lp_print_ok(snum))
1575 return WERR_ACCESS_DENIED;
1577 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1579 /* fail out now if you are not root and not a disk op */
1581 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1582 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1583 "SeDiskOperatorPrivilege privilege needed to modify "
1584 "share %s\n",
1585 (unsigned int)p->session_info->unix_token->uid,
1586 share_name ));
1587 return WERR_ACCESS_DENIED;
1590 switch (r->in.level) {
1591 case 1:
1592 pathname = lp_pathname(ctx, snum);
1593 comment = talloc_strdup(ctx, info->info1->comment);
1594 type = info->info1->type;
1595 psd = NULL;
1596 break;
1597 case 2:
1598 comment = talloc_strdup(ctx, info->info2->comment);
1599 pathname = info->info2->path;
1600 type = info->info2->type;
1601 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1602 0 : info->info2->max_users;
1603 psd = NULL;
1604 break;
1605 #if 0
1606 /* not supported on set but here for completeness */
1607 case 501:
1608 comment = talloc_strdup(ctx, info->info501->comment);
1609 type = info->info501->type;
1610 psd = NULL;
1611 break;
1612 #endif
1613 case 502:
1614 comment = talloc_strdup(ctx, info->info502->comment);
1615 pathname = info->info502->path;
1616 type = info->info502->type;
1617 psd = info->info502->sd_buf.sd;
1618 map_generic_share_sd_bits(psd);
1619 break;
1620 case 1004:
1621 pathname = lp_pathname(ctx, snum);
1622 comment = talloc_strdup(ctx, info->info1004->comment);
1623 type = STYPE_DISKTREE;
1624 break;
1625 case 1005:
1626 /* XP re-sets the csc policy even if it wasn't changed by the
1627 user, so we must compare it to see if it's what is set in
1628 smb.conf, so that we can contine other ops like setting
1629 ACLs on a share */
1630 if (((info->info1005->dfs_flags &
1631 SHARE_1005_CSC_POLICY_MASK) >>
1632 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1633 return WERR_OK;
1634 else {
1635 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1636 return WERR_ACCESS_DENIED;
1638 case 1006:
1639 case 1007:
1640 return WERR_ACCESS_DENIED;
1641 case 1501:
1642 pathname = lp_pathname(ctx, snum);
1643 comment = lp_comment(ctx, snum);
1644 psd = info->info1501->sd;
1645 map_generic_share_sd_bits(psd);
1646 type = STYPE_DISKTREE;
1647 break;
1648 default:
1649 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1650 r->in.level));
1651 return WERR_UNKNOWN_LEVEL;
1654 /* We can only modify disk shares. */
1655 if (type != STYPE_DISKTREE) {
1656 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1657 "disk share\n",
1658 share_name ));
1659 return WERR_ACCESS_DENIED;
1662 if (comment == NULL) {
1663 return WERR_NOMEM;
1666 /* Check if the pathname is valid. */
1667 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1668 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1669 pathname ));
1670 return WERR_OBJECT_PATH_INVALID;
1673 /* Ensure share name, pathname and comment don't contain '"' characters. */
1674 string_replace(share_name, '"', ' ');
1675 string_replace(path, '"', ' ');
1676 string_replace(comment, '"', ' ');
1678 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1679 lp_change_share_cmd(talloc_tos()) ? lp_change_share_cmd(talloc_tos()) : "NULL" ));
1681 /* Only call modify function if something changed. */
1683 if (strcmp(path, lp_pathname(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1684 || (lp_max_connections(snum) != max_connections)) {
1685 if (!lp_change_share_cmd(talloc_tos()) || !*lp_change_share_cmd(talloc_tos())) {
1686 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1687 return WERR_ACCESS_DENIED;
1690 command = talloc_asprintf(p->mem_ctx,
1691 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1692 lp_change_share_cmd(talloc_tos()),
1693 get_dyn_CONFIGFILE(),
1694 share_name,
1695 path,
1696 comment ? comment : "",
1697 max_connections);
1698 if (!command) {
1699 return WERR_NOMEM;
1702 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1704 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1706 if (is_disk_op)
1707 become_root();
1709 if ( (ret = smbrun(command, NULL)) == 0 ) {
1710 /* Tell everyone we updated smb.conf. */
1711 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1712 NULL, 0, NULL);
1715 if ( is_disk_op )
1716 unbecome_root();
1718 /********* END SeDiskOperatorPrivilege BLOCK *********/
1720 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1721 command, ret ));
1723 TALLOC_FREE(command);
1725 if ( ret != 0 )
1726 return WERR_ACCESS_DENIED;
1727 } else {
1728 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1729 share_name ));
1732 /* Replace SD if changed. */
1733 if (psd) {
1734 struct security_descriptor *old_sd;
1735 size_t sd_size;
1737 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1739 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1740 if (!set_share_security(share_name, psd))
1741 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1742 share_name ));
1746 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1748 return WERR_OK;
1751 /*******************************************************************
1752 _srvsvc_NetShareAdd.
1753 Call 'add_share_command "sharename" "pathname"
1754 "comment" "max connections = "
1755 ********************************************************************/
1757 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1758 struct srvsvc_NetShareAdd *r)
1760 char *command = NULL;
1761 char *share_name_in = NULL;
1762 char *share_name = NULL;
1763 char *comment = NULL;
1764 char *pathname = NULL;
1765 int type;
1766 int snum;
1767 int ret;
1768 char *path;
1769 struct security_descriptor *psd = NULL;
1770 bool is_disk_op;
1771 int max_connections = 0;
1772 TALLOC_CTX *ctx = p->mem_ctx;
1774 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1776 if (r->out.parm_error) {
1777 *r->out.parm_error = 0;
1780 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1782 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1783 return WERR_ACCESS_DENIED;
1785 if (!lp_add_share_cmd(talloc_tos()) || !*lp_add_share_cmd(talloc_tos())) {
1786 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1787 return WERR_ACCESS_DENIED;
1790 switch (r->in.level) {
1791 case 0:
1792 /* No path. Not enough info in a level 0 to do anything. */
1793 return WERR_ACCESS_DENIED;
1794 case 1:
1795 /* Not enough info in a level 1 to do anything. */
1796 return WERR_ACCESS_DENIED;
1797 case 2:
1798 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1799 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1800 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1801 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1802 0 : r->in.info->info2->max_users;
1803 type = r->in.info->info2->type;
1804 break;
1805 case 501:
1806 /* No path. Not enough info in a level 501 to do anything. */
1807 return WERR_ACCESS_DENIED;
1808 case 502:
1809 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1810 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1811 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1812 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1813 0 : r->in.info->info502->max_users;
1814 type = r->in.info->info502->type;
1815 psd = r->in.info->info502->sd_buf.sd;
1816 map_generic_share_sd_bits(psd);
1817 break;
1819 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1821 case 1004:
1822 case 1005:
1823 case 1006:
1824 case 1007:
1825 return WERR_ACCESS_DENIED;
1826 case 1501:
1827 /* DFS only level. */
1828 return WERR_ACCESS_DENIED;
1829 default:
1830 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1831 r->in.level));
1832 return WERR_UNKNOWN_LEVEL;
1835 /* check for invalid share names */
1837 if (!share_name_in || !validate_net_name(share_name_in,
1838 INVALID_SHARENAME_CHARS,
1839 strlen(share_name_in))) {
1840 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1841 share_name_in ? share_name_in : ""));
1842 return WERR_INVALID_NAME;
1845 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1846 || (lp_enable_asu_support() &&
1847 strequal(share_name_in,"ADMIN$"))) {
1848 return WERR_ACCESS_DENIED;
1851 snum = find_service(ctx, share_name_in, &share_name);
1852 if (!share_name) {
1853 return WERR_NOMEM;
1856 /* Share already exists. */
1857 if (snum >= 0) {
1858 return WERR_FILE_EXISTS;
1861 /* We can only add disk shares. */
1862 if (type != STYPE_DISKTREE) {
1863 return WERR_ACCESS_DENIED;
1866 /* Check if the pathname is valid. */
1867 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1868 return WERR_OBJECT_PATH_INVALID;
1871 /* Ensure share name, pathname and comment don't contain '"' characters. */
1872 string_replace(share_name_in, '"', ' ');
1873 string_replace(share_name, '"', ' ');
1874 string_replace(path, '"', ' ');
1875 if (comment) {
1876 string_replace(comment, '"', ' ');
1879 command = talloc_asprintf(ctx,
1880 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1881 lp_add_share_cmd(talloc_tos()),
1882 get_dyn_CONFIGFILE(),
1883 share_name_in,
1884 path,
1885 comment ? comment : "",
1886 max_connections);
1887 if (!command) {
1888 return WERR_NOMEM;
1891 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1893 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1895 if ( is_disk_op )
1896 become_root();
1898 /* FIXME: use libnetconf here - gd */
1900 if ( (ret = smbrun(command, NULL)) == 0 ) {
1901 /* Tell everyone we updated smb.conf. */
1902 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1903 NULL);
1906 if ( is_disk_op )
1907 unbecome_root();
1909 /********* END SeDiskOperatorPrivilege BLOCK *********/
1911 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1912 command, ret ));
1914 TALLOC_FREE(command);
1916 if ( ret != 0 )
1917 return WERR_ACCESS_DENIED;
1919 if (psd) {
1920 /* Note we use share_name here, not share_name_in as
1921 we need a canonicalized name for setting security. */
1922 if (!set_share_security(share_name, psd)) {
1923 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1924 share_name ));
1929 * We don't call reload_services() here, the message will
1930 * cause this to be done before the next packet is read
1931 * from the client. JRA.
1934 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1936 return WERR_OK;
1939 /*******************************************************************
1940 _srvsvc_NetShareDel
1941 Call "delete share command" with the share name as
1942 a parameter.
1943 ********************************************************************/
1945 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
1946 struct srvsvc_NetShareDel *r)
1948 char *command = NULL;
1949 char *share_name = NULL;
1950 int ret;
1951 int snum;
1952 bool is_disk_op;
1953 struct share_params *params;
1954 TALLOC_CTX *ctx = p->mem_ctx;
1956 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1958 if (!r->in.share_name) {
1959 return WERR_NET_NAME_NOT_FOUND;
1962 if ( strequal(r->in.share_name,"IPC$")
1963 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1964 || strequal(r->in.share_name,"global") )
1966 return WERR_ACCESS_DENIED;
1969 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1970 if (!share_name) {
1971 return WERR_NOMEM;
1974 if (snum < 0) {
1975 return WERR_NO_SUCH_SHARE;
1978 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1979 return WERR_NO_SUCH_SHARE;
1982 /* No change to printer shares. */
1983 if (lp_print_ok(snum))
1984 return WERR_ACCESS_DENIED;
1986 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1988 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1989 return WERR_ACCESS_DENIED;
1991 if (!lp_delete_share_cmd(talloc_tos()) || !*lp_delete_share_cmd(talloc_tos())) {
1992 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1993 return WERR_ACCESS_DENIED;
1996 command = talloc_asprintf(ctx,
1997 "%s \"%s\" \"%s\"",
1998 lp_delete_share_cmd(talloc_tos()),
1999 get_dyn_CONFIGFILE(),
2000 lp_servicename(talloc_tos(), snum));
2001 if (!command) {
2002 return WERR_NOMEM;
2005 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2007 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2009 if ( is_disk_op )
2010 become_root();
2012 if ( (ret = smbrun(command, NULL)) == 0 ) {
2013 /* Tell everyone we updated smb.conf. */
2014 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2015 NULL);
2018 if ( is_disk_op )
2019 unbecome_root();
2021 /********* END SeDiskOperatorPrivilege BLOCK *********/
2023 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2025 if ( ret != 0 )
2026 return WERR_ACCESS_DENIED;
2028 /* Delete the SD in the database. */
2029 delete_share_security(lp_servicename(talloc_tos(), params->service));
2031 lp_killservice(params->service);
2033 return WERR_OK;
2036 /*******************************************************************
2037 _srvsvc_NetShareDelSticky
2038 ********************************************************************/
2040 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2041 struct srvsvc_NetShareDelSticky *r)
2043 struct srvsvc_NetShareDel q;
2045 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2047 q.in.server_unc = r->in.server_unc;
2048 q.in.share_name = r->in.share_name;
2049 q.in.reserved = r->in.reserved;
2051 return _srvsvc_NetShareDel(p, &q);
2054 /*******************************************************************
2055 _srvsvc_NetRemoteTOD
2056 ********************************************************************/
2058 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2059 struct srvsvc_NetRemoteTOD *r)
2061 struct srvsvc_NetRemoteTODInfo *tod;
2062 struct tm *t;
2063 time_t unixdate = time(NULL);
2065 /* We do this call first as if we do it *after* the gmtime call
2066 it overwrites the pointed-to values. JRA */
2068 uint32 zone = get_time_zone(unixdate)/60;
2070 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2072 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2073 return WERR_NOMEM;
2075 *r->out.info = tod;
2077 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2079 t = gmtime(&unixdate);
2081 /* set up the */
2082 tod->elapsed = unixdate;
2083 tod->msecs = 0;
2084 tod->hours = t->tm_hour;
2085 tod->mins = t->tm_min;
2086 tod->secs = t->tm_sec;
2087 tod->hunds = 0;
2088 tod->timezone = zone;
2089 tod->tinterval = 10000;
2090 tod->day = t->tm_mday;
2091 tod->month = t->tm_mon + 1;
2092 tod->year = 1900+t->tm_year;
2093 tod->weekday = t->tm_wday;
2095 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2097 return WERR_OK;
2100 /***********************************************************************************
2101 _srvsvc_NetGetFileSecurity
2102 Win9x NT tools get security descriptor.
2103 ***********************************************************************************/
2105 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2106 struct srvsvc_NetGetFileSecurity *r)
2108 struct smb_filename *smb_fname = NULL;
2109 struct security_descriptor *psd = NULL;
2110 size_t sd_size;
2111 char *servicename = NULL;
2112 SMB_STRUCT_STAT st;
2113 NTSTATUS nt_status;
2114 WERROR werr;
2115 connection_struct *conn = NULL;
2116 struct sec_desc_buf *sd_buf = NULL;
2117 files_struct *fsp = NULL;
2118 int snum;
2119 char *oldcwd = NULL;
2121 ZERO_STRUCT(st);
2123 if (!r->in.share) {
2124 werr = WERR_NET_NAME_NOT_FOUND;
2125 goto error_exit;
2127 snum = find_service(talloc_tos(), r->in.share, &servicename);
2128 if (!servicename) {
2129 werr = WERR_NOMEM;
2130 goto error_exit;
2132 if (snum == -1) {
2133 DEBUG(10, ("Could not find service %s\n", servicename));
2134 werr = WERR_NET_NAME_NOT_FOUND;
2135 goto error_exit;
2138 nt_status = create_conn_struct(talloc_tos(),
2139 server_event_context(),
2140 server_messaging_context(),
2141 &conn,
2142 snum, lp_pathname(talloc_tos(), snum),
2143 p->session_info, &oldcwd);
2144 if (!NT_STATUS_IS_OK(nt_status)) {
2145 DEBUG(10, ("create_conn_struct failed: %s\n",
2146 nt_errstr(nt_status)));
2147 werr = ntstatus_to_werror(nt_status);
2148 goto error_exit;
2151 nt_status = filename_convert(talloc_tos(),
2152 conn,
2153 false,
2154 r->in.file,
2156 NULL,
2157 &smb_fname);
2158 if (!NT_STATUS_IS_OK(nt_status)) {
2159 werr = ntstatus_to_werror(nt_status);
2160 goto error_exit;
2163 nt_status = SMB_VFS_CREATE_FILE(
2164 conn, /* conn */
2165 NULL, /* req */
2166 0, /* root_dir_fid */
2167 smb_fname, /* fname */
2168 FILE_READ_ATTRIBUTES, /* access_mask */
2169 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2170 FILE_OPEN, /* create_disposition*/
2171 0, /* create_options */
2172 0, /* file_attributes */
2173 INTERNAL_OPEN_ONLY, /* oplock_request */
2174 0, /* allocation_size */
2175 0, /* private_flags */
2176 NULL, /* sd */
2177 NULL, /* ea_list */
2178 &fsp, /* result */
2179 NULL); /* pinfo */
2181 if (!NT_STATUS_IS_OK(nt_status)) {
2182 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2183 smb_fname_str_dbg(smb_fname)));
2184 werr = ntstatus_to_werror(nt_status);
2185 goto error_exit;
2188 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2189 (SECINFO_OWNER
2190 |SECINFO_GROUP
2191 |SECINFO_DACL), &psd);
2193 if (!NT_STATUS_IS_OK(nt_status)) {
2194 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2195 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2196 werr = ntstatus_to_werror(nt_status);
2197 goto error_exit;
2200 sd_size = ndr_size_security_descriptor(psd, 0);
2202 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2203 if (!sd_buf) {
2204 werr = WERR_NOMEM;
2205 goto error_exit;
2208 sd_buf->sd_size = sd_size;
2209 sd_buf->sd = psd;
2211 *r->out.sd_buf = sd_buf;
2213 psd->dacl->revision = NT4_ACL_REVISION;
2215 close_file(NULL, fsp, NORMAL_CLOSE);
2216 vfs_ChDir(conn, oldcwd);
2217 SMB_VFS_DISCONNECT(conn);
2218 conn_free(conn);
2219 werr = WERR_OK;
2220 goto done;
2222 error_exit:
2224 if (fsp) {
2225 close_file(NULL, fsp, NORMAL_CLOSE);
2228 if (oldcwd) {
2229 vfs_ChDir(conn, oldcwd);
2232 if (conn) {
2233 SMB_VFS_DISCONNECT(conn);
2234 conn_free(conn);
2237 done:
2238 TALLOC_FREE(smb_fname);
2240 return werr;
2243 /***********************************************************************************
2244 _srvsvc_NetSetFileSecurity
2245 Win9x NT tools set security descriptor.
2246 ***********************************************************************************/
2248 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2249 struct srvsvc_NetSetFileSecurity *r)
2251 struct smb_filename *smb_fname = NULL;
2252 char *servicename = NULL;
2253 files_struct *fsp = NULL;
2254 SMB_STRUCT_STAT st;
2255 NTSTATUS nt_status;
2256 WERROR werr;
2257 connection_struct *conn = NULL;
2258 int snum;
2259 char *oldcwd = NULL;
2260 struct security_descriptor *psd = NULL;
2261 uint32_t security_info_sent = 0;
2263 ZERO_STRUCT(st);
2265 if (!r->in.share) {
2266 werr = WERR_NET_NAME_NOT_FOUND;
2267 goto error_exit;
2270 snum = find_service(talloc_tos(), r->in.share, &servicename);
2271 if (!servicename) {
2272 werr = WERR_NOMEM;
2273 goto error_exit;
2276 if (snum == -1) {
2277 DEBUG(10, ("Could not find service %s\n", servicename));
2278 werr = WERR_NET_NAME_NOT_FOUND;
2279 goto error_exit;
2282 nt_status = create_conn_struct(talloc_tos(),
2283 server_event_context(),
2284 server_messaging_context(),
2285 &conn,
2286 snum, lp_pathname(talloc_tos(), snum),
2287 p->session_info, &oldcwd);
2288 if (!NT_STATUS_IS_OK(nt_status)) {
2289 DEBUG(10, ("create_conn_struct failed: %s\n",
2290 nt_errstr(nt_status)));
2291 werr = ntstatus_to_werror(nt_status);
2292 goto error_exit;
2295 nt_status = filename_convert(talloc_tos(),
2296 conn,
2297 false,
2298 r->in.file,
2300 NULL,
2301 &smb_fname);
2302 if (!NT_STATUS_IS_OK(nt_status)) {
2303 werr = ntstatus_to_werror(nt_status);
2304 goto error_exit;
2307 nt_status = SMB_VFS_CREATE_FILE(
2308 conn, /* conn */
2309 NULL, /* req */
2310 0, /* root_dir_fid */
2311 smb_fname, /* fname */
2312 FILE_WRITE_ATTRIBUTES, /* access_mask */
2313 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2314 FILE_OPEN, /* create_disposition*/
2315 0, /* create_options */
2316 0, /* file_attributes */
2317 INTERNAL_OPEN_ONLY, /* oplock_request */
2318 0, /* allocation_size */
2319 0, /* private_flags */
2320 NULL, /* sd */
2321 NULL, /* ea_list */
2322 &fsp, /* result */
2323 NULL); /* pinfo */
2325 if (!NT_STATUS_IS_OK(nt_status)) {
2326 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2327 smb_fname_str_dbg(smb_fname)));
2328 werr = ntstatus_to_werror(nt_status);
2329 goto error_exit;
2332 psd = r->in.sd_buf->sd;
2333 security_info_sent = r->in.securityinformation;
2335 if (psd->owner_sid==0) {
2336 security_info_sent &= ~SECINFO_OWNER;
2338 if (psd->group_sid==0) {
2339 security_info_sent &= ~SECINFO_GROUP;
2341 if (psd->sacl==0) {
2342 security_info_sent &= ~SECINFO_SACL;
2344 if (psd->dacl==0) {
2345 security_info_sent &= ~SECINFO_DACL;
2348 /* Convert all the generic bits. */
2349 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2350 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2352 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2353 security_info_sent,
2354 psd);
2356 if (!NT_STATUS_IS_OK(nt_status) ) {
2357 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2358 "on file %s\n", r->in.share));
2359 werr = WERR_ACCESS_DENIED;
2360 goto error_exit;
2363 close_file(NULL, fsp, NORMAL_CLOSE);
2364 vfs_ChDir(conn, oldcwd);
2365 SMB_VFS_DISCONNECT(conn);
2366 conn_free(conn);
2367 werr = WERR_OK;
2368 goto done;
2370 error_exit:
2372 if (fsp) {
2373 close_file(NULL, fsp, NORMAL_CLOSE);
2376 if (oldcwd) {
2377 vfs_ChDir(conn, oldcwd);
2380 if (conn) {
2381 SMB_VFS_DISCONNECT(conn);
2382 conn_free(conn);
2385 done:
2386 TALLOC_FREE(smb_fname);
2388 return werr;
2391 /***********************************************************************************
2392 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2393 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2394 These disks would the disks listed by this function.
2395 Users could then create shares relative to these disks. Watch out for moving these disks around.
2396 "Nigel Williams" <nigel@veritas.com>.
2397 ***********************************************************************************/
2399 static const char *server_disks[] = {"C:"};
2401 static uint32 get_server_disk_count(void)
2403 return sizeof(server_disks)/sizeof(server_disks[0]);
2406 static uint32 init_server_disk_enum(uint32 *resume)
2408 uint32 server_disk_count = get_server_disk_count();
2410 /*resume can be an offset into the list for now*/
2412 if(*resume & 0x80000000)
2413 *resume = 0;
2415 if(*resume > server_disk_count)
2416 *resume = server_disk_count;
2418 return server_disk_count - *resume;
2421 static const char *next_server_disk_enum(uint32 *resume)
2423 const char *disk;
2425 if(init_server_disk_enum(resume) == 0)
2426 return NULL;
2428 disk = server_disks[*resume];
2430 (*resume)++;
2432 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2434 return disk;
2437 /********************************************************************
2438 _srvsvc_NetDiskEnum
2439 ********************************************************************/
2441 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2442 struct srvsvc_NetDiskEnum *r)
2444 uint32 i;
2445 const char *disk_name;
2446 TALLOC_CTX *ctx = p->mem_ctx;
2447 WERROR werr;
2448 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2450 werr = WERR_OK;
2452 *r->out.totalentries = init_server_disk_enum(&resume);
2454 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2455 MAX_SERVER_DISK_ENTRIES);
2456 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2458 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2460 r->out.info->count = 0;
2462 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2464 r->out.info->count++;
2466 /*copy disk name into a unicode string*/
2468 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2469 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2472 /* add a terminating null string. Is this there if there is more data to come? */
2474 r->out.info->count++;
2476 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2477 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2479 if (r->out.resume_handle) {
2480 *r->out.resume_handle = resume;
2483 return werr;
2486 /********************************************************************
2487 _srvsvc_NetNameValidate
2488 ********************************************************************/
2490 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2491 struct srvsvc_NetNameValidate *r)
2493 switch (r->in.name_type) {
2494 case 0x9:
2495 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2496 strlen_m(r->in.name)))
2498 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2499 r->in.name));
2500 return WERR_INVALID_NAME;
2502 break;
2504 default:
2505 return WERR_UNKNOWN_LEVEL;
2508 return WERR_OK;
2511 /*******************************************************************
2512 ********************************************************************/
2514 struct enum_file_close_state {
2515 struct srvsvc_NetFileClose *r;
2516 struct messaging_context *msg_ctx;
2519 static void enum_file_close_fn( const struct share_mode_entry *e,
2520 const char *sharepath, const char *fname,
2521 void *private_data )
2523 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2524 struct enum_file_close_state *state =
2525 (struct enum_file_close_state *)private_data;
2526 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2528 if (fid != state->r->in.fid) {
2529 return; /* Not this file. */
2532 if (!process_exists(e->pid) ) {
2533 return;
2536 /* Ok - send the close message. */
2537 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2538 sharepath,
2539 share_mode_str(talloc_tos(), 0, e) ));
2541 share_mode_entry_to_message(msg, e);
2543 state->r->out.result = ntstatus_to_werror(
2544 messaging_send_buf(state->msg_ctx,
2545 e->pid, MSG_SMB_CLOSE_FILE,
2546 (uint8 *)msg,
2547 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2550 /********************************************************************
2551 Close a file given a 32-bit file id.
2552 ********************************************************************/
2554 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2555 struct srvsvc_NetFileClose *r)
2557 struct enum_file_close_state state;
2558 bool is_disk_op;
2560 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2562 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2564 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2565 return WERR_ACCESS_DENIED;
2568 /* enum_file_close_fn sends the close message to
2569 * the relevent smbd process. */
2571 r->out.result = WERR_BADFILE;
2572 state.r = r;
2573 state.msg_ctx = p->msg_ctx;
2574 share_mode_forall(enum_file_close_fn, &state);
2575 return r->out.result;
2578 /********************************************************************
2579 ********************************************************************/
2581 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2582 struct srvsvc_NetCharDevEnum *r)
2584 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2585 return WERR_NOT_SUPPORTED;
2588 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2589 struct srvsvc_NetCharDevGetInfo *r)
2591 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2592 return WERR_NOT_SUPPORTED;
2595 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2596 struct srvsvc_NetCharDevControl *r)
2598 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2599 return WERR_NOT_SUPPORTED;
2602 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2603 struct srvsvc_NetCharDevQEnum *r)
2605 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2606 return WERR_NOT_SUPPORTED;
2609 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2610 struct srvsvc_NetCharDevQGetInfo *r)
2612 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2613 return WERR_NOT_SUPPORTED;
2616 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2617 struct srvsvc_NetCharDevQSetInfo *r)
2619 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2620 return WERR_NOT_SUPPORTED;
2623 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2624 struct srvsvc_NetCharDevQPurge *r)
2626 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2627 return WERR_NOT_SUPPORTED;
2630 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2631 struct srvsvc_NetCharDevQPurgeSelf *r)
2633 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2634 return WERR_NOT_SUPPORTED;
2637 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2638 struct srvsvc_NetFileGetInfo *r)
2640 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2641 return WERR_NOT_SUPPORTED;
2644 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2645 struct srvsvc_NetShareCheck *r)
2647 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2648 return WERR_NOT_SUPPORTED;
2651 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2652 struct srvsvc_NetServerStatisticsGet *r)
2654 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2655 return WERR_NOT_SUPPORTED;
2658 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2659 struct srvsvc_NetTransportAdd *r)
2661 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2662 return WERR_NOT_SUPPORTED;
2665 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2666 struct srvsvc_NetTransportEnum *r)
2668 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2669 return WERR_NOT_SUPPORTED;
2672 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2673 struct srvsvc_NetTransportDel *r)
2675 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2676 return WERR_NOT_SUPPORTED;
2679 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2680 struct srvsvc_NetSetServiceBits *r)
2682 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2683 return WERR_NOT_SUPPORTED;
2686 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2687 struct srvsvc_NetPathType *r)
2689 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2690 return WERR_NOT_SUPPORTED;
2693 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2694 struct srvsvc_NetPathCanonicalize *r)
2696 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2697 return WERR_NOT_SUPPORTED;
2700 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2701 struct srvsvc_NetPathCompare *r)
2703 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2704 return WERR_NOT_SUPPORTED;
2707 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2708 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2710 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2711 return WERR_NOT_SUPPORTED;
2714 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2715 struct srvsvc_NetPRNameCompare *r)
2717 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2718 return WERR_NOT_SUPPORTED;
2721 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2722 struct srvsvc_NetShareDelStart *r)
2724 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2725 return WERR_NOT_SUPPORTED;
2728 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2729 struct srvsvc_NetShareDelCommit *r)
2731 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2732 return WERR_NOT_SUPPORTED;
2735 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2736 struct srvsvc_NetServerTransportAddEx *r)
2738 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2739 return WERR_NOT_SUPPORTED;
2742 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2743 struct srvsvc_NetServerSetServiceBitsEx *r)
2745 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2746 return WERR_NOT_SUPPORTED;
2749 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2750 struct srvsvc_NETRDFSGETVERSION *r)
2752 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2753 return WERR_NOT_SUPPORTED;
2756 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2757 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2759 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2760 return WERR_NOT_SUPPORTED;
2763 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2764 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2766 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2767 return WERR_NOT_SUPPORTED;
2770 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2771 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2773 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2774 return WERR_NOT_SUPPORTED;
2777 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2778 struct srvsvc_NETRDFSSETSERVERINFO *r)
2780 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2781 return WERR_NOT_SUPPORTED;
2784 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2785 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2787 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2788 return WERR_NOT_SUPPORTED;
2791 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2792 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2794 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2795 return WERR_NOT_SUPPORTED;
2798 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2799 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2801 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2802 return WERR_NOT_SUPPORTED;
2805 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2806 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2808 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2809 return WERR_NOT_SUPPORTED;
2812 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2813 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2815 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2816 return WERR_NOT_SUPPORTED;
2819 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2820 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2822 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2823 return WERR_NOT_SUPPORTED;