smbd: Fix calls to create_conn_struct_cwd to be correctly indented.
[Samba/gebeck_regimport.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob2d5846685050f41c285d6113362343bbd01899dd
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 /*******************************************************************
64 ********************************************************************/
66 static void enum_file_fn( const struct share_mode_entry *e,
67 const char *sharepath, const char *fname,
68 void *private_data )
70 struct file_enum_count *fenum =
71 (struct file_enum_count *)private_data;
73 struct srvsvc_NetFileInfo3 *f;
74 int i = fenum->ctr3->count;
75 files_struct fsp;
76 struct byte_range_lock *brl;
77 int num_locks = 0;
78 char *fullpath = NULL;
79 uint32 permissions;
80 const char *username;
82 /* If the pid was not found delete the entry from connections.tdb */
84 if ( !process_exists(e->pid) ) {
85 return;
88 username = uidtoname(e->uid);
90 if ((fenum->username != NULL)
91 && !strequal(username, fenum->username)) {
92 return;
95 f = talloc_realloc(fenum->ctx, fenum->ctr3->array,
96 struct srvsvc_NetFileInfo3, i+1);
97 if ( !f ) {
98 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
99 return;
101 fenum->ctr3->array = f;
103 /* need to count the number of locks on a file */
105 ZERO_STRUCT( fsp );
106 fsp.file_id = e->id;
108 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
109 num_locks = brl->num_locks;
110 TALLOC_FREE(brl);
113 if ( strcmp( fname, "." ) == 0 ) {
114 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
115 } else {
116 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
117 sharepath, fname );
119 if (!fullpath) {
120 return;
122 string_replace( fullpath, '/', '\\' );
124 /* mask out create (what ever that is) */
125 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
127 /* now fill in the srvsvc_NetFileInfo3 struct */
129 fenum->ctr3->array[i].fid =
130 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
131 fenum->ctr3->array[i].permissions = permissions;
132 fenum->ctr3->array[i].num_locks = num_locks;
133 fenum->ctr3->array[i].path = fullpath;
134 fenum->ctr3->array[i].user = username;
136 fenum->ctr3->count++;
139 /*******************************************************************
140 ********************************************************************/
142 static WERROR net_enum_files(TALLOC_CTX *ctx,
143 const char *username,
144 struct srvsvc_NetFileCtr3 **ctr3,
145 uint32_t resume)
147 struct file_enum_count f_enum_cnt;
149 f_enum_cnt.ctx = ctx;
150 f_enum_cnt.username = username;
151 f_enum_cnt.ctr3 = *ctr3;
153 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
155 *ctr3 = f_enum_cnt.ctr3;
157 return WERR_OK;
160 /*******************************************************************
161 Utility function to get the 'type' of a share from an snum.
162 ********************************************************************/
163 static enum srvsvc_ShareType get_share_type(int snum)
165 /* work out the share type */
166 enum srvsvc_ShareType type = STYPE_DISKTREE;
168 if (lp_print_ok(snum)) {
169 type = lp_administrative_share(snum)
170 ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
172 if (strequal(lp_fstype(talloc_tos(), snum), "IPC")) {
173 type = lp_administrative_share(snum)
174 ? STYPE_IPC_HIDDEN : STYPE_IPC;
176 return type;
179 /*******************************************************************
180 Fill in a share info level 0 structure.
181 ********************************************************************/
183 static void init_srv_share_info_0(struct pipes_struct *p,
184 struct srvsvc_NetShareInfo0 *r, int snum)
186 r->name = lp_servicename(talloc_tos(), snum);
189 /*******************************************************************
190 Fill in a share info level 1 structure.
191 ********************************************************************/
193 static void init_srv_share_info_1(struct pipes_struct *p,
194 struct srvsvc_NetShareInfo1 *r,
195 int snum)
197 char *net_name = lp_servicename(talloc_tos(), snum);
198 char *remark = lp_comment(p->mem_ctx, snum);
200 if (remark) {
201 remark = talloc_sub_advanced(
202 p->mem_ctx, lp_servicename(talloc_tos(), snum),
203 get_current_username(), lp_pathname(talloc_tos(), snum),
204 p->session_info->unix_token->uid, get_current_username(),
205 "", remark);
208 r->name = net_name;
209 r->type = get_share_type(snum);
210 r->comment = remark ? remark : "";
213 /*******************************************************************
214 Fill in a share info level 2 structure.
215 ********************************************************************/
217 static void init_srv_share_info_2(struct pipes_struct *p,
218 struct srvsvc_NetShareInfo2 *r,
219 int snum)
221 char *remark = NULL;
222 char *path = NULL;
223 int max_connections = lp_max_connections(snum);
224 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
225 char *net_name = lp_servicename(talloc_tos(), snum);
227 remark = lp_comment(p->mem_ctx, snum);
228 if (remark) {
229 remark = talloc_sub_advanced(
230 p->mem_ctx, lp_servicename(talloc_tos(), snum),
231 get_current_username(), lp_pathname(talloc_tos(), snum),
232 p->session_info->unix_token->uid, get_current_username(),
233 "", remark);
235 path = talloc_asprintf(p->mem_ctx,
236 "C:%s", lp_pathname(talloc_tos(), snum));
238 if (path) {
240 * Change / to \\ so that win2k will see it as a valid path.
241 * This was added to enable use of browsing in win2k add
242 * share dialog.
245 string_replace(path, '/', '\\');
248 r->name = net_name;
249 r->type = get_share_type(snum);
250 r->comment = remark ? remark : "";
251 r->permissions = 0;
252 r->max_users = max_uses;
253 r->current_users = count_current_connections(net_name, false);
254 r->path = path ? path : "";
255 r->password = "";
258 /*******************************************************************
259 Map any generic bits to file specific bits.
260 ********************************************************************/
262 static void map_generic_share_sd_bits(struct security_descriptor *psd)
264 int i;
265 struct security_acl *ps_dacl = NULL;
267 if (!psd)
268 return;
270 ps_dacl = psd->dacl;
271 if (!ps_dacl)
272 return;
274 for (i = 0; i < ps_dacl->num_aces; i++) {
275 struct security_ace *psa = &ps_dacl->aces[i];
276 uint32 orig_mask = psa->access_mask;
278 se_map_generic(&psa->access_mask, &file_generic_mapping);
279 psa->access_mask |= orig_mask;
283 /*******************************************************************
284 Fill in a share info level 501 structure.
285 ********************************************************************/
287 static void init_srv_share_info_501(struct pipes_struct *p,
288 struct srvsvc_NetShareInfo501 *r, int snum)
290 const char *net_name = lp_servicename(talloc_tos(), snum);
291 char *remark = lp_comment(p->mem_ctx, snum);
293 if (remark) {
294 remark = talloc_sub_advanced(
295 p->mem_ctx, lp_servicename(talloc_tos(), snum),
296 get_current_username(), lp_pathname(talloc_tos(), snum),
297 p->session_info->unix_token->uid, get_current_username(),
298 "", remark);
301 r->name = net_name;
302 r->type = get_share_type(snum);
303 r->comment = remark ? remark : "";
304 r->csc_policy = (lp_csc_policy(snum) << 4);
307 /*******************************************************************
308 Fill in a share info level 502 structure.
309 ********************************************************************/
311 static void init_srv_share_info_502(struct pipes_struct *p,
312 struct srvsvc_NetShareInfo502 *r, int snum)
314 const char *net_name = lp_servicename(talloc_tos(), snum);
315 char *path = NULL;
316 struct security_descriptor *sd = NULL;
317 struct sec_desc_buf *sd_buf = NULL;
318 size_t sd_size = 0;
319 TALLOC_CTX *ctx = p->mem_ctx;
320 char *remark = lp_comment(ctx, snum);
322 if (remark) {
323 remark = talloc_sub_advanced(
324 p->mem_ctx, lp_servicename(talloc_tos(), snum),
325 get_current_username(), lp_pathname(talloc_tos(), snum),
326 p->session_info->unix_token->uid, get_current_username(),
327 "", remark);
329 path = talloc_asprintf(ctx, "C:%s", lp_pathname(talloc_tos(), snum));
330 if (path) {
332 * Change / to \\ so that win2k will see it as a valid path. This was added to
333 * enable use of browsing in win2k add share dialog.
335 string_replace(path, '/', '\\');
338 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
340 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
342 r->name = net_name;
343 r->type = get_share_type(snum);
344 r->comment = remark ? remark : "";
345 r->permissions = 0;
346 r->max_users = (uint32_t)-1;
347 r->current_users = 1; /* ??? */
348 r->path = path ? path : "";
349 r->password = "";
350 r->sd_buf = *sd_buf;
353 /***************************************************************************
354 Fill in a share info level 1004 structure.
355 ***************************************************************************/
357 static void init_srv_share_info_1004(struct pipes_struct *p,
358 struct srvsvc_NetShareInfo1004 *r,
359 int snum)
361 char *remark = lp_comment(p->mem_ctx, snum);
363 if (remark) {
364 remark = talloc_sub_advanced(
365 p->mem_ctx, lp_servicename(talloc_tos(), snum),
366 get_current_username(), lp_pathname(talloc_tos(), snum),
367 p->session_info->unix_token->uid, get_current_username(),
368 "", remark);
371 r->comment = remark ? remark : "";
374 /***************************************************************************
375 Fill in a share info level 1005 structure.
376 ***************************************************************************/
378 static void init_srv_share_info_1005(struct pipes_struct *p,
379 struct srvsvc_NetShareInfo1005 *r,
380 int snum)
382 uint32_t dfs_flags = 0;
384 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
385 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
388 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
390 r->dfs_flags = dfs_flags;
393 /***************************************************************************
394 Fill in a share info level 1006 structure.
395 ***************************************************************************/
397 static void init_srv_share_info_1006(struct pipes_struct *p,
398 struct srvsvc_NetShareInfo1006 *r,
399 int snum)
401 r->max_users = (uint32_t)-1;
404 /***************************************************************************
405 Fill in a share info level 1007 structure.
406 ***************************************************************************/
408 static void init_srv_share_info_1007(struct pipes_struct *p,
409 struct srvsvc_NetShareInfo1007 *r,
410 int snum)
412 r->flags = 0;
413 r->alternate_directory_name = "";
416 /*******************************************************************
417 Fill in a share info level 1501 structure.
418 ********************************************************************/
420 static void init_srv_share_info_1501(struct pipes_struct *p,
421 struct sec_desc_buf **r,
422 int snum)
424 struct security_descriptor *sd;
425 struct sec_desc_buf *sd_buf = NULL;
426 size_t sd_size;
427 TALLOC_CTX *ctx = p->mem_ctx;
429 sd = get_share_security(ctx, lp_servicename(talloc_tos(), snum), &sd_size);
430 if (sd) {
431 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
434 *r = sd_buf;
437 /*******************************************************************
438 True if it ends in '$'.
439 ********************************************************************/
441 static bool is_hidden_share(int snum)
443 const char *net_name = lp_servicename(talloc_tos(), snum);
445 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
448 /*******************************************************************
449 Verify user is allowed to view share, access based enumeration
450 ********************************************************************/
451 static bool is_enumeration_allowed(struct pipes_struct *p,
452 int snum)
454 if (!lp_access_based_share_enum(snum))
455 return true;
457 return share_access_check(p->session_info->security_token,
458 lp_servicename(talloc_tos(), snum),
459 FILE_READ_DATA, NULL);
462 /*******************************************************************
463 Fill in a share info structure.
464 ********************************************************************/
466 static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
467 struct srvsvc_NetShareInfoCtr *info_ctr,
468 uint32_t *resume_handle_p,
469 uint32_t *total_entries,
470 bool all_shares)
472 int num_entries = 0;
473 int alloc_entries = 0;
474 int num_services = 0;
475 int snum;
476 TALLOC_CTX *ctx = p->mem_ctx;
477 int i = 0;
478 int valid_share_count = 0;
479 bool *allowed = 0;
480 union srvsvc_NetShareCtr ctr;
481 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
483 DEBUG(5,("init_srv_share_info_ctr\n"));
485 /* Ensure all the usershares are loaded. */
486 become_root();
487 load_usershare_shares(NULL, connections_snum_used);
488 load_registry_shares();
489 num_services = lp_numservices();
490 unbecome_root();
492 allowed = talloc_zero_array(ctx, bool, num_services);
493 W_ERROR_HAVE_NO_MEMORY(allowed);
495 /* Count the number of entries. */
496 for (snum = 0; snum < num_services; snum++) {
497 if (lp_browseable(snum) && lp_snum_ok(snum) &&
498 is_enumeration_allowed(p, snum) &&
499 (all_shares || !is_hidden_share(snum)) ) {
500 DEBUG(10, ("counting service %s\n",
501 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
502 allowed[snum] = true;
503 num_entries++;
504 } else {
505 DEBUG(10, ("NOT counting service %s\n",
506 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
510 if (!num_entries || (resume_handle >= num_entries)) {
511 return WERR_OK;
514 /* Calculate alloc entries. */
515 alloc_entries = num_entries - resume_handle;
516 switch (info_ctr->level) {
517 case 0:
518 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
519 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
521 ctr.ctr0->count = alloc_entries;
522 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
523 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
525 for (snum = 0; snum < num_services; snum++) {
526 if (allowed[snum] &&
527 (resume_handle <= (i + valid_share_count++)) ) {
528 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
532 break;
534 case 1:
535 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
536 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
538 ctr.ctr1->count = alloc_entries;
539 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
540 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
542 for (snum = 0; snum < num_services; snum++) {
543 if (allowed[snum] &&
544 (resume_handle <= (i + valid_share_count++)) ) {
545 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
549 break;
551 case 2:
552 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
553 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
555 ctr.ctr2->count = alloc_entries;
556 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
557 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
559 for (snum = 0; snum < num_services; snum++) {
560 if (allowed[snum] &&
561 (resume_handle <= (i + valid_share_count++)) ) {
562 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
566 break;
568 case 501:
569 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
570 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
572 ctr.ctr501->count = alloc_entries;
573 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
574 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
576 for (snum = 0; snum < num_services; snum++) {
577 if (allowed[snum] &&
578 (resume_handle <= (i + valid_share_count++)) ) {
579 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
583 break;
585 case 502:
586 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
587 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
589 ctr.ctr502->count = alloc_entries;
590 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
591 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
593 for (snum = 0; snum < num_services; snum++) {
594 if (allowed[snum] &&
595 (resume_handle <= (i + valid_share_count++)) ) {
596 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
600 break;
602 case 1004:
603 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
604 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
606 ctr.ctr1004->count = alloc_entries;
607 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
608 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
610 for (snum = 0; snum < num_services; snum++) {
611 if (allowed[snum] &&
612 (resume_handle <= (i + valid_share_count++)) ) {
613 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
617 break;
619 case 1005:
620 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
621 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
623 ctr.ctr1005->count = alloc_entries;
624 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
625 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
627 for (snum = 0; snum < num_services; snum++) {
628 if (allowed[snum] &&
629 (resume_handle <= (i + valid_share_count++)) ) {
630 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
634 break;
636 case 1006:
637 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
638 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
640 ctr.ctr1006->count = alloc_entries;
641 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
642 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
644 for (snum = 0; snum < num_services; snum++) {
645 if (allowed[snum] &&
646 (resume_handle <= (i + valid_share_count++)) ) {
647 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
651 break;
653 case 1007:
654 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
655 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
657 ctr.ctr1007->count = alloc_entries;
658 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
659 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
661 for (snum = 0; snum < num_services; snum++) {
662 if (allowed[snum] &&
663 (resume_handle <= (i + valid_share_count++)) ) {
664 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
668 break;
670 case 1501:
671 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
672 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
674 ctr.ctr1501->count = alloc_entries;
675 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
676 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
678 for (snum = 0; snum < num_services; snum++) {
679 if (allowed[snum] &&
680 (resume_handle <= (i + valid_share_count++)) ) {
681 struct sec_desc_buf *sd_buf = NULL;
682 init_srv_share_info_1501(p, &sd_buf, snum);
683 ctr.ctr1501->array[i++] = *sd_buf;
687 break;
689 default:
690 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
691 info_ctr->level));
692 return WERR_UNKNOWN_LEVEL;
695 *total_entries = alloc_entries;
696 if (resume_handle_p) {
697 if (all_shares) {
698 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
699 } else {
700 *resume_handle_p = num_entries;
704 info_ctr->ctr = ctr;
706 return WERR_OK;
709 /*******************************************************************
710 fill in a sess info level 0 structure.
711 ********************************************************************/
713 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
714 struct srvsvc_NetSessCtr0 *ctr0,
715 uint32_t *resume_handle_p,
716 uint32_t *total_entries)
718 struct sessionid *session_list;
719 uint32_t num_entries = 0;
720 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
721 *total_entries = list_sessions(p->mem_ctx, &session_list);
723 DEBUG(5,("init_srv_sess_info_0\n"));
725 if (ctr0 == NULL) {
726 if (resume_handle_p) {
727 *resume_handle_p = 0;
729 return WERR_OK;
732 for (; resume_handle < *total_entries; resume_handle++) {
734 ctr0->array = talloc_realloc(p->mem_ctx,
735 ctr0->array,
736 struct srvsvc_NetSessInfo0,
737 num_entries+1);
738 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
740 ctr0->array[num_entries].client =
741 session_list[resume_handle].remote_machine;
743 num_entries++;
746 ctr0->count = num_entries;
748 if (resume_handle_p) {
749 if (*resume_handle_p >= *total_entries) {
750 *resume_handle_p = 0;
751 } else {
752 *resume_handle_p = resume_handle;
756 return WERR_OK;
759 /*******************************************************************
760 ********************************************************************/
762 static void sess_file_fn( const struct share_mode_entry *e,
763 const char *sharepath, const char *fname,
764 void *data )
766 struct sess_file_count *sess = (struct sess_file_count *)data;
768 if (serverid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid)) {
769 sess->count++;
772 return;
775 /*******************************************************************
776 ********************************************************************/
778 static int net_count_files( uid_t uid, struct server_id pid )
780 struct sess_file_count s_file_cnt;
782 s_file_cnt.count = 0;
783 s_file_cnt.uid = uid;
784 s_file_cnt.pid = pid;
786 share_mode_forall( sess_file_fn, &s_file_cnt );
788 return s_file_cnt.count;
791 /*******************************************************************
792 fill in a sess info level 1 structure.
793 ********************************************************************/
795 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
796 struct srvsvc_NetSessCtr1 *ctr1,
797 uint32_t *resume_handle_p,
798 uint32_t *total_entries)
800 struct sessionid *session_list;
801 uint32_t num_entries = 0;
802 time_t now = time(NULL);
803 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
805 ZERO_STRUCTP(ctr1);
807 if (ctr1 == NULL) {
808 if (resume_handle_p) {
809 *resume_handle_p = 0;
811 return WERR_OK;
814 *total_entries = list_sessions(p->mem_ctx, &session_list);
816 for (; resume_handle < *total_entries; resume_handle++) {
817 uint32 num_files;
818 uint32 connect_time;
819 struct passwd *pw = getpwnam(session_list[resume_handle].username);
820 bool guest;
822 if ( !pw ) {
823 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
824 session_list[resume_handle].username));
825 continue;
828 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
829 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
830 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
832 ctr1->array = talloc_realloc(p->mem_ctx,
833 ctr1->array,
834 struct srvsvc_NetSessInfo1,
835 num_entries+1);
836 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
838 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
839 ctr1->array[num_entries].user = session_list[resume_handle].username;
840 ctr1->array[num_entries].num_open = num_files;
841 ctr1->array[num_entries].time = connect_time;
842 ctr1->array[num_entries].idle_time = 0;
843 ctr1->array[num_entries].user_flags = guest;
845 num_entries++;
848 ctr1->count = num_entries;
850 if (resume_handle_p) {
851 if (*resume_handle_p >= *total_entries) {
852 *resume_handle_p = 0;
853 } else {
854 *resume_handle_p = resume_handle;
858 return WERR_OK;
861 /*******************************************************************
862 fill in a conn info level 0 structure.
863 ********************************************************************/
865 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
866 uint32_t *resume_handle_p,
867 uint32_t *total_entries)
869 uint32_t num_entries = 0;
870 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
872 DEBUG(5,("init_srv_conn_info_0\n"));
874 if (ctr0 == NULL) {
875 if (resume_handle_p) {
876 *resume_handle_p = 0;
878 return WERR_OK;
881 *total_entries = 1;
883 ZERO_STRUCTP(ctr0);
885 for (; resume_handle < *total_entries; resume_handle++) {
887 ctr0->array = talloc_realloc(talloc_tos(),
888 ctr0->array,
889 struct srvsvc_NetConnInfo0,
890 num_entries+1);
891 if (!ctr0->array) {
892 return WERR_NOMEM;
895 ctr0->array[num_entries].conn_id = *total_entries;
897 /* move on to creating next connection */
898 num_entries++;
901 ctr0->count = num_entries;
902 *total_entries = num_entries;
904 if (resume_handle_p) {
905 if (*resume_handle_p >= *total_entries) {
906 *resume_handle_p = 0;
907 } else {
908 *resume_handle_p = resume_handle;
912 return WERR_OK;
915 /*******************************************************************
916 fill in a conn info level 1 structure.
917 ********************************************************************/
919 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
920 uint32_t *resume_handle_p,
921 uint32_t *total_entries)
923 uint32_t num_entries = 0;
924 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
926 DEBUG(5,("init_srv_conn_info_1\n"));
928 if (ctr1 == NULL) {
929 if (resume_handle_p) {
930 *resume_handle_p = 0;
932 return WERR_OK;
935 *total_entries = 1;
937 ZERO_STRUCTP(ctr1);
939 for (; resume_handle < *total_entries; resume_handle++) {
941 ctr1->array = talloc_realloc(talloc_tos(),
942 ctr1->array,
943 struct srvsvc_NetConnInfo1,
944 num_entries+1);
945 if (!ctr1->array) {
946 return WERR_NOMEM;
949 ctr1->array[num_entries].conn_id = *total_entries;
950 ctr1->array[num_entries].conn_type = 0x3;
951 ctr1->array[num_entries].num_open = 1;
952 ctr1->array[num_entries].num_users = 1;
953 ctr1->array[num_entries].conn_time = 3;
954 ctr1->array[num_entries].user = "dummy_user";
955 ctr1->array[num_entries].share = "IPC$";
957 /* move on to creating next connection */
958 num_entries++;
961 ctr1->count = num_entries;
962 *total_entries = num_entries;
964 if (resume_handle_p) {
965 if (*resume_handle_p >= *total_entries) {
966 *resume_handle_p = 0;
967 } else {
968 *resume_handle_p = resume_handle;
972 return WERR_OK;
975 /*******************************************************************
976 _srvsvc_NetFileEnum
977 *******************************************************************/
979 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
980 struct srvsvc_NetFileEnum *r)
982 TALLOC_CTX *ctx = NULL;
983 struct srvsvc_NetFileCtr3 *ctr3;
984 uint32_t resume_hnd = 0;
985 WERROR werr;
987 switch (r->in.info_ctr->level) {
988 case 3:
989 break;
990 default:
991 return WERR_UNKNOWN_LEVEL;
994 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
995 p->session_info->security_token)) {
996 DEBUG(1, ("Enumerating files only allowed for "
997 "administrators\n"));
998 return WERR_ACCESS_DENIED;
1001 ctx = talloc_tos();
1002 ctr3 = r->in.info_ctr->ctr.ctr3;
1003 if (!ctr3) {
1004 werr = WERR_INVALID_PARAM;
1005 goto done;
1008 /* TODO -- Windows enumerates
1009 (b) active pipes
1010 (c) open directories and files */
1012 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1013 if (!W_ERROR_IS_OK(werr)) {
1014 goto done;
1017 *r->out.totalentries = ctr3->count;
1018 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1019 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1021 werr = WERR_OK;
1023 done:
1024 return werr;
1027 /*******************************************************************
1028 _srvsvc_NetSrvGetInfo
1029 ********************************************************************/
1031 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1032 struct srvsvc_NetSrvGetInfo *r)
1034 WERROR status = WERR_OK;
1036 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1038 if (!pipe_access_check(p)) {
1039 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1040 return WERR_ACCESS_DENIED;
1043 switch (r->in.level) {
1045 /* Technically level 102 should only be available to
1046 Administrators but there isn't anything super-secret
1047 here, as most of it is made up. */
1049 case 102: {
1050 struct srvsvc_NetSrvInfo102 *info102;
1052 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1053 if (!info102) {
1054 return WERR_NOMEM;
1057 info102->platform_id = PLATFORM_ID_NT;
1058 info102->server_name = lp_netbios_name();
1059 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1060 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1061 info102->server_type = lp_default_server_announce();
1062 info102->comment = string_truncate(lp_serverstring(talloc_tos()),
1063 MAX_SERVER_STRING_LENGTH);
1064 info102->users = 0xffffffff;
1065 info102->disc = 0xf;
1066 info102->hidden = 0;
1067 info102->announce = 240;
1068 info102->anndelta = 3000;
1069 info102->licenses = 100000;
1070 info102->userpath = "C:\\";
1072 r->out.info->info102 = info102;
1073 break;
1075 case 101: {
1076 struct srvsvc_NetSrvInfo101 *info101;
1078 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1079 if (!info101) {
1080 return WERR_NOMEM;
1083 info101->platform_id = PLATFORM_ID_NT;
1084 info101->server_name = lp_netbios_name();
1085 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1086 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1087 info101->server_type = lp_default_server_announce();
1088 info101->comment = string_truncate(lp_serverstring(talloc_tos()),
1089 MAX_SERVER_STRING_LENGTH);
1091 r->out.info->info101 = info101;
1092 break;
1094 case 100: {
1095 struct srvsvc_NetSrvInfo100 *info100;
1097 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1098 if (!info100) {
1099 return WERR_NOMEM;
1102 info100->platform_id = PLATFORM_ID_NT;
1103 info100->server_name = lp_netbios_name();
1105 r->out.info->info100 = info100;
1107 break;
1109 default:
1110 status = WERR_UNKNOWN_LEVEL;
1111 break;
1114 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1116 return status;
1119 /*******************************************************************
1120 _srvsvc_NetSrvSetInfo
1121 ********************************************************************/
1123 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1124 struct srvsvc_NetSrvSetInfo *r)
1126 WERROR status = WERR_OK;
1128 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1130 /* Set up the net server set info structure. */
1132 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1134 return status;
1137 /*******************************************************************
1138 _srvsvc_NetConnEnum
1139 ********************************************************************/
1141 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1142 struct srvsvc_NetConnEnum *r)
1144 WERROR werr;
1146 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1148 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1149 p->session_info->security_token)) {
1150 DEBUG(1, ("Enumerating connections only allowed for "
1151 "administrators\n"));
1152 return WERR_ACCESS_DENIED;
1155 switch (r->in.info_ctr->level) {
1156 case 0:
1157 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1158 r->in.resume_handle,
1159 r->out.totalentries);
1160 break;
1161 case 1:
1162 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1163 r->in.resume_handle,
1164 r->out.totalentries);
1165 break;
1166 default:
1167 return WERR_UNKNOWN_LEVEL;
1170 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1172 return werr;
1175 /*******************************************************************
1176 _srvsvc_NetSessEnum
1177 ********************************************************************/
1179 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1180 struct srvsvc_NetSessEnum *r)
1182 WERROR werr;
1184 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1186 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1187 p->session_info->security_token)) {
1188 DEBUG(1, ("Enumerating sessions only allowed for "
1189 "administrators\n"));
1190 return WERR_ACCESS_DENIED;
1193 switch (r->in.info_ctr->level) {
1194 case 0:
1195 werr = init_srv_sess_info_0(p,
1196 r->in.info_ctr->ctr.ctr0,
1197 r->in.resume_handle,
1198 r->out.totalentries);
1199 break;
1200 case 1:
1201 werr = init_srv_sess_info_1(p,
1202 r->in.info_ctr->ctr.ctr1,
1203 r->in.resume_handle,
1204 r->out.totalentries);
1205 break;
1206 default:
1207 return WERR_UNKNOWN_LEVEL;
1210 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1212 return werr;
1215 /*******************************************************************
1216 _srvsvc_NetSessDel
1217 ********************************************************************/
1219 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1220 struct srvsvc_NetSessDel *r)
1222 struct sessionid *session_list;
1223 int num_sessions, snum;
1224 const char *username;
1225 const char *machine;
1226 bool not_root = False;
1227 WERROR werr;
1229 username = r->in.user;
1230 machine = r->in.client;
1232 /* strip leading backslashes if any */
1233 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1234 machine += 2;
1237 num_sessions = list_sessions(p->mem_ctx, &session_list);
1239 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1241 werr = WERR_ACCESS_DENIED;
1243 /* fail out now if you are not root or not a domain admin */
1245 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1246 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1247 DOMAIN_RID_ADMINS))) {
1249 goto done;
1252 for (snum = 0; snum < num_sessions; snum++) {
1254 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1255 strequal(session_list[snum].remote_machine, machine)) {
1257 NTSTATUS ntstat;
1259 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1260 not_root = True;
1261 become_root();
1264 ntstat = messaging_send(p->msg_ctx,
1265 session_list[snum].pid,
1266 MSG_SHUTDOWN, &data_blob_null);
1268 if (NT_STATUS_IS_OK(ntstat))
1269 werr = WERR_OK;
1271 if (not_root)
1272 unbecome_root();
1276 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1278 done:
1280 return werr;
1283 /*******************************************************************
1284 _srvsvc_NetShareEnumAll
1285 ********************************************************************/
1287 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1288 struct srvsvc_NetShareEnumAll *r)
1290 WERROR werr;
1292 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1294 if (!pipe_access_check(p)) {
1295 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1296 return WERR_ACCESS_DENIED;
1299 /* Create the list of shares for the response. */
1300 werr = init_srv_share_info_ctr(p,
1301 r->in.info_ctr,
1302 r->in.resume_handle,
1303 r->out.totalentries,
1304 true);
1306 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1308 return werr;
1311 /*******************************************************************
1312 _srvsvc_NetShareEnum
1313 ********************************************************************/
1315 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1316 struct srvsvc_NetShareEnum *r)
1318 WERROR werr;
1320 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1322 if (!pipe_access_check(p)) {
1323 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1324 return WERR_ACCESS_DENIED;
1327 /* Create the list of shares for the response. */
1328 werr = init_srv_share_info_ctr(p,
1329 r->in.info_ctr,
1330 r->in.resume_handle,
1331 r->out.totalentries,
1332 false);
1334 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1336 return werr;
1339 /*******************************************************************
1340 _srvsvc_NetShareGetInfo
1341 ********************************************************************/
1343 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1344 struct srvsvc_NetShareGetInfo *r)
1346 WERROR status = WERR_OK;
1347 char *share_name = NULL;
1348 int snum;
1349 union srvsvc_NetShareInfo *info = r->out.info;
1351 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1353 if (!r->in.share_name) {
1354 return WERR_INVALID_NAME;
1357 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1358 if (!share_name) {
1359 return WERR_NOMEM;
1361 if (snum < 0) {
1362 return WERR_INVALID_NAME;
1365 switch (r->in.level) {
1366 case 0:
1367 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1368 W_ERROR_HAVE_NO_MEMORY(info->info0);
1369 init_srv_share_info_0(p, info->info0, snum);
1370 break;
1371 case 1:
1372 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1373 W_ERROR_HAVE_NO_MEMORY(info->info1);
1374 init_srv_share_info_1(p, info->info1, snum);
1375 break;
1376 case 2:
1377 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1378 W_ERROR_HAVE_NO_MEMORY(info->info2);
1379 init_srv_share_info_2(p, info->info2, snum);
1380 break;
1381 case 501:
1382 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1383 W_ERROR_HAVE_NO_MEMORY(info->info501);
1384 init_srv_share_info_501(p, info->info501, snum);
1385 break;
1386 case 502:
1387 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1388 W_ERROR_HAVE_NO_MEMORY(info->info502);
1389 init_srv_share_info_502(p, info->info502, snum);
1390 break;
1391 case 1004:
1392 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1393 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1394 init_srv_share_info_1004(p, info->info1004, snum);
1395 break;
1396 case 1005:
1397 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1398 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1399 init_srv_share_info_1005(p, info->info1005, snum);
1400 break;
1401 case 1006:
1402 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1403 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1404 init_srv_share_info_1006(p, info->info1006, snum);
1405 break;
1406 case 1007:
1407 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1408 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1409 init_srv_share_info_1007(p, info->info1007, snum);
1410 break;
1411 case 1501:
1412 init_srv_share_info_1501(p, &info->info1501, snum);
1413 break;
1414 default:
1415 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1416 r->in.level));
1417 status = WERR_UNKNOWN_LEVEL;
1418 break;
1421 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1423 return status;
1426 /*******************************************************************
1427 _srvsvc_NetShareSetInfo. Modify share details.
1428 ********************************************************************/
1430 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1431 struct srvsvc_NetShareSetInfo *r)
1433 char *command = NULL;
1434 char *share_name = NULL;
1435 char *comment = NULL;
1436 const char *pathname = NULL;
1437 int type;
1438 int snum;
1439 int ret;
1440 char *path = NULL;
1441 struct security_descriptor *psd = NULL;
1442 bool is_disk_op = False;
1443 int max_connections = 0;
1444 TALLOC_CTX *ctx = p->mem_ctx;
1445 union srvsvc_NetShareInfo *info = r->in.info;
1447 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1449 if (!r->in.share_name) {
1450 return WERR_INVALID_NAME;
1453 if (r->out.parm_error) {
1454 *r->out.parm_error = 0;
1457 if ( strequal(r->in.share_name,"IPC$")
1458 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1459 || strequal(r->in.share_name,"global") )
1461 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1462 "modified by a remote user.\n",
1463 r->in.share_name ));
1464 return WERR_ACCESS_DENIED;
1467 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1468 if (!share_name) {
1469 return WERR_NOMEM;
1472 /* Does this share exist ? */
1473 if (snum < 0)
1474 return WERR_NET_NAME_NOT_FOUND;
1476 /* No change to printer shares. */
1477 if (lp_print_ok(snum))
1478 return WERR_ACCESS_DENIED;
1480 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1482 /* fail out now if you are not root and not a disk op */
1484 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1485 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1486 "SeDiskOperatorPrivilege privilege needed to modify "
1487 "share %s\n",
1488 (unsigned int)p->session_info->unix_token->uid,
1489 share_name ));
1490 return WERR_ACCESS_DENIED;
1493 switch (r->in.level) {
1494 case 1:
1495 pathname = lp_pathname(ctx, snum);
1496 comment = talloc_strdup(ctx, info->info1->comment);
1497 type = info->info1->type;
1498 psd = NULL;
1499 break;
1500 case 2:
1501 comment = talloc_strdup(ctx, info->info2->comment);
1502 pathname = info->info2->path;
1503 type = info->info2->type;
1504 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1505 0 : info->info2->max_users;
1506 psd = NULL;
1507 break;
1508 #if 0
1509 /* not supported on set but here for completeness */
1510 case 501:
1511 comment = talloc_strdup(ctx, info->info501->comment);
1512 type = info->info501->type;
1513 psd = NULL;
1514 break;
1515 #endif
1516 case 502:
1517 comment = talloc_strdup(ctx, info->info502->comment);
1518 pathname = info->info502->path;
1519 type = info->info502->type;
1520 psd = info->info502->sd_buf.sd;
1521 map_generic_share_sd_bits(psd);
1522 break;
1523 case 1004:
1524 pathname = lp_pathname(ctx, snum);
1525 comment = talloc_strdup(ctx, info->info1004->comment);
1526 type = STYPE_DISKTREE;
1527 break;
1528 case 1005:
1529 /* XP re-sets the csc policy even if it wasn't changed by the
1530 user, so we must compare it to see if it's what is set in
1531 smb.conf, so that we can contine other ops like setting
1532 ACLs on a share */
1533 if (((info->info1005->dfs_flags &
1534 SHARE_1005_CSC_POLICY_MASK) >>
1535 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1536 return WERR_OK;
1537 else {
1538 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1539 return WERR_ACCESS_DENIED;
1541 case 1006:
1542 case 1007:
1543 return WERR_ACCESS_DENIED;
1544 case 1501:
1545 pathname = lp_pathname(ctx, snum);
1546 comment = lp_comment(ctx, snum);
1547 psd = info->info1501->sd;
1548 map_generic_share_sd_bits(psd);
1549 type = STYPE_DISKTREE;
1550 break;
1551 default:
1552 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1553 r->in.level));
1554 return WERR_UNKNOWN_LEVEL;
1557 /* We can only modify disk shares. */
1558 if (type != STYPE_DISKTREE) {
1559 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1560 "disk share\n",
1561 share_name ));
1562 return WERR_ACCESS_DENIED;
1565 if (comment == NULL) {
1566 return WERR_NOMEM;
1569 /* Check if the pathname is valid. */
1570 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1571 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1572 pathname ));
1573 return WERR_OBJECT_PATH_INVALID;
1576 /* Ensure share name, pathname and comment don't contain '"' characters. */
1577 string_replace(share_name, '"', ' ');
1578 string_replace(path, '"', ' ');
1579 string_replace(comment, '"', ' ');
1581 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1582 lp_change_share_cmd(talloc_tos()) ? lp_change_share_cmd(talloc_tos()) : "NULL" ));
1584 /* Only call modify function if something changed. */
1586 if (strcmp(path, lp_pathname(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1587 || (lp_max_connections(snum) != max_connections)) {
1588 if (!lp_change_share_cmd(talloc_tos()) || !*lp_change_share_cmd(talloc_tos())) {
1589 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1590 return WERR_ACCESS_DENIED;
1593 command = talloc_asprintf(p->mem_ctx,
1594 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1595 lp_change_share_cmd(talloc_tos()),
1596 get_dyn_CONFIGFILE(),
1597 share_name,
1598 path,
1599 comment ? comment : "",
1600 max_connections);
1601 if (!command) {
1602 return WERR_NOMEM;
1605 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1607 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1609 if (is_disk_op)
1610 become_root();
1612 if ( (ret = smbrun(command, NULL)) == 0 ) {
1613 /* Tell everyone we updated smb.conf. */
1614 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1615 NULL, 0, NULL);
1618 if ( is_disk_op )
1619 unbecome_root();
1621 /********* END SeDiskOperatorPrivilege BLOCK *********/
1623 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1624 command, ret ));
1626 TALLOC_FREE(command);
1628 if ( ret != 0 )
1629 return WERR_ACCESS_DENIED;
1630 } else {
1631 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1632 share_name ));
1635 /* Replace SD if changed. */
1636 if (psd) {
1637 struct security_descriptor *old_sd;
1638 size_t sd_size;
1640 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1642 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1643 if (!set_share_security(share_name, psd))
1644 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1645 share_name ));
1649 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1651 return WERR_OK;
1654 /*******************************************************************
1655 _srvsvc_NetShareAdd.
1656 Call 'add_share_command "sharename" "pathname"
1657 "comment" "max connections = "
1658 ********************************************************************/
1660 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1661 struct srvsvc_NetShareAdd *r)
1663 char *command = NULL;
1664 char *share_name_in = NULL;
1665 char *share_name = NULL;
1666 char *comment = NULL;
1667 char *pathname = NULL;
1668 int type;
1669 int snum;
1670 int ret;
1671 char *path;
1672 struct security_descriptor *psd = NULL;
1673 bool is_disk_op;
1674 int max_connections = 0;
1675 TALLOC_CTX *ctx = p->mem_ctx;
1677 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1679 if (r->out.parm_error) {
1680 *r->out.parm_error = 0;
1683 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1685 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1686 return WERR_ACCESS_DENIED;
1688 if (!lp_add_share_cmd(talloc_tos()) || !*lp_add_share_cmd(talloc_tos())) {
1689 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1690 return WERR_ACCESS_DENIED;
1693 switch (r->in.level) {
1694 case 0:
1695 /* No path. Not enough info in a level 0 to do anything. */
1696 return WERR_ACCESS_DENIED;
1697 case 1:
1698 /* Not enough info in a level 1 to do anything. */
1699 return WERR_ACCESS_DENIED;
1700 case 2:
1701 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1702 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1703 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1704 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1705 0 : r->in.info->info2->max_users;
1706 type = r->in.info->info2->type;
1707 break;
1708 case 501:
1709 /* No path. Not enough info in a level 501 to do anything. */
1710 return WERR_ACCESS_DENIED;
1711 case 502:
1712 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1713 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1714 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1715 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1716 0 : r->in.info->info502->max_users;
1717 type = r->in.info->info502->type;
1718 psd = r->in.info->info502->sd_buf.sd;
1719 map_generic_share_sd_bits(psd);
1720 break;
1722 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1724 case 1004:
1725 case 1005:
1726 case 1006:
1727 case 1007:
1728 return WERR_ACCESS_DENIED;
1729 case 1501:
1730 /* DFS only level. */
1731 return WERR_ACCESS_DENIED;
1732 default:
1733 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1734 r->in.level));
1735 return WERR_UNKNOWN_LEVEL;
1738 /* check for invalid share names */
1740 if (!share_name_in || !validate_net_name(share_name_in,
1741 INVALID_SHARENAME_CHARS,
1742 strlen(share_name_in))) {
1743 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1744 share_name_in ? share_name_in : ""));
1745 return WERR_INVALID_NAME;
1748 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1749 || (lp_enable_asu_support() &&
1750 strequal(share_name_in,"ADMIN$"))) {
1751 return WERR_ACCESS_DENIED;
1754 snum = find_service(ctx, share_name_in, &share_name);
1755 if (!share_name) {
1756 return WERR_NOMEM;
1759 /* Share already exists. */
1760 if (snum >= 0) {
1761 return WERR_FILE_EXISTS;
1764 /* We can only add disk shares. */
1765 if (type != STYPE_DISKTREE) {
1766 return WERR_ACCESS_DENIED;
1769 /* Check if the pathname is valid. */
1770 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1771 return WERR_OBJECT_PATH_INVALID;
1774 /* Ensure share name, pathname and comment don't contain '"' characters. */
1775 string_replace(share_name_in, '"', ' ');
1776 string_replace(share_name, '"', ' ');
1777 string_replace(path, '"', ' ');
1778 if (comment) {
1779 string_replace(comment, '"', ' ');
1782 command = talloc_asprintf(ctx,
1783 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1784 lp_add_share_cmd(talloc_tos()),
1785 get_dyn_CONFIGFILE(),
1786 share_name_in,
1787 path,
1788 comment ? comment : "",
1789 max_connections);
1790 if (!command) {
1791 return WERR_NOMEM;
1794 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1796 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1798 if ( is_disk_op )
1799 become_root();
1801 /* FIXME: use libnetconf here - gd */
1803 if ( (ret = smbrun(command, NULL)) == 0 ) {
1804 /* Tell everyone we updated smb.conf. */
1805 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1806 NULL);
1809 if ( is_disk_op )
1810 unbecome_root();
1812 /********* END SeDiskOperatorPrivilege BLOCK *********/
1814 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1815 command, ret ));
1817 TALLOC_FREE(command);
1819 if ( ret != 0 )
1820 return WERR_ACCESS_DENIED;
1822 if (psd) {
1823 /* Note we use share_name here, not share_name_in as
1824 we need a canonicalized name for setting security. */
1825 if (!set_share_security(share_name, psd)) {
1826 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1827 share_name ));
1832 * We don't call reload_services() here, the message will
1833 * cause this to be done before the next packet is read
1834 * from the client. JRA.
1837 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1839 return WERR_OK;
1842 /*******************************************************************
1843 _srvsvc_NetShareDel
1844 Call "delete share command" with the share name as
1845 a parameter.
1846 ********************************************************************/
1848 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
1849 struct srvsvc_NetShareDel *r)
1851 char *command = NULL;
1852 char *share_name = NULL;
1853 int ret;
1854 int snum;
1855 bool is_disk_op;
1856 struct share_params *params;
1857 TALLOC_CTX *ctx = p->mem_ctx;
1859 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1861 if (!r->in.share_name) {
1862 return WERR_NET_NAME_NOT_FOUND;
1865 if ( strequal(r->in.share_name,"IPC$")
1866 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1867 || strequal(r->in.share_name,"global") )
1869 return WERR_ACCESS_DENIED;
1872 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1873 if (!share_name) {
1874 return WERR_NOMEM;
1877 if (snum < 0) {
1878 return WERR_NO_SUCH_SHARE;
1881 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1882 return WERR_NO_SUCH_SHARE;
1885 /* No change to printer shares. */
1886 if (lp_print_ok(snum))
1887 return WERR_ACCESS_DENIED;
1889 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1891 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1892 return WERR_ACCESS_DENIED;
1894 if (!lp_delete_share_cmd(talloc_tos()) || !*lp_delete_share_cmd(talloc_tos())) {
1895 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1896 return WERR_ACCESS_DENIED;
1899 command = talloc_asprintf(ctx,
1900 "%s \"%s\" \"%s\"",
1901 lp_delete_share_cmd(talloc_tos()),
1902 get_dyn_CONFIGFILE(),
1903 lp_servicename(talloc_tos(), snum));
1904 if (!command) {
1905 return WERR_NOMEM;
1908 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1910 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1912 if ( is_disk_op )
1913 become_root();
1915 if ( (ret = smbrun(command, NULL)) == 0 ) {
1916 /* Tell everyone we updated smb.conf. */
1917 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1918 NULL);
1921 if ( is_disk_op )
1922 unbecome_root();
1924 /********* END SeDiskOperatorPrivilege BLOCK *********/
1926 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1928 if ( ret != 0 )
1929 return WERR_ACCESS_DENIED;
1931 /* Delete the SD in the database. */
1932 delete_share_security(lp_servicename(talloc_tos(), params->service));
1934 lp_killservice(params->service);
1936 return WERR_OK;
1939 /*******************************************************************
1940 _srvsvc_NetShareDelSticky
1941 ********************************************************************/
1943 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
1944 struct srvsvc_NetShareDelSticky *r)
1946 struct srvsvc_NetShareDel q;
1948 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1950 q.in.server_unc = r->in.server_unc;
1951 q.in.share_name = r->in.share_name;
1952 q.in.reserved = r->in.reserved;
1954 return _srvsvc_NetShareDel(p, &q);
1957 /*******************************************************************
1958 _srvsvc_NetRemoteTOD
1959 ********************************************************************/
1961 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
1962 struct srvsvc_NetRemoteTOD *r)
1964 struct srvsvc_NetRemoteTODInfo *tod;
1965 struct tm *t;
1966 time_t unixdate = time(NULL);
1968 /* We do this call first as if we do it *after* the gmtime call
1969 it overwrites the pointed-to values. JRA */
1971 uint32 zone = get_time_zone(unixdate)/60;
1973 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1975 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1976 return WERR_NOMEM;
1978 *r->out.info = tod;
1980 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1982 t = gmtime(&unixdate);
1984 /* set up the */
1985 tod->elapsed = unixdate;
1986 tod->msecs = 0;
1987 tod->hours = t->tm_hour;
1988 tod->mins = t->tm_min;
1989 tod->secs = t->tm_sec;
1990 tod->hunds = 0;
1991 tod->timezone = zone;
1992 tod->tinterval = 10000;
1993 tod->day = t->tm_mday;
1994 tod->month = t->tm_mon + 1;
1995 tod->year = 1900+t->tm_year;
1996 tod->weekday = t->tm_wday;
1998 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2000 return WERR_OK;
2003 /***********************************************************************************
2004 _srvsvc_NetGetFileSecurity
2005 Win9x NT tools get security descriptor.
2006 ***********************************************************************************/
2008 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2009 struct srvsvc_NetGetFileSecurity *r)
2011 struct smb_filename *smb_fname = NULL;
2012 size_t sd_size;
2013 char *servicename = NULL;
2014 SMB_STRUCT_STAT st;
2015 NTSTATUS nt_status;
2016 WERROR werr;
2017 connection_struct *conn = NULL;
2018 struct sec_desc_buf *sd_buf = NULL;
2019 files_struct *fsp = NULL;
2020 int snum;
2021 char *oldcwd = NULL;
2023 ZERO_STRUCT(st);
2025 if (!r->in.share) {
2026 werr = WERR_NET_NAME_NOT_FOUND;
2027 goto error_exit;
2029 snum = find_service(talloc_tos(), r->in.share, &servicename);
2030 if (!servicename) {
2031 werr = WERR_NOMEM;
2032 goto error_exit;
2034 if (snum == -1) {
2035 DEBUG(10, ("Could not find service %s\n", servicename));
2036 werr = WERR_NET_NAME_NOT_FOUND;
2037 goto error_exit;
2040 nt_status = create_conn_struct_cwd(talloc_tos(),
2041 server_event_context(),
2042 server_messaging_context(),
2043 &conn,
2044 snum, lp_pathname(talloc_tos(), snum),
2045 p->session_info, &oldcwd);
2046 if (!NT_STATUS_IS_OK(nt_status)) {
2047 DEBUG(10, ("create_conn_struct failed: %s\n",
2048 nt_errstr(nt_status)));
2049 werr = ntstatus_to_werror(nt_status);
2050 goto error_exit;
2053 nt_status = filename_convert(talloc_tos(),
2054 conn,
2055 false,
2056 r->in.file,
2058 NULL,
2059 &smb_fname);
2060 if (!NT_STATUS_IS_OK(nt_status)) {
2061 werr = ntstatus_to_werror(nt_status);
2062 goto error_exit;
2065 nt_status = SMB_VFS_CREATE_FILE(
2066 conn, /* conn */
2067 NULL, /* req */
2068 0, /* root_dir_fid */
2069 smb_fname, /* fname */
2070 FILE_READ_ATTRIBUTES, /* access_mask */
2071 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2072 FILE_OPEN, /* create_disposition*/
2073 0, /* create_options */
2074 0, /* file_attributes */
2075 INTERNAL_OPEN_ONLY, /* oplock_request */
2076 0, /* allocation_size */
2077 0, /* private_flags */
2078 NULL, /* sd */
2079 NULL, /* ea_list */
2080 &fsp, /* result */
2081 NULL); /* pinfo */
2083 if (!NT_STATUS_IS_OK(nt_status)) {
2084 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2085 smb_fname_str_dbg(smb_fname)));
2086 werr = ntstatus_to_werror(nt_status);
2087 goto error_exit;
2090 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2091 if (!sd_buf) {
2092 werr = WERR_NOMEM;
2093 goto error_exit;
2096 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2097 (SECINFO_OWNER
2098 |SECINFO_GROUP
2099 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2101 if (!NT_STATUS_IS_OK(nt_status)) {
2102 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2103 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2104 werr = ntstatus_to_werror(nt_status);
2105 TALLOC_FREE(sd_buf);
2106 goto error_exit;
2109 if (sd_buf->sd->dacl) {
2110 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2113 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2115 sd_buf->sd_size = sd_size;
2117 *r->out.sd_buf = sd_buf;
2119 close_file(NULL, fsp, NORMAL_CLOSE);
2120 vfs_ChDir(conn, oldcwd);
2121 SMB_VFS_DISCONNECT(conn);
2122 conn_free(conn);
2123 werr = WERR_OK;
2124 goto done;
2126 error_exit:
2128 if (fsp) {
2129 close_file(NULL, fsp, NORMAL_CLOSE);
2132 if (oldcwd) {
2133 vfs_ChDir(conn, oldcwd);
2136 if (conn) {
2137 SMB_VFS_DISCONNECT(conn);
2138 conn_free(conn);
2141 done:
2143 TALLOC_FREE(smb_fname);
2145 return werr;
2148 /***********************************************************************************
2149 _srvsvc_NetSetFileSecurity
2150 Win9x NT tools set security descriptor.
2151 ***********************************************************************************/
2153 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2154 struct srvsvc_NetSetFileSecurity *r)
2156 struct smb_filename *smb_fname = NULL;
2157 char *servicename = NULL;
2158 files_struct *fsp = NULL;
2159 SMB_STRUCT_STAT st;
2160 NTSTATUS nt_status;
2161 WERROR werr;
2162 connection_struct *conn = NULL;
2163 int snum;
2164 char *oldcwd = NULL;
2165 struct security_descriptor *psd = NULL;
2166 uint32_t security_info_sent = 0;
2168 ZERO_STRUCT(st);
2170 if (!r->in.share) {
2171 werr = WERR_NET_NAME_NOT_FOUND;
2172 goto error_exit;
2175 snum = find_service(talloc_tos(), r->in.share, &servicename);
2176 if (!servicename) {
2177 werr = WERR_NOMEM;
2178 goto error_exit;
2181 if (snum == -1) {
2182 DEBUG(10, ("Could not find service %s\n", servicename));
2183 werr = WERR_NET_NAME_NOT_FOUND;
2184 goto error_exit;
2187 nt_status = create_conn_struct_cwd(talloc_tos(),
2188 server_event_context(),
2189 server_messaging_context(),
2190 &conn,
2191 snum, lp_pathname(talloc_tos(), snum),
2192 p->session_info, &oldcwd);
2193 if (!NT_STATUS_IS_OK(nt_status)) {
2194 DEBUG(10, ("create_conn_struct failed: %s\n",
2195 nt_errstr(nt_status)));
2196 werr = ntstatus_to_werror(nt_status);
2197 goto error_exit;
2200 nt_status = filename_convert(talloc_tos(),
2201 conn,
2202 false,
2203 r->in.file,
2205 NULL,
2206 &smb_fname);
2207 if (!NT_STATUS_IS_OK(nt_status)) {
2208 werr = ntstatus_to_werror(nt_status);
2209 goto error_exit;
2212 nt_status = SMB_VFS_CREATE_FILE(
2213 conn, /* conn */
2214 NULL, /* req */
2215 0, /* root_dir_fid */
2216 smb_fname, /* fname */
2217 FILE_WRITE_ATTRIBUTES, /* access_mask */
2218 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2219 FILE_OPEN, /* create_disposition*/
2220 0, /* create_options */
2221 0, /* file_attributes */
2222 INTERNAL_OPEN_ONLY, /* oplock_request */
2223 0, /* allocation_size */
2224 0, /* private_flags */
2225 NULL, /* sd */
2226 NULL, /* ea_list */
2227 &fsp, /* result */
2228 NULL); /* pinfo */
2230 if (!NT_STATUS_IS_OK(nt_status)) {
2231 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2232 smb_fname_str_dbg(smb_fname)));
2233 werr = ntstatus_to_werror(nt_status);
2234 goto error_exit;
2237 psd = r->in.sd_buf->sd;
2238 security_info_sent = r->in.securityinformation;
2240 nt_status = set_sd(fsp, psd, security_info_sent);
2242 if (!NT_STATUS_IS_OK(nt_status) ) {
2243 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2244 "on file %s\n", r->in.share));
2245 werr = WERR_ACCESS_DENIED;
2246 goto error_exit;
2249 close_file(NULL, fsp, NORMAL_CLOSE);
2250 vfs_ChDir(conn, oldcwd);
2251 SMB_VFS_DISCONNECT(conn);
2252 conn_free(conn);
2253 werr = WERR_OK;
2254 goto done;
2256 error_exit:
2258 if (fsp) {
2259 close_file(NULL, fsp, NORMAL_CLOSE);
2262 if (oldcwd) {
2263 vfs_ChDir(conn, oldcwd);
2266 if (conn) {
2267 SMB_VFS_DISCONNECT(conn);
2268 conn_free(conn);
2271 done:
2272 TALLOC_FREE(smb_fname);
2274 return werr;
2277 /***********************************************************************************
2278 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2279 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2280 These disks would the disks listed by this function.
2281 Users could then create shares relative to these disks. Watch out for moving these disks around.
2282 "Nigel Williams" <nigel@veritas.com>.
2283 ***********************************************************************************/
2285 static const char *server_disks[] = {"C:"};
2287 static uint32 get_server_disk_count(void)
2289 return sizeof(server_disks)/sizeof(server_disks[0]);
2292 static uint32 init_server_disk_enum(uint32 *resume)
2294 uint32 server_disk_count = get_server_disk_count();
2296 /*resume can be an offset into the list for now*/
2298 if(*resume & 0x80000000)
2299 *resume = 0;
2301 if(*resume > server_disk_count)
2302 *resume = server_disk_count;
2304 return server_disk_count - *resume;
2307 static const char *next_server_disk_enum(uint32 *resume)
2309 const char *disk;
2311 if(init_server_disk_enum(resume) == 0)
2312 return NULL;
2314 disk = server_disks[*resume];
2316 (*resume)++;
2318 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2320 return disk;
2323 /********************************************************************
2324 _srvsvc_NetDiskEnum
2325 ********************************************************************/
2327 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2328 struct srvsvc_NetDiskEnum *r)
2330 uint32 i;
2331 const char *disk_name;
2332 TALLOC_CTX *ctx = p->mem_ctx;
2333 WERROR werr;
2334 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2336 werr = WERR_OK;
2338 *r->out.totalentries = init_server_disk_enum(&resume);
2340 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2341 MAX_SERVER_DISK_ENTRIES);
2342 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2344 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2346 r->out.info->count = 0;
2348 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2350 r->out.info->count++;
2352 /*copy disk name into a unicode string*/
2354 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2355 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2358 /* add a terminating null string. Is this there if there is more data to come? */
2360 r->out.info->count++;
2362 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2363 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2365 if (r->out.resume_handle) {
2366 *r->out.resume_handle = resume;
2369 return werr;
2372 /********************************************************************
2373 _srvsvc_NetNameValidate
2374 ********************************************************************/
2376 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2377 struct srvsvc_NetNameValidate *r)
2379 switch (r->in.name_type) {
2380 case 0x9:
2381 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2382 strlen_m(r->in.name)))
2384 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2385 r->in.name));
2386 return WERR_INVALID_NAME;
2388 break;
2390 default:
2391 return WERR_UNKNOWN_LEVEL;
2394 return WERR_OK;
2397 /*******************************************************************
2398 ********************************************************************/
2400 struct enum_file_close_state {
2401 struct srvsvc_NetFileClose *r;
2402 struct messaging_context *msg_ctx;
2405 static void enum_file_close_fn( const struct share_mode_entry *e,
2406 const char *sharepath, const char *fname,
2407 void *private_data )
2409 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2410 struct enum_file_close_state *state =
2411 (struct enum_file_close_state *)private_data;
2412 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2414 if (fid != state->r->in.fid) {
2415 return; /* Not this file. */
2418 if (!process_exists(e->pid) ) {
2419 return;
2422 /* Ok - send the close message. */
2423 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2424 sharepath,
2425 share_mode_str(talloc_tos(), 0, e) ));
2427 share_mode_entry_to_message(msg, e);
2429 state->r->out.result = ntstatus_to_werror(
2430 messaging_send_buf(state->msg_ctx,
2431 e->pid, MSG_SMB_CLOSE_FILE,
2432 (uint8 *)msg,
2433 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2436 /********************************************************************
2437 Close a file given a 32-bit file id.
2438 ********************************************************************/
2440 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2441 struct srvsvc_NetFileClose *r)
2443 struct enum_file_close_state state;
2444 bool is_disk_op;
2446 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2448 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2450 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2451 return WERR_ACCESS_DENIED;
2454 /* enum_file_close_fn sends the close message to
2455 * the relevent smbd process. */
2457 r->out.result = WERR_BADFILE;
2458 state.r = r;
2459 state.msg_ctx = p->msg_ctx;
2460 share_mode_forall(enum_file_close_fn, &state);
2461 return r->out.result;
2464 /********************************************************************
2465 ********************************************************************/
2467 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2468 struct srvsvc_NetCharDevEnum *r)
2470 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2471 return WERR_NOT_SUPPORTED;
2474 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2475 struct srvsvc_NetCharDevGetInfo *r)
2477 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2478 return WERR_NOT_SUPPORTED;
2481 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2482 struct srvsvc_NetCharDevControl *r)
2484 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2485 return WERR_NOT_SUPPORTED;
2488 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2489 struct srvsvc_NetCharDevQEnum *r)
2491 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2492 return WERR_NOT_SUPPORTED;
2495 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2496 struct srvsvc_NetCharDevQGetInfo *r)
2498 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2499 return WERR_NOT_SUPPORTED;
2502 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2503 struct srvsvc_NetCharDevQSetInfo *r)
2505 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2506 return WERR_NOT_SUPPORTED;
2509 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2510 struct srvsvc_NetCharDevQPurge *r)
2512 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2513 return WERR_NOT_SUPPORTED;
2516 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2517 struct srvsvc_NetCharDevQPurgeSelf *r)
2519 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2520 return WERR_NOT_SUPPORTED;
2523 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2524 struct srvsvc_NetFileGetInfo *r)
2526 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2527 return WERR_NOT_SUPPORTED;
2530 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2531 struct srvsvc_NetShareCheck *r)
2533 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2534 return WERR_NOT_SUPPORTED;
2537 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2538 struct srvsvc_NetServerStatisticsGet *r)
2540 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2541 return WERR_NOT_SUPPORTED;
2544 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2545 struct srvsvc_NetTransportAdd *r)
2547 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2552 struct srvsvc_NetTransportEnum *r)
2554 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2555 return WERR_NOT_SUPPORTED;
2558 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2559 struct srvsvc_NetTransportDel *r)
2561 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2562 return WERR_NOT_SUPPORTED;
2565 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2566 struct srvsvc_NetSetServiceBits *r)
2568 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2569 return WERR_NOT_SUPPORTED;
2572 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2573 struct srvsvc_NetPathType *r)
2575 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2576 return WERR_NOT_SUPPORTED;
2579 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2580 struct srvsvc_NetPathCanonicalize *r)
2582 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2583 return WERR_NOT_SUPPORTED;
2586 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2587 struct srvsvc_NetPathCompare *r)
2589 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2594 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2596 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2597 return WERR_NOT_SUPPORTED;
2600 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2601 struct srvsvc_NetPRNameCompare *r)
2603 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2604 return WERR_NOT_SUPPORTED;
2607 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2608 struct srvsvc_NetShareDelStart *r)
2610 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2611 return WERR_NOT_SUPPORTED;
2614 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2615 struct srvsvc_NetShareDelCommit *r)
2617 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2618 return WERR_NOT_SUPPORTED;
2621 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2622 struct srvsvc_NetServerTransportAddEx *r)
2624 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2625 return WERR_NOT_SUPPORTED;
2628 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2629 struct srvsvc_NetServerSetServiceBitsEx *r)
2631 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2632 return WERR_NOT_SUPPORTED;
2635 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2636 struct srvsvc_NETRDFSGETVERSION *r)
2638 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2639 return WERR_NOT_SUPPORTED;
2642 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2643 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2645 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2646 return WERR_NOT_SUPPORTED;
2649 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2650 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2652 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2653 return WERR_NOT_SUPPORTED;
2656 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2657 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2659 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2660 return WERR_NOT_SUPPORTED;
2663 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2664 struct srvsvc_NETRDFSSETSERVERINFO *r)
2666 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2667 return WERR_NOT_SUPPORTED;
2670 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2671 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2673 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2674 return WERR_NOT_SUPPORTED;
2677 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2678 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2680 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2681 return WERR_NOT_SUPPORTED;
2684 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2685 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2687 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2688 return WERR_NOT_SUPPORTED;
2691 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2692 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2694 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2695 return WERR_NOT_SUPPORTED;
2698 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2699 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2701 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2702 return WERR_NOT_SUPPORTED;
2705 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2706 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2708 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2709 return WERR_NOT_SUPPORTED;