s3:smbd: make use of smbXsrv_tcon and smbXsrv_session for smb2
[Samba/gebeck_regimport.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob6702784ff536ebd2e2ce6698a7423b8c1e2de935
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(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(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(snum);
290 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
292 if (remark) {
293 remark = talloc_sub_advanced(
294 p->mem_ctx, lp_servicename(snum),
295 get_current_username(), lp_pathname(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(snum);
319 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
320 if (remark) {
321 remark = talloc_sub_advanced(
322 p->mem_ctx, lp_servicename(snum),
323 get_current_username(), lp_pathname(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(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(snum);
383 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
385 if (remark) {
386 remark = talloc_sub_advanced(
387 p->mem_ctx, lp_servicename(snum),
388 get_current_username(), lp_pathname(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(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 = talloc_strdup(ctx, lp_comment(snum));
414 if (remark) {
415 remark = talloc_sub_advanced(
416 p->mem_ctx, lp_servicename(snum),
417 get_current_username(), lp_pathname(snum),
418 p->session_info->unix_token->uid, get_current_username(),
419 "", remark);
421 path = talloc_asprintf(ctx, "C:%s", lp_pathname(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(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 = talloc_strdup(p->mem_ctx, lp_comment(snum));
455 if (remark) {
456 remark = talloc_sub_advanced(
457 p->mem_ctx, lp_servicename(snum),
458 get_current_username(), lp_pathname(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(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(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(snum), FILE_READ_DATA, NULL);
553 /*******************************************************************
554 Fill in a share info structure.
555 ********************************************************************/
557 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
558 struct srvsvc_NetShareInfoCtr *info_ctr,
559 uint32_t *resume_handle_p,
560 uint32_t *total_entries,
561 bool all_shares)
563 int num_entries = 0;
564 int alloc_entries = 0;
565 int num_services = 0;
566 int snum;
567 TALLOC_CTX *ctx = p->mem_ctx;
568 int i = 0;
569 int valid_share_count = 0;
570 bool *allowed = 0;
571 union srvsvc_NetShareCtr ctr;
572 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
574 DEBUG(5,("init_srv_share_info_ctr\n"));
576 /* Ensure all the usershares are loaded. */
577 become_root();
578 load_usershare_shares(NULL, connections_snum_used);
579 load_registry_shares();
580 num_services = lp_numservices();
581 unbecome_root();
583 allowed = talloc_zero_array(ctx, bool, num_services);
584 W_ERROR_HAVE_NO_MEMORY(allowed);
586 /* Count the number of entries. */
587 for (snum = 0; snum < num_services; snum++) {
588 if (lp_browseable(snum) && lp_snum_ok(snum) &&
589 is_enumeration_allowed(p, snum) &&
590 (all_shares || !is_hidden_share(snum)) ) {
591 DEBUG(10, ("counting service %s\n",
592 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
593 allowed[snum] = true;
594 num_entries++;
595 } else {
596 DEBUG(10, ("NOT counting service %s\n",
597 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
601 if (!num_entries || (resume_handle >= num_entries)) {
602 return WERR_OK;
605 /* Calculate alloc entries. */
606 alloc_entries = num_entries - resume_handle;
607 switch (info_ctr->level) {
608 case 0:
609 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
610 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
612 ctr.ctr0->count = alloc_entries;
613 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
614 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
616 for (snum = 0; snum < num_services; snum++) {
617 if (allowed[snum] &&
618 (resume_handle <= (i + valid_share_count++)) ) {
619 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
623 break;
625 case 1:
626 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
627 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
629 ctr.ctr1->count = alloc_entries;
630 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
631 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
633 for (snum = 0; snum < num_services; snum++) {
634 if (allowed[snum] &&
635 (resume_handle <= (i + valid_share_count++)) ) {
636 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
640 break;
642 case 2:
643 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
644 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
646 ctr.ctr2->count = alloc_entries;
647 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
648 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
650 for (snum = 0; snum < num_services; snum++) {
651 if (allowed[snum] &&
652 (resume_handle <= (i + valid_share_count++)) ) {
653 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
657 break;
659 case 501:
660 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
661 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
663 ctr.ctr501->count = alloc_entries;
664 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
665 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
667 for (snum = 0; snum < num_services; snum++) {
668 if (allowed[snum] &&
669 (resume_handle <= (i + valid_share_count++)) ) {
670 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
674 break;
676 case 502:
677 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
678 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
680 ctr.ctr502->count = alloc_entries;
681 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
682 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
684 for (snum = 0; snum < num_services; snum++) {
685 if (allowed[snum] &&
686 (resume_handle <= (i + valid_share_count++)) ) {
687 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
691 break;
693 case 1004:
694 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
695 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
697 ctr.ctr1004->count = alloc_entries;
698 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
699 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
701 for (snum = 0; snum < num_services; snum++) {
702 if (allowed[snum] &&
703 (resume_handle <= (i + valid_share_count++)) ) {
704 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
708 break;
710 case 1005:
711 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
712 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
714 ctr.ctr1005->count = alloc_entries;
715 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
716 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
718 for (snum = 0; snum < num_services; snum++) {
719 if (allowed[snum] &&
720 (resume_handle <= (i + valid_share_count++)) ) {
721 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
725 break;
727 case 1006:
728 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
729 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
731 ctr.ctr1006->count = alloc_entries;
732 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
733 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
735 for (snum = 0; snum < num_services; snum++) {
736 if (allowed[snum] &&
737 (resume_handle <= (i + valid_share_count++)) ) {
738 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
742 break;
744 case 1007:
745 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
746 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
748 ctr.ctr1007->count = alloc_entries;
749 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
750 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
752 for (snum = 0; snum < num_services; snum++) {
753 if (allowed[snum] &&
754 (resume_handle <= (i + valid_share_count++)) ) {
755 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
759 break;
761 case 1501:
762 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
763 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
765 ctr.ctr1501->count = alloc_entries;
766 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
767 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
769 for (snum = 0; snum < num_services; snum++) {
770 if (allowed[snum] &&
771 (resume_handle <= (i + valid_share_count++)) ) {
772 struct sec_desc_buf *sd_buf = NULL;
773 init_srv_share_info_1501(p, &sd_buf, snum);
774 ctr.ctr1501->array[i++] = *sd_buf;
778 break;
780 default:
781 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
782 info_ctr->level));
783 return WERR_UNKNOWN_LEVEL;
786 *total_entries = alloc_entries;
787 if (resume_handle_p) {
788 if (all_shares) {
789 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
790 } else {
791 *resume_handle_p = num_entries;
795 info_ctr->ctr = ctr;
797 return WERR_OK;
800 /*******************************************************************
801 fill in a sess info level 0 structure.
802 ********************************************************************/
804 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
805 struct srvsvc_NetSessCtr0 *ctr0,
806 uint32_t *resume_handle_p,
807 uint32_t *total_entries)
809 struct sessionid *session_list;
810 uint32_t num_entries = 0;
811 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
812 *total_entries = list_sessions(p->mem_ctx, &session_list);
814 DEBUG(5,("init_srv_sess_info_0\n"));
816 if (ctr0 == NULL) {
817 if (resume_handle_p) {
818 *resume_handle_p = 0;
820 return WERR_OK;
823 for (; resume_handle < *total_entries; resume_handle++) {
825 ctr0->array = talloc_realloc(p->mem_ctx,
826 ctr0->array,
827 struct srvsvc_NetSessInfo0,
828 num_entries+1);
829 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
831 ctr0->array[num_entries].client =
832 session_list[resume_handle].remote_machine;
834 num_entries++;
837 ctr0->count = num_entries;
839 if (resume_handle_p) {
840 if (*resume_handle_p >= *total_entries) {
841 *resume_handle_p = 0;
842 } else {
843 *resume_handle_p = resume_handle;
847 return WERR_OK;
850 /*******************************************************************
851 ********************************************************************/
853 static void sess_file_fn( const struct share_mode_entry *e,
854 const char *sharepath, const char *fname,
855 void *data )
857 struct sess_file_count *sess = (struct sess_file_count *)data;
859 if (serverid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid)) {
860 sess->count++;
863 return;
866 /*******************************************************************
867 ********************************************************************/
869 static int net_count_files( uid_t uid, struct server_id pid )
871 struct sess_file_count s_file_cnt;
873 s_file_cnt.count = 0;
874 s_file_cnt.uid = uid;
875 s_file_cnt.pid = pid;
877 share_mode_forall( sess_file_fn, &s_file_cnt );
879 return s_file_cnt.count;
882 /*******************************************************************
883 fill in a sess info level 1 structure.
884 ********************************************************************/
886 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
887 struct srvsvc_NetSessCtr1 *ctr1,
888 uint32_t *resume_handle_p,
889 uint32_t *total_entries)
891 struct sessionid *session_list;
892 uint32_t num_entries = 0;
893 time_t now = time(NULL);
894 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
896 ZERO_STRUCTP(ctr1);
898 if (ctr1 == NULL) {
899 if (resume_handle_p) {
900 *resume_handle_p = 0;
902 return WERR_OK;
905 *total_entries = list_sessions(p->mem_ctx, &session_list);
907 for (; resume_handle < *total_entries; resume_handle++) {
908 uint32 num_files;
909 uint32 connect_time;
910 struct passwd *pw = getpwnam(session_list[resume_handle].username);
911 bool guest;
913 if ( !pw ) {
914 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
915 session_list[resume_handle].username));
916 continue;
919 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
920 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
921 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
923 ctr1->array = talloc_realloc(p->mem_ctx,
924 ctr1->array,
925 struct srvsvc_NetSessInfo1,
926 num_entries+1);
927 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
929 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
930 ctr1->array[num_entries].user = session_list[resume_handle].username;
931 ctr1->array[num_entries].num_open = num_files;
932 ctr1->array[num_entries].time = connect_time;
933 ctr1->array[num_entries].idle_time = 0;
934 ctr1->array[num_entries].user_flags = guest;
936 num_entries++;
939 ctr1->count = num_entries;
941 if (resume_handle_p) {
942 if (*resume_handle_p >= *total_entries) {
943 *resume_handle_p = 0;
944 } else {
945 *resume_handle_p = resume_handle;
949 return WERR_OK;
952 /*******************************************************************
953 fill in a conn info level 0 structure.
954 ********************************************************************/
956 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
957 uint32_t *resume_handle_p,
958 uint32_t *total_entries)
960 uint32_t num_entries = 0;
961 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
963 DEBUG(5,("init_srv_conn_info_0\n"));
965 if (ctr0 == NULL) {
966 if (resume_handle_p) {
967 *resume_handle_p = 0;
969 return WERR_OK;
972 *total_entries = 1;
974 ZERO_STRUCTP(ctr0);
976 for (; resume_handle < *total_entries; resume_handle++) {
978 ctr0->array = talloc_realloc(talloc_tos(),
979 ctr0->array,
980 struct srvsvc_NetConnInfo0,
981 num_entries+1);
982 if (!ctr0->array) {
983 return WERR_NOMEM;
986 ctr0->array[num_entries].conn_id = *total_entries;
988 /* move on to creating next connection */
989 num_entries++;
992 ctr0->count = num_entries;
993 *total_entries = num_entries;
995 if (resume_handle_p) {
996 if (*resume_handle_p >= *total_entries) {
997 *resume_handle_p = 0;
998 } else {
999 *resume_handle_p = resume_handle;
1003 return WERR_OK;
1006 /*******************************************************************
1007 fill in a conn info level 1 structure.
1008 ********************************************************************/
1010 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
1011 uint32_t *resume_handle_p,
1012 uint32_t *total_entries)
1014 uint32_t num_entries = 0;
1015 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
1017 DEBUG(5,("init_srv_conn_info_1\n"));
1019 if (ctr1 == NULL) {
1020 if (resume_handle_p) {
1021 *resume_handle_p = 0;
1023 return WERR_OK;
1026 *total_entries = 1;
1028 ZERO_STRUCTP(ctr1);
1030 for (; resume_handle < *total_entries; resume_handle++) {
1032 ctr1->array = talloc_realloc(talloc_tos(),
1033 ctr1->array,
1034 struct srvsvc_NetConnInfo1,
1035 num_entries+1);
1036 if (!ctr1->array) {
1037 return WERR_NOMEM;
1040 ctr1->array[num_entries].conn_id = *total_entries;
1041 ctr1->array[num_entries].conn_type = 0x3;
1042 ctr1->array[num_entries].num_open = 1;
1043 ctr1->array[num_entries].num_users = 1;
1044 ctr1->array[num_entries].conn_time = 3;
1045 ctr1->array[num_entries].user = "dummy_user";
1046 ctr1->array[num_entries].share = "IPC$";
1048 /* move on to creating next connection */
1049 num_entries++;
1052 ctr1->count = num_entries;
1053 *total_entries = num_entries;
1055 if (resume_handle_p) {
1056 if (*resume_handle_p >= *total_entries) {
1057 *resume_handle_p = 0;
1058 } else {
1059 *resume_handle_p = resume_handle;
1063 return WERR_OK;
1066 /*******************************************************************
1067 _srvsvc_NetFileEnum
1068 *******************************************************************/
1070 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
1071 struct srvsvc_NetFileEnum *r)
1073 TALLOC_CTX *ctx = NULL;
1074 struct srvsvc_NetFileCtr3 *ctr3;
1075 uint32_t resume_hnd = 0;
1076 WERROR werr;
1078 switch (r->in.info_ctr->level) {
1079 case 3:
1080 break;
1081 default:
1082 return WERR_UNKNOWN_LEVEL;
1085 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1086 p->session_info->security_token)) {
1087 DEBUG(1, ("Enumerating files only allowed for "
1088 "administrators\n"));
1089 return WERR_ACCESS_DENIED;
1092 ctx = talloc_tos();
1093 ctr3 = r->in.info_ctr->ctr.ctr3;
1094 if (!ctr3) {
1095 werr = WERR_INVALID_PARAM;
1096 goto done;
1099 /* TODO -- Windows enumerates
1100 (b) active pipes
1101 (c) open directories and files */
1103 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1104 if (!W_ERROR_IS_OK(werr)) {
1105 goto done;
1108 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1109 if (!W_ERROR_IS_OK(werr)) {
1110 goto done;
1113 *r->out.totalentries = ctr3->count;
1114 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1115 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1117 werr = WERR_OK;
1119 done:
1120 return werr;
1123 /*******************************************************************
1124 _srvsvc_NetSrvGetInfo
1125 ********************************************************************/
1127 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1128 struct srvsvc_NetSrvGetInfo *r)
1130 WERROR status = WERR_OK;
1132 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1134 if (!pipe_access_check(p)) {
1135 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1136 return WERR_ACCESS_DENIED;
1139 switch (r->in.level) {
1141 /* Technically level 102 should only be available to
1142 Administrators but there isn't anything super-secret
1143 here, as most of it is made up. */
1145 case 102: {
1146 struct srvsvc_NetSrvInfo102 *info102;
1148 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1149 if (!info102) {
1150 return WERR_NOMEM;
1153 info102->platform_id = PLATFORM_ID_NT;
1154 info102->server_name = lp_netbios_name();
1155 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1156 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1157 info102->server_type = lp_default_server_announce();
1158 info102->comment = string_truncate(lp_serverstring(),
1159 MAX_SERVER_STRING_LENGTH);
1160 info102->users = 0xffffffff;
1161 info102->disc = 0xf;
1162 info102->hidden = 0;
1163 info102->announce = 240;
1164 info102->anndelta = 3000;
1165 info102->licenses = 100000;
1166 info102->userpath = "C:\\";
1168 r->out.info->info102 = info102;
1169 break;
1171 case 101: {
1172 struct srvsvc_NetSrvInfo101 *info101;
1174 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1175 if (!info101) {
1176 return WERR_NOMEM;
1179 info101->platform_id = PLATFORM_ID_NT;
1180 info101->server_name = lp_netbios_name();
1181 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1182 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1183 info101->server_type = lp_default_server_announce();
1184 info101->comment = string_truncate(lp_serverstring(),
1185 MAX_SERVER_STRING_LENGTH);
1187 r->out.info->info101 = info101;
1188 break;
1190 case 100: {
1191 struct srvsvc_NetSrvInfo100 *info100;
1193 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1194 if (!info100) {
1195 return WERR_NOMEM;
1198 info100->platform_id = PLATFORM_ID_NT;
1199 info100->server_name = lp_netbios_name();
1201 r->out.info->info100 = info100;
1203 break;
1205 default:
1206 status = WERR_UNKNOWN_LEVEL;
1207 break;
1210 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1212 return status;
1215 /*******************************************************************
1216 _srvsvc_NetSrvSetInfo
1217 ********************************************************************/
1219 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1220 struct srvsvc_NetSrvSetInfo *r)
1222 WERROR status = WERR_OK;
1224 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1226 /* Set up the net server set info structure. */
1228 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1230 return status;
1233 /*******************************************************************
1234 _srvsvc_NetConnEnum
1235 ********************************************************************/
1237 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1238 struct srvsvc_NetConnEnum *r)
1240 WERROR werr;
1242 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1244 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1245 p->session_info->security_token)) {
1246 DEBUG(1, ("Enumerating connections only allowed for "
1247 "administrators\n"));
1248 return WERR_ACCESS_DENIED;
1251 switch (r->in.info_ctr->level) {
1252 case 0:
1253 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1254 r->in.resume_handle,
1255 r->out.totalentries);
1256 break;
1257 case 1:
1258 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1259 r->in.resume_handle,
1260 r->out.totalentries);
1261 break;
1262 default:
1263 return WERR_UNKNOWN_LEVEL;
1266 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1268 return werr;
1271 /*******************************************************************
1272 _srvsvc_NetSessEnum
1273 ********************************************************************/
1275 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1276 struct srvsvc_NetSessEnum *r)
1278 WERROR werr;
1280 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1282 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1283 p->session_info->security_token)) {
1284 DEBUG(1, ("Enumerating sessions only allowed for "
1285 "administrators\n"));
1286 return WERR_ACCESS_DENIED;
1289 switch (r->in.info_ctr->level) {
1290 case 0:
1291 werr = init_srv_sess_info_0(p,
1292 r->in.info_ctr->ctr.ctr0,
1293 r->in.resume_handle,
1294 r->out.totalentries);
1295 break;
1296 case 1:
1297 werr = init_srv_sess_info_1(p,
1298 r->in.info_ctr->ctr.ctr1,
1299 r->in.resume_handle,
1300 r->out.totalentries);
1301 break;
1302 default:
1303 return WERR_UNKNOWN_LEVEL;
1306 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1308 return werr;
1311 /*******************************************************************
1312 _srvsvc_NetSessDel
1313 ********************************************************************/
1315 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1316 struct srvsvc_NetSessDel *r)
1318 struct sessionid *session_list;
1319 int num_sessions, snum;
1320 const char *username;
1321 const char *machine;
1322 bool not_root = False;
1323 WERROR werr;
1325 username = r->in.user;
1326 machine = r->in.client;
1328 /* strip leading backslashes if any */
1329 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1330 machine += 2;
1333 num_sessions = list_sessions(p->mem_ctx, &session_list);
1335 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1337 werr = WERR_ACCESS_DENIED;
1339 /* fail out now if you are not root or not a domain admin */
1341 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1342 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1343 DOMAIN_RID_ADMINS))) {
1345 goto done;
1348 for (snum = 0; snum < num_sessions; snum++) {
1350 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1351 strequal(session_list[snum].remote_machine, machine)) {
1353 NTSTATUS ntstat;
1355 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1356 not_root = True;
1357 become_root();
1360 ntstat = messaging_send(p->msg_ctx,
1361 session_list[snum].pid,
1362 MSG_SHUTDOWN, &data_blob_null);
1364 if (NT_STATUS_IS_OK(ntstat))
1365 werr = WERR_OK;
1367 if (not_root)
1368 unbecome_root();
1372 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1374 done:
1376 return werr;
1379 /*******************************************************************
1380 _srvsvc_NetShareEnumAll
1381 ********************************************************************/
1383 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1384 struct srvsvc_NetShareEnumAll *r)
1386 WERROR werr;
1388 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1390 if (!pipe_access_check(p)) {
1391 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1392 return WERR_ACCESS_DENIED;
1395 /* Create the list of shares for the response. */
1396 werr = init_srv_share_info_ctr(p,
1397 r->in.info_ctr,
1398 r->in.resume_handle,
1399 r->out.totalentries,
1400 true);
1402 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1404 return werr;
1407 /*******************************************************************
1408 _srvsvc_NetShareEnum
1409 ********************************************************************/
1411 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1412 struct srvsvc_NetShareEnum *r)
1414 WERROR werr;
1416 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1418 if (!pipe_access_check(p)) {
1419 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1420 return WERR_ACCESS_DENIED;
1423 /* Create the list of shares for the response. */
1424 werr = init_srv_share_info_ctr(p,
1425 r->in.info_ctr,
1426 r->in.resume_handle,
1427 r->out.totalentries,
1428 false);
1430 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1432 return werr;
1435 /*******************************************************************
1436 _srvsvc_NetShareGetInfo
1437 ********************************************************************/
1439 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1440 struct srvsvc_NetShareGetInfo *r)
1442 WERROR status = WERR_OK;
1443 char *share_name = NULL;
1444 int snum;
1445 union srvsvc_NetShareInfo *info = r->out.info;
1447 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1449 if (!r->in.share_name) {
1450 return WERR_INVALID_NAME;
1453 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1454 if (!share_name) {
1455 return WERR_NOMEM;
1457 if (snum < 0) {
1458 return WERR_INVALID_NAME;
1461 switch (r->in.level) {
1462 case 0:
1463 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1464 W_ERROR_HAVE_NO_MEMORY(info->info0);
1465 init_srv_share_info_0(p, info->info0, snum);
1466 break;
1467 case 1:
1468 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1469 W_ERROR_HAVE_NO_MEMORY(info->info1);
1470 init_srv_share_info_1(p, info->info1, snum);
1471 break;
1472 case 2:
1473 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1474 W_ERROR_HAVE_NO_MEMORY(info->info2);
1475 init_srv_share_info_2(p, info->info2, snum);
1476 break;
1477 case 501:
1478 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1479 W_ERROR_HAVE_NO_MEMORY(info->info501);
1480 init_srv_share_info_501(p, info->info501, snum);
1481 break;
1482 case 502:
1483 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1484 W_ERROR_HAVE_NO_MEMORY(info->info502);
1485 init_srv_share_info_502(p, info->info502, snum);
1486 break;
1487 case 1004:
1488 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1489 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1490 init_srv_share_info_1004(p, info->info1004, snum);
1491 break;
1492 case 1005:
1493 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1494 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1495 init_srv_share_info_1005(p, info->info1005, snum);
1496 break;
1497 case 1006:
1498 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1499 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1500 init_srv_share_info_1006(p, info->info1006, snum);
1501 break;
1502 case 1007:
1503 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1504 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1505 init_srv_share_info_1007(p, info->info1007, snum);
1506 break;
1507 case 1501:
1508 init_srv_share_info_1501(p, &info->info1501, snum);
1509 break;
1510 default:
1511 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1512 r->in.level));
1513 status = WERR_UNKNOWN_LEVEL;
1514 break;
1517 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1519 return status;
1522 /*******************************************************************
1523 _srvsvc_NetShareSetInfo. Modify share details.
1524 ********************************************************************/
1526 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1527 struct srvsvc_NetShareSetInfo *r)
1529 char *command = NULL;
1530 char *share_name = NULL;
1531 char *comment = NULL;
1532 const char *pathname = NULL;
1533 int type;
1534 int snum;
1535 int ret;
1536 char *path = NULL;
1537 struct security_descriptor *psd = NULL;
1538 bool is_disk_op = False;
1539 int max_connections = 0;
1540 TALLOC_CTX *ctx = p->mem_ctx;
1541 union srvsvc_NetShareInfo *info = r->in.info;
1543 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1545 if (!r->in.share_name) {
1546 return WERR_INVALID_NAME;
1549 if (r->out.parm_error) {
1550 *r->out.parm_error = 0;
1553 if ( strequal(r->in.share_name,"IPC$")
1554 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1555 || strequal(r->in.share_name,"global") )
1557 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1558 "modified by a remote user.\n",
1559 r->in.share_name ));
1560 return WERR_ACCESS_DENIED;
1563 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1564 if (!share_name) {
1565 return WERR_NOMEM;
1568 /* Does this share exist ? */
1569 if (snum < 0)
1570 return WERR_NET_NAME_NOT_FOUND;
1572 /* No change to printer shares. */
1573 if (lp_print_ok(snum))
1574 return WERR_ACCESS_DENIED;
1576 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1578 /* fail out now if you are not root and not a disk op */
1580 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1581 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1582 "SeDiskOperatorPrivilege privilege needed to modify "
1583 "share %s\n",
1584 (unsigned int)p->session_info->unix_token->uid,
1585 share_name ));
1586 return WERR_ACCESS_DENIED;
1589 switch (r->in.level) {
1590 case 1:
1591 pathname = talloc_strdup(ctx, lp_pathname(snum));
1592 comment = talloc_strdup(ctx, info->info1->comment);
1593 type = info->info1->type;
1594 psd = NULL;
1595 break;
1596 case 2:
1597 comment = talloc_strdup(ctx, info->info2->comment);
1598 pathname = info->info2->path;
1599 type = info->info2->type;
1600 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1601 0 : info->info2->max_users;
1602 psd = NULL;
1603 break;
1604 #if 0
1605 /* not supported on set but here for completeness */
1606 case 501:
1607 comment = talloc_strdup(ctx, info->info501->comment);
1608 type = info->info501->type;
1609 psd = NULL;
1610 break;
1611 #endif
1612 case 502:
1613 comment = talloc_strdup(ctx, info->info502->comment);
1614 pathname = info->info502->path;
1615 type = info->info502->type;
1616 psd = info->info502->sd_buf.sd;
1617 map_generic_share_sd_bits(psd);
1618 break;
1619 case 1004:
1620 pathname = talloc_strdup(ctx, lp_pathname(snum));
1621 comment = talloc_strdup(ctx, info->info1004->comment);
1622 type = STYPE_DISKTREE;
1623 break;
1624 case 1005:
1625 /* XP re-sets the csc policy even if it wasn't changed by the
1626 user, so we must compare it to see if it's what is set in
1627 smb.conf, so that we can contine other ops like setting
1628 ACLs on a share */
1629 if (((info->info1005->dfs_flags &
1630 SHARE_1005_CSC_POLICY_MASK) >>
1631 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1632 return WERR_OK;
1633 else {
1634 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1635 return WERR_ACCESS_DENIED;
1637 case 1006:
1638 case 1007:
1639 return WERR_ACCESS_DENIED;
1640 case 1501:
1641 pathname = talloc_strdup(ctx, lp_pathname(snum));
1642 comment = talloc_strdup(ctx, lp_comment(snum));
1643 psd = info->info1501->sd;
1644 map_generic_share_sd_bits(psd);
1645 type = STYPE_DISKTREE;
1646 break;
1647 default:
1648 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1649 r->in.level));
1650 return WERR_UNKNOWN_LEVEL;
1653 /* We can only modify disk shares. */
1654 if (type != STYPE_DISKTREE) {
1655 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1656 "disk share\n",
1657 share_name ));
1658 return WERR_ACCESS_DENIED;
1661 if (comment == NULL) {
1662 return WERR_NOMEM;
1665 /* Check if the pathname is valid. */
1666 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1667 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1668 pathname ));
1669 return WERR_OBJECT_PATH_INVALID;
1672 /* Ensure share name, pathname and comment don't contain '"' characters. */
1673 string_replace(share_name, '"', ' ');
1674 string_replace(path, '"', ' ');
1675 string_replace(comment, '"', ' ');
1677 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1678 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1680 /* Only call modify function if something changed. */
1682 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1683 || (lp_max_connections(snum) != max_connections)) {
1684 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1685 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1686 return WERR_ACCESS_DENIED;
1689 command = talloc_asprintf(p->mem_ctx,
1690 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1691 lp_change_share_cmd(),
1692 get_dyn_CONFIGFILE(),
1693 share_name,
1694 path,
1695 comment ? comment : "",
1696 max_connections);
1697 if (!command) {
1698 return WERR_NOMEM;
1701 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1703 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1705 if (is_disk_op)
1706 become_root();
1708 if ( (ret = smbrun(command, NULL)) == 0 ) {
1709 /* Tell everyone we updated smb.conf. */
1710 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1711 NULL, 0, NULL);
1714 if ( is_disk_op )
1715 unbecome_root();
1717 /********* END SeDiskOperatorPrivilege BLOCK *********/
1719 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1720 command, ret ));
1722 TALLOC_FREE(command);
1724 if ( ret != 0 )
1725 return WERR_ACCESS_DENIED;
1726 } else {
1727 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1728 share_name ));
1731 /* Replace SD if changed. */
1732 if (psd) {
1733 struct security_descriptor *old_sd;
1734 size_t sd_size;
1736 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1738 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1739 if (!set_share_security(share_name, psd))
1740 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1741 share_name ));
1745 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1747 return WERR_OK;
1750 /*******************************************************************
1751 _srvsvc_NetShareAdd.
1752 Call 'add_share_command "sharename" "pathname"
1753 "comment" "max connections = "
1754 ********************************************************************/
1756 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1757 struct srvsvc_NetShareAdd *r)
1759 char *command = NULL;
1760 char *share_name_in = NULL;
1761 char *share_name = NULL;
1762 char *comment = NULL;
1763 char *pathname = NULL;
1764 int type;
1765 int snum;
1766 int ret;
1767 char *path;
1768 struct security_descriptor *psd = NULL;
1769 bool is_disk_op;
1770 int max_connections = 0;
1771 TALLOC_CTX *ctx = p->mem_ctx;
1773 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1775 if (r->out.parm_error) {
1776 *r->out.parm_error = 0;
1779 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1781 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1782 return WERR_ACCESS_DENIED;
1784 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1785 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1786 return WERR_ACCESS_DENIED;
1789 switch (r->in.level) {
1790 case 0:
1791 /* No path. Not enough info in a level 0 to do anything. */
1792 return WERR_ACCESS_DENIED;
1793 case 1:
1794 /* Not enough info in a level 1 to do anything. */
1795 return WERR_ACCESS_DENIED;
1796 case 2:
1797 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1798 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1799 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1800 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1801 0 : r->in.info->info2->max_users;
1802 type = r->in.info->info2->type;
1803 break;
1804 case 501:
1805 /* No path. Not enough info in a level 501 to do anything. */
1806 return WERR_ACCESS_DENIED;
1807 case 502:
1808 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1809 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1810 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1811 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1812 0 : r->in.info->info502->max_users;
1813 type = r->in.info->info502->type;
1814 psd = r->in.info->info502->sd_buf.sd;
1815 map_generic_share_sd_bits(psd);
1816 break;
1818 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1820 case 1004:
1821 case 1005:
1822 case 1006:
1823 case 1007:
1824 return WERR_ACCESS_DENIED;
1825 case 1501:
1826 /* DFS only level. */
1827 return WERR_ACCESS_DENIED;
1828 default:
1829 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1830 r->in.level));
1831 return WERR_UNKNOWN_LEVEL;
1834 /* check for invalid share names */
1836 if (!share_name_in || !validate_net_name(share_name_in,
1837 INVALID_SHARENAME_CHARS,
1838 strlen(share_name_in))) {
1839 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1840 share_name_in ? share_name_in : ""));
1841 return WERR_INVALID_NAME;
1844 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1845 || (lp_enable_asu_support() &&
1846 strequal(share_name_in,"ADMIN$"))) {
1847 return WERR_ACCESS_DENIED;
1850 snum = find_service(ctx, share_name_in, &share_name);
1851 if (!share_name) {
1852 return WERR_NOMEM;
1855 /* Share already exists. */
1856 if (snum >= 0) {
1857 return WERR_FILE_EXISTS;
1860 /* We can only add disk shares. */
1861 if (type != STYPE_DISKTREE) {
1862 return WERR_ACCESS_DENIED;
1865 /* Check if the pathname is valid. */
1866 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1867 return WERR_OBJECT_PATH_INVALID;
1870 /* Ensure share name, pathname and comment don't contain '"' characters. */
1871 string_replace(share_name_in, '"', ' ');
1872 string_replace(share_name, '"', ' ');
1873 string_replace(path, '"', ' ');
1874 if (comment) {
1875 string_replace(comment, '"', ' ');
1878 command = talloc_asprintf(ctx,
1879 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1880 lp_add_share_cmd(),
1881 get_dyn_CONFIGFILE(),
1882 share_name_in,
1883 path,
1884 comment ? comment : "",
1885 max_connections);
1886 if (!command) {
1887 return WERR_NOMEM;
1890 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1892 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1894 if ( is_disk_op )
1895 become_root();
1897 /* FIXME: use libnetconf here - gd */
1899 if ( (ret = smbrun(command, NULL)) == 0 ) {
1900 /* Tell everyone we updated smb.conf. */
1901 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1902 NULL);
1905 if ( is_disk_op )
1906 unbecome_root();
1908 /********* END SeDiskOperatorPrivilege BLOCK *********/
1910 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1911 command, ret ));
1913 TALLOC_FREE(command);
1915 if ( ret != 0 )
1916 return WERR_ACCESS_DENIED;
1918 if (psd) {
1919 /* Note we use share_name here, not share_name_in as
1920 we need a canonicalized name for setting security. */
1921 if (!set_share_security(share_name, psd)) {
1922 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1923 share_name ));
1928 * We don't call reload_services() here, the message will
1929 * cause this to be done before the next packet is read
1930 * from the client. JRA.
1933 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1935 return WERR_OK;
1938 /*******************************************************************
1939 _srvsvc_NetShareDel
1940 Call "delete share command" with the share name as
1941 a parameter.
1942 ********************************************************************/
1944 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
1945 struct srvsvc_NetShareDel *r)
1947 char *command = NULL;
1948 char *share_name = NULL;
1949 int ret;
1950 int snum;
1951 bool is_disk_op;
1952 struct share_params *params;
1953 TALLOC_CTX *ctx = p->mem_ctx;
1955 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1957 if (!r->in.share_name) {
1958 return WERR_NET_NAME_NOT_FOUND;
1961 if ( strequal(r->in.share_name,"IPC$")
1962 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1963 || strequal(r->in.share_name,"global") )
1965 return WERR_ACCESS_DENIED;
1968 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1969 if (!share_name) {
1970 return WERR_NOMEM;
1973 if (snum < 0) {
1974 return WERR_NO_SUCH_SHARE;
1977 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1978 return WERR_NO_SUCH_SHARE;
1981 /* No change to printer shares. */
1982 if (lp_print_ok(snum))
1983 return WERR_ACCESS_DENIED;
1985 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1987 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1988 return WERR_ACCESS_DENIED;
1990 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1991 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1992 return WERR_ACCESS_DENIED;
1995 command = talloc_asprintf(ctx,
1996 "%s \"%s\" \"%s\"",
1997 lp_delete_share_cmd(),
1998 get_dyn_CONFIGFILE(),
1999 lp_servicename(snum));
2000 if (!command) {
2001 return WERR_NOMEM;
2004 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
2006 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
2008 if ( is_disk_op )
2009 become_root();
2011 if ( (ret = smbrun(command, NULL)) == 0 ) {
2012 /* Tell everyone we updated smb.conf. */
2013 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
2014 NULL);
2017 if ( is_disk_op )
2018 unbecome_root();
2020 /********* END SeDiskOperatorPrivilege BLOCK *********/
2022 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
2024 if ( ret != 0 )
2025 return WERR_ACCESS_DENIED;
2027 /* Delete the SD in the database. */
2028 delete_share_security(lp_servicename(params->service));
2030 lp_killservice(params->service);
2032 return WERR_OK;
2035 /*******************************************************************
2036 _srvsvc_NetShareDelSticky
2037 ********************************************************************/
2039 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
2040 struct srvsvc_NetShareDelSticky *r)
2042 struct srvsvc_NetShareDel q;
2044 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2046 q.in.server_unc = r->in.server_unc;
2047 q.in.share_name = r->in.share_name;
2048 q.in.reserved = r->in.reserved;
2050 return _srvsvc_NetShareDel(p, &q);
2053 /*******************************************************************
2054 _srvsvc_NetRemoteTOD
2055 ********************************************************************/
2057 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
2058 struct srvsvc_NetRemoteTOD *r)
2060 struct srvsvc_NetRemoteTODInfo *tod;
2061 struct tm *t;
2062 time_t unixdate = time(NULL);
2064 /* We do this call first as if we do it *after* the gmtime call
2065 it overwrites the pointed-to values. JRA */
2067 uint32 zone = get_time_zone(unixdate)/60;
2069 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2071 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2072 return WERR_NOMEM;
2074 *r->out.info = tod;
2076 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2078 t = gmtime(&unixdate);
2080 /* set up the */
2081 tod->elapsed = unixdate;
2082 tod->msecs = 0;
2083 tod->hours = t->tm_hour;
2084 tod->mins = t->tm_min;
2085 tod->secs = t->tm_sec;
2086 tod->hunds = 0;
2087 tod->timezone = zone;
2088 tod->tinterval = 10000;
2089 tod->day = t->tm_mday;
2090 tod->month = t->tm_mon + 1;
2091 tod->year = 1900+t->tm_year;
2092 tod->weekday = t->tm_wday;
2094 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2096 return WERR_OK;
2099 /***********************************************************************************
2100 _srvsvc_NetGetFileSecurity
2101 Win9x NT tools get security descriptor.
2102 ***********************************************************************************/
2104 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2105 struct srvsvc_NetGetFileSecurity *r)
2107 struct smb_filename *smb_fname = NULL;
2108 struct security_descriptor *psd = NULL;
2109 size_t sd_size;
2110 char *servicename = NULL;
2111 SMB_STRUCT_STAT st;
2112 NTSTATUS nt_status;
2113 WERROR werr;
2114 connection_struct *conn = NULL;
2115 struct sec_desc_buf *sd_buf = NULL;
2116 files_struct *fsp = NULL;
2117 int snum;
2118 char *oldcwd = NULL;
2120 ZERO_STRUCT(st);
2122 if (!r->in.share) {
2123 werr = WERR_NET_NAME_NOT_FOUND;
2124 goto error_exit;
2126 snum = find_service(talloc_tos(), r->in.share, &servicename);
2127 if (!servicename) {
2128 werr = WERR_NOMEM;
2129 goto error_exit;
2131 if (snum == -1) {
2132 DEBUG(10, ("Could not find service %s\n", servicename));
2133 werr = WERR_NET_NAME_NOT_FOUND;
2134 goto error_exit;
2137 nt_status = create_conn_struct(talloc_tos(),
2138 server_event_context(),
2139 server_messaging_context(),
2140 &conn,
2141 snum, lp_pathname(snum),
2142 p->session_info, &oldcwd);
2143 if (!NT_STATUS_IS_OK(nt_status)) {
2144 DEBUG(10, ("create_conn_struct failed: %s\n",
2145 nt_errstr(nt_status)));
2146 werr = ntstatus_to_werror(nt_status);
2147 goto error_exit;
2150 nt_status = filename_convert(talloc_tos(),
2151 conn,
2152 false,
2153 r->in.file,
2155 NULL,
2156 &smb_fname);
2157 if (!NT_STATUS_IS_OK(nt_status)) {
2158 werr = ntstatus_to_werror(nt_status);
2159 goto error_exit;
2162 nt_status = SMB_VFS_CREATE_FILE(
2163 conn, /* conn */
2164 NULL, /* req */
2165 0, /* root_dir_fid */
2166 smb_fname, /* fname */
2167 FILE_READ_ATTRIBUTES, /* access_mask */
2168 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2169 FILE_OPEN, /* create_disposition*/
2170 0, /* create_options */
2171 0, /* file_attributes */
2172 INTERNAL_OPEN_ONLY, /* oplock_request */
2173 0, /* allocation_size */
2174 0, /* private_flags */
2175 NULL, /* sd */
2176 NULL, /* ea_list */
2177 &fsp, /* result */
2178 NULL); /* pinfo */
2180 if (!NT_STATUS_IS_OK(nt_status)) {
2181 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2182 smb_fname_str_dbg(smb_fname)));
2183 werr = ntstatus_to_werror(nt_status);
2184 goto error_exit;
2187 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2188 (SECINFO_OWNER
2189 |SECINFO_GROUP
2190 |SECINFO_DACL), &psd);
2192 if (!NT_STATUS_IS_OK(nt_status)) {
2193 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2194 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2195 werr = ntstatus_to_werror(nt_status);
2196 goto error_exit;
2199 sd_size = ndr_size_security_descriptor(psd, 0);
2201 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2202 if (!sd_buf) {
2203 werr = WERR_NOMEM;
2204 goto error_exit;
2207 sd_buf->sd_size = sd_size;
2208 sd_buf->sd = psd;
2210 *r->out.sd_buf = sd_buf;
2212 psd->dacl->revision = NT4_ACL_REVISION;
2214 close_file(NULL, fsp, NORMAL_CLOSE);
2215 vfs_ChDir(conn, oldcwd);
2216 SMB_VFS_DISCONNECT(conn);
2217 conn_free(conn);
2218 werr = WERR_OK;
2219 goto done;
2221 error_exit:
2223 if (fsp) {
2224 close_file(NULL, fsp, NORMAL_CLOSE);
2227 if (oldcwd) {
2228 vfs_ChDir(conn, oldcwd);
2231 if (conn) {
2232 SMB_VFS_DISCONNECT(conn);
2233 conn_free(conn);
2236 done:
2237 TALLOC_FREE(smb_fname);
2239 return werr;
2242 /***********************************************************************************
2243 _srvsvc_NetSetFileSecurity
2244 Win9x NT tools set security descriptor.
2245 ***********************************************************************************/
2247 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2248 struct srvsvc_NetSetFileSecurity *r)
2250 struct smb_filename *smb_fname = NULL;
2251 char *servicename = NULL;
2252 files_struct *fsp = NULL;
2253 SMB_STRUCT_STAT st;
2254 NTSTATUS nt_status;
2255 WERROR werr;
2256 connection_struct *conn = NULL;
2257 int snum;
2258 char *oldcwd = NULL;
2259 struct security_descriptor *psd = NULL;
2260 uint32_t security_info_sent = 0;
2262 ZERO_STRUCT(st);
2264 if (!r->in.share) {
2265 werr = WERR_NET_NAME_NOT_FOUND;
2266 goto error_exit;
2269 snum = find_service(talloc_tos(), r->in.share, &servicename);
2270 if (!servicename) {
2271 werr = WERR_NOMEM;
2272 goto error_exit;
2275 if (snum == -1) {
2276 DEBUG(10, ("Could not find service %s\n", servicename));
2277 werr = WERR_NET_NAME_NOT_FOUND;
2278 goto error_exit;
2281 nt_status = create_conn_struct(talloc_tos(),
2282 server_event_context(),
2283 server_messaging_context(),
2284 &conn,
2285 snum, lp_pathname(snum),
2286 p->session_info, &oldcwd);
2287 if (!NT_STATUS_IS_OK(nt_status)) {
2288 DEBUG(10, ("create_conn_struct failed: %s\n",
2289 nt_errstr(nt_status)));
2290 werr = ntstatus_to_werror(nt_status);
2291 goto error_exit;
2294 nt_status = filename_convert(talloc_tos(),
2295 conn,
2296 false,
2297 r->in.file,
2299 NULL,
2300 &smb_fname);
2301 if (!NT_STATUS_IS_OK(nt_status)) {
2302 werr = ntstatus_to_werror(nt_status);
2303 goto error_exit;
2306 nt_status = SMB_VFS_CREATE_FILE(
2307 conn, /* conn */
2308 NULL, /* req */
2309 0, /* root_dir_fid */
2310 smb_fname, /* fname */
2311 FILE_WRITE_ATTRIBUTES, /* access_mask */
2312 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2313 FILE_OPEN, /* create_disposition*/
2314 0, /* create_options */
2315 0, /* file_attributes */
2316 INTERNAL_OPEN_ONLY, /* oplock_request */
2317 0, /* allocation_size */
2318 0, /* private_flags */
2319 NULL, /* sd */
2320 NULL, /* ea_list */
2321 &fsp, /* result */
2322 NULL); /* pinfo */
2324 if (!NT_STATUS_IS_OK(nt_status)) {
2325 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2326 smb_fname_str_dbg(smb_fname)));
2327 werr = ntstatus_to_werror(nt_status);
2328 goto error_exit;
2331 psd = r->in.sd_buf->sd;
2332 security_info_sent = r->in.securityinformation;
2334 if (psd->owner_sid==0) {
2335 security_info_sent &= ~SECINFO_OWNER;
2337 if (psd->group_sid==0) {
2338 security_info_sent &= ~SECINFO_GROUP;
2340 if (psd->sacl==0) {
2341 security_info_sent &= ~SECINFO_SACL;
2343 if (psd->dacl==0) {
2344 security_info_sent &= ~SECINFO_DACL;
2347 /* Convert all the generic bits. */
2348 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2349 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2351 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2352 security_info_sent,
2353 psd);
2355 if (!NT_STATUS_IS_OK(nt_status) ) {
2356 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2357 "on file %s\n", r->in.share));
2358 werr = WERR_ACCESS_DENIED;
2359 goto error_exit;
2362 close_file(NULL, fsp, NORMAL_CLOSE);
2363 vfs_ChDir(conn, oldcwd);
2364 SMB_VFS_DISCONNECT(conn);
2365 conn_free(conn);
2366 werr = WERR_OK;
2367 goto done;
2369 error_exit:
2371 if (fsp) {
2372 close_file(NULL, fsp, NORMAL_CLOSE);
2375 if (oldcwd) {
2376 vfs_ChDir(conn, oldcwd);
2379 if (conn) {
2380 SMB_VFS_DISCONNECT(conn);
2381 conn_free(conn);
2384 done:
2385 TALLOC_FREE(smb_fname);
2387 return werr;
2390 /***********************************************************************************
2391 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2392 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2393 These disks would the disks listed by this function.
2394 Users could then create shares relative to these disks. Watch out for moving these disks around.
2395 "Nigel Williams" <nigel@veritas.com>.
2396 ***********************************************************************************/
2398 static const char *server_disks[] = {"C:"};
2400 static uint32 get_server_disk_count(void)
2402 return sizeof(server_disks)/sizeof(server_disks[0]);
2405 static uint32 init_server_disk_enum(uint32 *resume)
2407 uint32 server_disk_count = get_server_disk_count();
2409 /*resume can be an offset into the list for now*/
2411 if(*resume & 0x80000000)
2412 *resume = 0;
2414 if(*resume > server_disk_count)
2415 *resume = server_disk_count;
2417 return server_disk_count - *resume;
2420 static const char *next_server_disk_enum(uint32 *resume)
2422 const char *disk;
2424 if(init_server_disk_enum(resume) == 0)
2425 return NULL;
2427 disk = server_disks[*resume];
2429 (*resume)++;
2431 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2433 return disk;
2436 /********************************************************************
2437 _srvsvc_NetDiskEnum
2438 ********************************************************************/
2440 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2441 struct srvsvc_NetDiskEnum *r)
2443 uint32 i;
2444 const char *disk_name;
2445 TALLOC_CTX *ctx = p->mem_ctx;
2446 WERROR werr;
2447 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2449 werr = WERR_OK;
2451 *r->out.totalentries = init_server_disk_enum(&resume);
2453 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2454 MAX_SERVER_DISK_ENTRIES);
2455 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2457 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2459 r->out.info->count = 0;
2461 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2463 r->out.info->count++;
2465 /*copy disk name into a unicode string*/
2467 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2468 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2471 /* add a terminating null string. Is this there if there is more data to come? */
2473 r->out.info->count++;
2475 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2476 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2478 if (r->out.resume_handle) {
2479 *r->out.resume_handle = resume;
2482 return werr;
2485 /********************************************************************
2486 _srvsvc_NetNameValidate
2487 ********************************************************************/
2489 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2490 struct srvsvc_NetNameValidate *r)
2492 switch (r->in.name_type) {
2493 case 0x9:
2494 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2495 strlen_m(r->in.name)))
2497 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2498 r->in.name));
2499 return WERR_INVALID_NAME;
2501 break;
2503 default:
2504 return WERR_UNKNOWN_LEVEL;
2507 return WERR_OK;
2510 /*******************************************************************
2511 ********************************************************************/
2513 struct enum_file_close_state {
2514 struct srvsvc_NetFileClose *r;
2515 struct messaging_context *msg_ctx;
2518 static void enum_file_close_fn( const struct share_mode_entry *e,
2519 const char *sharepath, const char *fname,
2520 void *private_data )
2522 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2523 struct enum_file_close_state *state =
2524 (struct enum_file_close_state *)private_data;
2525 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2527 if (fid != state->r->in.fid) {
2528 return; /* Not this file. */
2531 if (!process_exists(e->pid) ) {
2532 return;
2535 /* Ok - send the close message. */
2536 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2537 sharepath,
2538 share_mode_str(talloc_tos(), 0, e) ));
2540 share_mode_entry_to_message(msg, e);
2542 state->r->out.result = ntstatus_to_werror(
2543 messaging_send_buf(state->msg_ctx,
2544 e->pid, MSG_SMB_CLOSE_FILE,
2545 (uint8 *)msg,
2546 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2549 /********************************************************************
2550 Close a file given a 32-bit file id.
2551 ********************************************************************/
2553 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2554 struct srvsvc_NetFileClose *r)
2556 struct enum_file_close_state state;
2557 bool is_disk_op;
2559 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2561 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2563 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2564 return WERR_ACCESS_DENIED;
2567 /* enum_file_close_fn sends the close message to
2568 * the relevent smbd process. */
2570 r->out.result = WERR_BADFILE;
2571 state.r = r;
2572 state.msg_ctx = p->msg_ctx;
2573 share_mode_forall(enum_file_close_fn, &state);
2574 return r->out.result;
2577 /********************************************************************
2578 ********************************************************************/
2580 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2581 struct srvsvc_NetCharDevEnum *r)
2583 p->rng_fault_state = True;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2588 struct srvsvc_NetCharDevGetInfo *r)
2590 p->rng_fault_state = True;
2591 return WERR_NOT_SUPPORTED;
2594 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2595 struct srvsvc_NetCharDevControl *r)
2597 p->rng_fault_state = True;
2598 return WERR_NOT_SUPPORTED;
2601 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2602 struct srvsvc_NetCharDevQEnum *r)
2604 p->rng_fault_state = True;
2605 return WERR_NOT_SUPPORTED;
2608 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2609 struct srvsvc_NetCharDevQGetInfo *r)
2611 p->rng_fault_state = True;
2612 return WERR_NOT_SUPPORTED;
2615 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2616 struct srvsvc_NetCharDevQSetInfo *r)
2618 p->rng_fault_state = True;
2619 return WERR_NOT_SUPPORTED;
2622 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2623 struct srvsvc_NetCharDevQPurge *r)
2625 p->rng_fault_state = True;
2626 return WERR_NOT_SUPPORTED;
2629 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2630 struct srvsvc_NetCharDevQPurgeSelf *r)
2632 p->rng_fault_state = True;
2633 return WERR_NOT_SUPPORTED;
2636 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2637 struct srvsvc_NetFileGetInfo *r)
2639 p->rng_fault_state = True;
2640 return WERR_NOT_SUPPORTED;
2643 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2644 struct srvsvc_NetShareCheck *r)
2646 p->rng_fault_state = True;
2647 return WERR_NOT_SUPPORTED;
2650 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2651 struct srvsvc_NetServerStatisticsGet *r)
2653 p->rng_fault_state = True;
2654 return WERR_NOT_SUPPORTED;
2657 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2658 struct srvsvc_NetTransportAdd *r)
2660 p->rng_fault_state = True;
2661 return WERR_NOT_SUPPORTED;
2664 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2665 struct srvsvc_NetTransportEnum *r)
2667 p->rng_fault_state = True;
2668 return WERR_NOT_SUPPORTED;
2671 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2672 struct srvsvc_NetTransportDel *r)
2674 p->rng_fault_state = True;
2675 return WERR_NOT_SUPPORTED;
2678 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2679 struct srvsvc_NetSetServiceBits *r)
2681 p->rng_fault_state = True;
2682 return WERR_NOT_SUPPORTED;
2685 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2686 struct srvsvc_NetPathType *r)
2688 p->rng_fault_state = True;
2689 return WERR_NOT_SUPPORTED;
2692 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2693 struct srvsvc_NetPathCanonicalize *r)
2695 p->rng_fault_state = True;
2696 return WERR_NOT_SUPPORTED;
2699 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2700 struct srvsvc_NetPathCompare *r)
2702 p->rng_fault_state = True;
2703 return WERR_NOT_SUPPORTED;
2706 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2707 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2709 p->rng_fault_state = True;
2710 return WERR_NOT_SUPPORTED;
2713 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2714 struct srvsvc_NetPRNameCompare *r)
2716 p->rng_fault_state = True;
2717 return WERR_NOT_SUPPORTED;
2720 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2721 struct srvsvc_NetShareDelStart *r)
2723 p->rng_fault_state = True;
2724 return WERR_NOT_SUPPORTED;
2727 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2728 struct srvsvc_NetShareDelCommit *r)
2730 p->rng_fault_state = True;
2731 return WERR_NOT_SUPPORTED;
2734 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2735 struct srvsvc_NetServerTransportAddEx *r)
2737 p->rng_fault_state = True;
2738 return WERR_NOT_SUPPORTED;
2741 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2742 struct srvsvc_NetServerSetServiceBitsEx *r)
2744 p->rng_fault_state = True;
2745 return WERR_NOT_SUPPORTED;
2748 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2749 struct srvsvc_NETRDFSGETVERSION *r)
2751 p->rng_fault_state = True;
2752 return WERR_NOT_SUPPORTED;
2755 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2756 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2758 p->rng_fault_state = True;
2759 return WERR_NOT_SUPPORTED;
2762 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2763 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2765 p->rng_fault_state = True;
2766 return WERR_NOT_SUPPORTED;
2769 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2770 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2772 p->rng_fault_state = True;
2773 return WERR_NOT_SUPPORTED;
2776 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2777 struct srvsvc_NETRDFSSETSERVERINFO *r)
2779 p->rng_fault_state = True;
2780 return WERR_NOT_SUPPORTED;
2783 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2784 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2786 p->rng_fault_state = True;
2787 return WERR_NOT_SUPPORTED;
2790 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2791 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2793 p->rng_fault_state = True;
2794 return WERR_NOT_SUPPORTED;
2797 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2798 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2800 p->rng_fault_state = True;
2801 return WERR_NOT_SUPPORTED;
2804 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2805 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2807 p->rng_fault_state = True;
2808 return WERR_NOT_SUPPORTED;
2811 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2812 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2814 p->rng_fault_state = True;
2815 return WERR_NOT_SUPPORTED;
2818 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2819 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2821 p->rng_fault_state = True;
2822 return WERR_NOT_SUPPORTED;