s3:registry/regfio read SD from the correct location
[Samba.git] / source3 / rpc_server / srvsvc / srv_srvsvc_nt.c
blob7b9ec5c87da289ae4daa1780b93e55c9517cb8a1
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 delete_and_reload_printers(server_event_context(), p->msg_ctx);
488 load_usershare_shares(NULL, connections_snum_used);
489 load_registry_shares();
490 num_services = lp_numservices();
491 unbecome_root();
493 allowed = talloc_zero_array(ctx, bool, num_services);
494 W_ERROR_HAVE_NO_MEMORY(allowed);
496 /* Count the number of entries. */
497 for (snum = 0; snum < num_services; snum++) {
498 if (lp_browseable(snum) && lp_snum_ok(snum) &&
499 is_enumeration_allowed(p, snum) &&
500 (all_shares || !is_hidden_share(snum)) ) {
501 DEBUG(10, ("counting service %s\n",
502 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
503 allowed[snum] = true;
504 num_entries++;
505 } else {
506 DEBUG(10, ("NOT counting service %s\n",
507 lp_servicename(talloc_tos(), snum) ? lp_servicename(talloc_tos(), snum) : "(null)"));
511 if (!num_entries || (resume_handle >= num_entries)) {
512 return WERR_OK;
515 /* Calculate alloc entries. */
516 alloc_entries = num_entries - resume_handle;
517 switch (info_ctr->level) {
518 case 0:
519 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
520 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
522 ctr.ctr0->count = alloc_entries;
523 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
524 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
526 for (snum = 0; snum < num_services; snum++) {
527 if (allowed[snum] &&
528 (resume_handle <= (i + valid_share_count++)) ) {
529 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
533 break;
535 case 1:
536 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
537 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
539 ctr.ctr1->count = alloc_entries;
540 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
541 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
543 for (snum = 0; snum < num_services; snum++) {
544 if (allowed[snum] &&
545 (resume_handle <= (i + valid_share_count++)) ) {
546 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
550 break;
552 case 2:
553 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
554 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
556 ctr.ctr2->count = alloc_entries;
557 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
558 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
560 for (snum = 0; snum < num_services; snum++) {
561 if (allowed[snum] &&
562 (resume_handle <= (i + valid_share_count++)) ) {
563 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
567 break;
569 case 501:
570 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
571 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
573 ctr.ctr501->count = alloc_entries;
574 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
575 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
577 for (snum = 0; snum < num_services; snum++) {
578 if (allowed[snum] &&
579 (resume_handle <= (i + valid_share_count++)) ) {
580 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
584 break;
586 case 502:
587 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
588 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
590 ctr.ctr502->count = alloc_entries;
591 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
592 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
594 for (snum = 0; snum < num_services; snum++) {
595 if (allowed[snum] &&
596 (resume_handle <= (i + valid_share_count++)) ) {
597 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
601 break;
603 case 1004:
604 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
605 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
607 ctr.ctr1004->count = alloc_entries;
608 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
609 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
611 for (snum = 0; snum < num_services; snum++) {
612 if (allowed[snum] &&
613 (resume_handle <= (i + valid_share_count++)) ) {
614 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
618 break;
620 case 1005:
621 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
622 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
624 ctr.ctr1005->count = alloc_entries;
625 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
626 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
628 for (snum = 0; snum < num_services; snum++) {
629 if (allowed[snum] &&
630 (resume_handle <= (i + valid_share_count++)) ) {
631 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
635 break;
637 case 1006:
638 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
639 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
641 ctr.ctr1006->count = alloc_entries;
642 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
643 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
645 for (snum = 0; snum < num_services; snum++) {
646 if (allowed[snum] &&
647 (resume_handle <= (i + valid_share_count++)) ) {
648 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
652 break;
654 case 1007:
655 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
656 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
658 ctr.ctr1007->count = alloc_entries;
659 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
660 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
662 for (snum = 0; snum < num_services; snum++) {
663 if (allowed[snum] &&
664 (resume_handle <= (i + valid_share_count++)) ) {
665 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
669 break;
671 case 1501:
672 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
673 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
675 ctr.ctr1501->count = alloc_entries;
676 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
677 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
679 for (snum = 0; snum < num_services; snum++) {
680 if (allowed[snum] &&
681 (resume_handle <= (i + valid_share_count++)) ) {
682 struct sec_desc_buf *sd_buf = NULL;
683 init_srv_share_info_1501(p, &sd_buf, snum);
684 ctr.ctr1501->array[i++] = *sd_buf;
688 break;
690 default:
691 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
692 info_ctr->level));
693 return WERR_UNKNOWN_LEVEL;
696 *total_entries = alloc_entries;
697 if (resume_handle_p) {
698 if (all_shares) {
699 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
700 } else {
701 *resume_handle_p = num_entries;
705 info_ctr->ctr = ctr;
707 return WERR_OK;
710 /*******************************************************************
711 fill in a sess info level 0 structure.
712 ********************************************************************/
714 static WERROR init_srv_sess_info_0(struct pipes_struct *p,
715 struct srvsvc_NetSessCtr0 *ctr0,
716 uint32_t *resume_handle_p,
717 uint32_t *total_entries)
719 struct sessionid *session_list;
720 uint32_t num_entries = 0;
721 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
722 *total_entries = list_sessions(p->mem_ctx, &session_list);
724 DEBUG(5,("init_srv_sess_info_0\n"));
726 if (ctr0 == NULL) {
727 if (resume_handle_p) {
728 *resume_handle_p = 0;
730 return WERR_OK;
733 for (; resume_handle < *total_entries; resume_handle++) {
735 ctr0->array = talloc_realloc(p->mem_ctx,
736 ctr0->array,
737 struct srvsvc_NetSessInfo0,
738 num_entries+1);
739 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
741 ctr0->array[num_entries].client =
742 session_list[resume_handle].remote_machine;
744 num_entries++;
747 ctr0->count = num_entries;
749 if (resume_handle_p) {
750 if (*resume_handle_p >= *total_entries) {
751 *resume_handle_p = 0;
752 } else {
753 *resume_handle_p = resume_handle;
757 return WERR_OK;
760 /*******************************************************************
761 ********************************************************************/
763 static void sess_file_fn( const struct share_mode_entry *e,
764 const char *sharepath, const char *fname,
765 void *data )
767 struct sess_file_count *sess = (struct sess_file_count *)data;
769 if (serverid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid)) {
770 sess->count++;
773 return;
776 /*******************************************************************
777 ********************************************************************/
779 static int net_count_files( uid_t uid, struct server_id pid )
781 struct sess_file_count s_file_cnt;
783 s_file_cnt.count = 0;
784 s_file_cnt.uid = uid;
785 s_file_cnt.pid = pid;
787 share_mode_forall( sess_file_fn, &s_file_cnt );
789 return s_file_cnt.count;
792 /*******************************************************************
793 fill in a sess info level 1 structure.
794 ********************************************************************/
796 static WERROR init_srv_sess_info_1(struct pipes_struct *p,
797 struct srvsvc_NetSessCtr1 *ctr1,
798 uint32_t *resume_handle_p,
799 uint32_t *total_entries)
801 struct sessionid *session_list;
802 uint32_t num_entries = 0;
803 time_t now = time(NULL);
804 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
806 ZERO_STRUCTP(ctr1);
808 if (ctr1 == NULL) {
809 if (resume_handle_p) {
810 *resume_handle_p = 0;
812 return WERR_OK;
815 *total_entries = list_sessions(p->mem_ctx, &session_list);
817 for (; resume_handle < *total_entries; resume_handle++) {
818 uint32 num_files;
819 uint32 connect_time;
820 struct passwd *pw = getpwnam(session_list[resume_handle].username);
821 bool guest;
823 if ( !pw ) {
824 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
825 session_list[resume_handle].username));
826 continue;
829 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
830 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
831 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
833 ctr1->array = talloc_realloc(p->mem_ctx,
834 ctr1->array,
835 struct srvsvc_NetSessInfo1,
836 num_entries+1);
837 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
839 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
840 ctr1->array[num_entries].user = session_list[resume_handle].username;
841 ctr1->array[num_entries].num_open = num_files;
842 ctr1->array[num_entries].time = connect_time;
843 ctr1->array[num_entries].idle_time = 0;
844 ctr1->array[num_entries].user_flags = guest;
846 num_entries++;
849 ctr1->count = num_entries;
851 if (resume_handle_p) {
852 if (*resume_handle_p >= *total_entries) {
853 *resume_handle_p = 0;
854 } else {
855 *resume_handle_p = resume_handle;
859 return WERR_OK;
862 /*******************************************************************
863 fill in a conn info level 0 structure.
864 ********************************************************************/
866 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
867 uint32_t *resume_handle_p,
868 uint32_t *total_entries)
870 uint32_t num_entries = 0;
871 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
873 DEBUG(5,("init_srv_conn_info_0\n"));
875 if (ctr0 == NULL) {
876 if (resume_handle_p) {
877 *resume_handle_p = 0;
879 return WERR_OK;
882 *total_entries = 1;
884 ZERO_STRUCTP(ctr0);
886 for (; resume_handle < *total_entries; resume_handle++) {
888 ctr0->array = talloc_realloc(talloc_tos(),
889 ctr0->array,
890 struct srvsvc_NetConnInfo0,
891 num_entries+1);
892 if (!ctr0->array) {
893 return WERR_NOMEM;
896 ctr0->array[num_entries].conn_id = *total_entries;
898 /* move on to creating next connection */
899 num_entries++;
902 ctr0->count = num_entries;
903 *total_entries = num_entries;
905 if (resume_handle_p) {
906 if (*resume_handle_p >= *total_entries) {
907 *resume_handle_p = 0;
908 } else {
909 *resume_handle_p = resume_handle;
913 return WERR_OK;
916 /*******************************************************************
917 fill in a conn info level 1 structure.
918 ********************************************************************/
920 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
921 uint32_t *resume_handle_p,
922 uint32_t *total_entries)
924 uint32_t num_entries = 0;
925 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
927 DEBUG(5,("init_srv_conn_info_1\n"));
929 if (ctr1 == NULL) {
930 if (resume_handle_p) {
931 *resume_handle_p = 0;
933 return WERR_OK;
936 *total_entries = 1;
938 ZERO_STRUCTP(ctr1);
940 for (; resume_handle < *total_entries; resume_handle++) {
942 ctr1->array = talloc_realloc(talloc_tos(),
943 ctr1->array,
944 struct srvsvc_NetConnInfo1,
945 num_entries+1);
946 if (!ctr1->array) {
947 return WERR_NOMEM;
950 ctr1->array[num_entries].conn_id = *total_entries;
951 ctr1->array[num_entries].conn_type = 0x3;
952 ctr1->array[num_entries].num_open = 1;
953 ctr1->array[num_entries].num_users = 1;
954 ctr1->array[num_entries].conn_time = 3;
955 ctr1->array[num_entries].user = "dummy_user";
956 ctr1->array[num_entries].share = "IPC$";
958 /* move on to creating next connection */
959 num_entries++;
962 ctr1->count = num_entries;
963 *total_entries = num_entries;
965 if (resume_handle_p) {
966 if (*resume_handle_p >= *total_entries) {
967 *resume_handle_p = 0;
968 } else {
969 *resume_handle_p = resume_handle;
973 return WERR_OK;
976 /*******************************************************************
977 _srvsvc_NetFileEnum
978 *******************************************************************/
980 WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
981 struct srvsvc_NetFileEnum *r)
983 TALLOC_CTX *ctx = NULL;
984 struct srvsvc_NetFileCtr3 *ctr3;
985 uint32_t resume_hnd = 0;
986 WERROR werr;
988 switch (r->in.info_ctr->level) {
989 case 3:
990 break;
991 default:
992 return WERR_UNKNOWN_LEVEL;
995 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
996 p->session_info->security_token)) {
997 DEBUG(1, ("Enumerating files only allowed for "
998 "administrators\n"));
999 return WERR_ACCESS_DENIED;
1002 ctx = talloc_tos();
1003 ctr3 = r->in.info_ctr->ctr.ctr3;
1004 if (!ctr3) {
1005 werr = WERR_INVALID_PARAM;
1006 goto done;
1009 /* TODO -- Windows enumerates
1010 (b) active pipes
1011 (c) open directories and files */
1013 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1014 if (!W_ERROR_IS_OK(werr)) {
1015 goto done;
1018 *r->out.totalentries = ctr3->count;
1019 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1020 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1022 werr = WERR_OK;
1024 done:
1025 return werr;
1028 /*******************************************************************
1029 _srvsvc_NetSrvGetInfo
1030 ********************************************************************/
1032 WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
1033 struct srvsvc_NetSrvGetInfo *r)
1035 WERROR status = WERR_OK;
1037 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1039 if (!pipe_access_check(p)) {
1040 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1041 return WERR_ACCESS_DENIED;
1044 switch (r->in.level) {
1046 /* Technically level 102 should only be available to
1047 Administrators but there isn't anything super-secret
1048 here, as most of it is made up. */
1050 case 102: {
1051 struct srvsvc_NetSrvInfo102 *info102;
1053 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1054 if (!info102) {
1055 return WERR_NOMEM;
1058 info102->platform_id = PLATFORM_ID_NT;
1059 info102->server_name = lp_netbios_name();
1060 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1061 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1062 info102->server_type = lp_default_server_announce();
1063 info102->comment = string_truncate(lp_serverstring(talloc_tos()),
1064 MAX_SERVER_STRING_LENGTH);
1065 info102->users = 0xffffffff;
1066 info102->disc = 0xf;
1067 info102->hidden = 0;
1068 info102->announce = 240;
1069 info102->anndelta = 3000;
1070 info102->licenses = 100000;
1071 info102->userpath = "C:\\";
1073 r->out.info->info102 = info102;
1074 break;
1076 case 101: {
1077 struct srvsvc_NetSrvInfo101 *info101;
1079 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1080 if (!info101) {
1081 return WERR_NOMEM;
1084 info101->platform_id = PLATFORM_ID_NT;
1085 info101->server_name = lp_netbios_name();
1086 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
1087 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
1088 info101->server_type = lp_default_server_announce();
1089 info101->comment = string_truncate(lp_serverstring(talloc_tos()),
1090 MAX_SERVER_STRING_LENGTH);
1092 r->out.info->info101 = info101;
1093 break;
1095 case 100: {
1096 struct srvsvc_NetSrvInfo100 *info100;
1098 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1099 if (!info100) {
1100 return WERR_NOMEM;
1103 info100->platform_id = PLATFORM_ID_NT;
1104 info100->server_name = lp_netbios_name();
1106 r->out.info->info100 = info100;
1108 break;
1110 default:
1111 status = WERR_UNKNOWN_LEVEL;
1112 break;
1115 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1117 return status;
1120 /*******************************************************************
1121 _srvsvc_NetSrvSetInfo
1122 ********************************************************************/
1124 WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
1125 struct srvsvc_NetSrvSetInfo *r)
1127 WERROR status = WERR_OK;
1129 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1131 /* Set up the net server set info structure. */
1133 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1135 return status;
1138 /*******************************************************************
1139 _srvsvc_NetConnEnum
1140 ********************************************************************/
1142 WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
1143 struct srvsvc_NetConnEnum *r)
1145 WERROR werr;
1147 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1149 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1150 p->session_info->security_token)) {
1151 DEBUG(1, ("Enumerating connections only allowed for "
1152 "administrators\n"));
1153 return WERR_ACCESS_DENIED;
1156 switch (r->in.info_ctr->level) {
1157 case 0:
1158 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1159 r->in.resume_handle,
1160 r->out.totalentries);
1161 break;
1162 case 1:
1163 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1164 r->in.resume_handle,
1165 r->out.totalentries);
1166 break;
1167 default:
1168 return WERR_UNKNOWN_LEVEL;
1171 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1173 return werr;
1176 /*******************************************************************
1177 _srvsvc_NetSessEnum
1178 ********************************************************************/
1180 WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
1181 struct srvsvc_NetSessEnum *r)
1183 WERROR werr;
1185 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1187 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1188 p->session_info->security_token)) {
1189 DEBUG(1, ("Enumerating sessions only allowed for "
1190 "administrators\n"));
1191 return WERR_ACCESS_DENIED;
1194 switch (r->in.info_ctr->level) {
1195 case 0:
1196 werr = init_srv_sess_info_0(p,
1197 r->in.info_ctr->ctr.ctr0,
1198 r->in.resume_handle,
1199 r->out.totalentries);
1200 break;
1201 case 1:
1202 werr = init_srv_sess_info_1(p,
1203 r->in.info_ctr->ctr.ctr1,
1204 r->in.resume_handle,
1205 r->out.totalentries);
1206 break;
1207 default:
1208 return WERR_UNKNOWN_LEVEL;
1211 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1213 return werr;
1216 /*******************************************************************
1217 _srvsvc_NetSessDel
1218 ********************************************************************/
1220 WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
1221 struct srvsvc_NetSessDel *r)
1223 struct sessionid *session_list;
1224 int num_sessions, snum;
1225 const char *username;
1226 const char *machine;
1227 bool not_root = False;
1228 WERROR werr;
1230 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1232 werr = WERR_ACCESS_DENIED;
1234 /* fail out now if you are not root or not a domain admin */
1236 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1237 ( ! nt_token_check_domain_rid(p->session_info->security_token,
1238 DOMAIN_RID_ADMINS))) {
1240 goto done;
1243 username = r->in.user;
1244 machine = r->in.client;
1246 /* strip leading backslashes if any */
1247 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1248 machine += 2;
1251 num_sessions = list_sessions(p->mem_ctx, &session_list);
1253 for (snum = 0; snum < num_sessions; snum++) {
1255 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1256 strequal(session_list[snum].remote_machine, machine)) {
1258 NTSTATUS ntstat;
1260 if (p->session_info->unix_token->uid != sec_initial_uid()) {
1261 not_root = True;
1262 become_root();
1265 ntstat = messaging_send(p->msg_ctx,
1266 session_list[snum].pid,
1267 MSG_SHUTDOWN, &data_blob_null);
1269 if (NT_STATUS_IS_OK(ntstat))
1270 werr = WERR_OK;
1272 if (not_root)
1273 unbecome_root();
1277 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1279 done:
1281 return werr;
1284 /*******************************************************************
1285 _srvsvc_NetShareEnumAll
1286 ********************************************************************/
1288 WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
1289 struct srvsvc_NetShareEnumAll *r)
1291 WERROR werr;
1293 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1295 if (!pipe_access_check(p)) {
1296 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1297 return WERR_ACCESS_DENIED;
1300 /* Create the list of shares for the response. */
1301 werr = init_srv_share_info_ctr(p,
1302 r->in.info_ctr,
1303 r->in.resume_handle,
1304 r->out.totalentries,
1305 true);
1307 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1309 return werr;
1312 /*******************************************************************
1313 _srvsvc_NetShareEnum
1314 ********************************************************************/
1316 WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
1317 struct srvsvc_NetShareEnum *r)
1319 WERROR werr;
1321 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1323 if (!pipe_access_check(p)) {
1324 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1325 return WERR_ACCESS_DENIED;
1328 /* Create the list of shares for the response. */
1329 werr = init_srv_share_info_ctr(p,
1330 r->in.info_ctr,
1331 r->in.resume_handle,
1332 r->out.totalentries,
1333 false);
1335 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1337 return werr;
1340 /*******************************************************************
1341 _srvsvc_NetShareGetInfo
1342 ********************************************************************/
1344 WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
1345 struct srvsvc_NetShareGetInfo *r)
1347 WERROR status = WERR_OK;
1348 char *share_name = NULL;
1349 int snum;
1350 union srvsvc_NetShareInfo *info = r->out.info;
1352 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1354 if (!r->in.share_name) {
1355 return WERR_INVALID_NAME;
1358 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1359 if (!share_name) {
1360 return WERR_NOMEM;
1362 if (snum < 0) {
1363 return WERR_INVALID_NAME;
1366 switch (r->in.level) {
1367 case 0:
1368 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1369 W_ERROR_HAVE_NO_MEMORY(info->info0);
1370 init_srv_share_info_0(p, info->info0, snum);
1371 break;
1372 case 1:
1373 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1374 W_ERROR_HAVE_NO_MEMORY(info->info1);
1375 init_srv_share_info_1(p, info->info1, snum);
1376 break;
1377 case 2:
1378 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1379 W_ERROR_HAVE_NO_MEMORY(info->info2);
1380 init_srv_share_info_2(p, info->info2, snum);
1381 break;
1382 case 501:
1383 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1384 W_ERROR_HAVE_NO_MEMORY(info->info501);
1385 init_srv_share_info_501(p, info->info501, snum);
1386 break;
1387 case 502:
1388 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1389 W_ERROR_HAVE_NO_MEMORY(info->info502);
1390 init_srv_share_info_502(p, info->info502, snum);
1391 break;
1392 case 1004:
1393 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1394 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1395 init_srv_share_info_1004(p, info->info1004, snum);
1396 break;
1397 case 1005:
1398 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1399 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1400 init_srv_share_info_1005(p, info->info1005, snum);
1401 break;
1402 case 1006:
1403 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1404 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1405 init_srv_share_info_1006(p, info->info1006, snum);
1406 break;
1407 case 1007:
1408 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1409 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1410 init_srv_share_info_1007(p, info->info1007, snum);
1411 break;
1412 case 1501:
1413 init_srv_share_info_1501(p, &info->info1501, snum);
1414 break;
1415 default:
1416 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1417 r->in.level));
1418 status = WERR_UNKNOWN_LEVEL;
1419 break;
1422 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1424 return status;
1427 /*******************************************************************
1428 _srvsvc_NetShareSetInfo. Modify share details.
1429 ********************************************************************/
1431 WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
1432 struct srvsvc_NetShareSetInfo *r)
1434 char *command = NULL;
1435 char *share_name = NULL;
1436 char *comment = NULL;
1437 const char *pathname = NULL;
1438 int type;
1439 int snum;
1440 int ret;
1441 char *path = NULL;
1442 struct security_descriptor *psd = NULL;
1443 bool is_disk_op = False;
1444 int max_connections = 0;
1445 TALLOC_CTX *ctx = p->mem_ctx;
1446 union srvsvc_NetShareInfo *info = r->in.info;
1448 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1450 if (!r->in.share_name) {
1451 return WERR_INVALID_NAME;
1454 if (r->out.parm_error) {
1455 *r->out.parm_error = 0;
1458 if ( strequal(r->in.share_name,"IPC$")
1459 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1460 || strequal(r->in.share_name,"global") )
1462 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1463 "modified by a remote user.\n",
1464 r->in.share_name ));
1465 return WERR_ACCESS_DENIED;
1468 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1469 if (!share_name) {
1470 return WERR_NOMEM;
1473 /* Does this share exist ? */
1474 if (snum < 0)
1475 return WERR_NET_NAME_NOT_FOUND;
1477 /* No change to printer shares. */
1478 if (lp_print_ok(snum))
1479 return WERR_ACCESS_DENIED;
1481 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1483 /* fail out now if you are not root and not a disk op */
1485 if ( p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op ) {
1486 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1487 "SeDiskOperatorPrivilege privilege needed to modify "
1488 "share %s\n",
1489 (unsigned int)p->session_info->unix_token->uid,
1490 share_name ));
1491 return WERR_ACCESS_DENIED;
1494 switch (r->in.level) {
1495 case 1:
1496 pathname = lp_pathname(ctx, snum);
1497 comment = talloc_strdup(ctx, info->info1->comment);
1498 type = info->info1->type;
1499 psd = NULL;
1500 break;
1501 case 2:
1502 comment = talloc_strdup(ctx, info->info2->comment);
1503 pathname = info->info2->path;
1504 type = info->info2->type;
1505 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1506 0 : info->info2->max_users;
1507 psd = NULL;
1508 break;
1509 #if 0
1510 /* not supported on set but here for completeness */
1511 case 501:
1512 comment = talloc_strdup(ctx, info->info501->comment);
1513 type = info->info501->type;
1514 psd = NULL;
1515 break;
1516 #endif
1517 case 502:
1518 comment = talloc_strdup(ctx, info->info502->comment);
1519 pathname = info->info502->path;
1520 type = info->info502->type;
1521 psd = info->info502->sd_buf.sd;
1522 map_generic_share_sd_bits(psd);
1523 break;
1524 case 1004:
1525 pathname = lp_pathname(ctx, snum);
1526 comment = talloc_strdup(ctx, info->info1004->comment);
1527 type = STYPE_DISKTREE;
1528 break;
1529 case 1005:
1530 /* XP re-sets the csc policy even if it wasn't changed by the
1531 user, so we must compare it to see if it's what is set in
1532 smb.conf, so that we can contine other ops like setting
1533 ACLs on a share */
1534 if (((info->info1005->dfs_flags &
1535 SHARE_1005_CSC_POLICY_MASK) >>
1536 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1537 return WERR_OK;
1538 else {
1539 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1540 return WERR_ACCESS_DENIED;
1542 case 1006:
1543 case 1007:
1544 return WERR_ACCESS_DENIED;
1545 case 1501:
1546 pathname = lp_pathname(ctx, snum);
1547 comment = lp_comment(ctx, snum);
1548 psd = info->info1501->sd;
1549 map_generic_share_sd_bits(psd);
1550 type = STYPE_DISKTREE;
1551 break;
1552 default:
1553 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1554 r->in.level));
1555 return WERR_UNKNOWN_LEVEL;
1558 /* We can only modify disk shares. */
1559 if (type != STYPE_DISKTREE) {
1560 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1561 "disk share\n",
1562 share_name ));
1563 return WERR_ACCESS_DENIED;
1566 if (comment == NULL) {
1567 return WERR_NOMEM;
1570 /* Check if the pathname is valid. */
1571 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1572 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1573 pathname ));
1574 return WERR_OBJECT_PATH_INVALID;
1577 /* Ensure share name, pathname and comment don't contain '"' characters. */
1578 string_replace(share_name, '"', ' ');
1579 string_replace(path, '"', ' ');
1580 string_replace(comment, '"', ' ');
1582 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1583 lp_change_share_cmd(talloc_tos()) ? lp_change_share_cmd(talloc_tos()) : "NULL" ));
1585 /* Only call modify function if something changed. */
1587 if (strcmp(path, lp_pathname(talloc_tos(), snum)) || strcmp(comment, lp_comment(talloc_tos(), snum))
1588 || (lp_max_connections(snum) != max_connections)) {
1589 if (!lp_change_share_cmd(talloc_tos()) || !*lp_change_share_cmd(talloc_tos())) {
1590 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1591 return WERR_ACCESS_DENIED;
1594 command = talloc_asprintf(p->mem_ctx,
1595 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1596 lp_change_share_cmd(talloc_tos()),
1597 get_dyn_CONFIGFILE(),
1598 share_name,
1599 path,
1600 comment ? comment : "",
1601 max_connections);
1602 if (!command) {
1603 return WERR_NOMEM;
1606 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1608 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1610 if (is_disk_op)
1611 become_root();
1613 if ( (ret = smbrun(command, NULL)) == 0 ) {
1614 /* Tell everyone we updated smb.conf. */
1615 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
1616 NULL, 0, NULL);
1619 if ( is_disk_op )
1620 unbecome_root();
1622 /********* END SeDiskOperatorPrivilege BLOCK *********/
1624 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1625 command, ret ));
1627 TALLOC_FREE(command);
1629 if ( ret != 0 )
1630 return WERR_ACCESS_DENIED;
1631 } else {
1632 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1633 share_name ));
1636 /* Replace SD if changed. */
1637 if (psd) {
1638 struct security_descriptor *old_sd;
1639 size_t sd_size;
1641 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), snum), &sd_size);
1643 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1644 if (!set_share_security(share_name, psd))
1645 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1646 share_name ));
1650 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1652 return WERR_OK;
1655 /*******************************************************************
1656 _srvsvc_NetShareAdd.
1657 Call 'add_share_command "sharename" "pathname"
1658 "comment" "max connections = "
1659 ********************************************************************/
1661 WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
1662 struct srvsvc_NetShareAdd *r)
1664 char *command = NULL;
1665 char *share_name_in = NULL;
1666 char *share_name = NULL;
1667 char *comment = NULL;
1668 char *pathname = NULL;
1669 int type;
1670 int snum;
1671 int ret;
1672 char *path;
1673 struct security_descriptor *psd = NULL;
1674 bool is_disk_op;
1675 int max_connections = 0;
1676 TALLOC_CTX *ctx = p->mem_ctx;
1678 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1680 if (r->out.parm_error) {
1681 *r->out.parm_error = 0;
1684 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1686 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1687 return WERR_ACCESS_DENIED;
1689 if (!lp_add_share_cmd(talloc_tos()) || !*lp_add_share_cmd(talloc_tos())) {
1690 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1691 return WERR_ACCESS_DENIED;
1694 switch (r->in.level) {
1695 case 0:
1696 /* No path. Not enough info in a level 0 to do anything. */
1697 return WERR_ACCESS_DENIED;
1698 case 1:
1699 /* Not enough info in a level 1 to do anything. */
1700 return WERR_ACCESS_DENIED;
1701 case 2:
1702 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1703 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1704 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1705 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1706 0 : r->in.info->info2->max_users;
1707 type = r->in.info->info2->type;
1708 break;
1709 case 501:
1710 /* No path. Not enough info in a level 501 to do anything. */
1711 return WERR_ACCESS_DENIED;
1712 case 502:
1713 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1714 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1715 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1716 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1717 0 : r->in.info->info502->max_users;
1718 type = r->in.info->info502->type;
1719 psd = r->in.info->info502->sd_buf.sd;
1720 map_generic_share_sd_bits(psd);
1721 break;
1723 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1725 case 1004:
1726 case 1005:
1727 case 1006:
1728 case 1007:
1729 return WERR_ACCESS_DENIED;
1730 case 1501:
1731 /* DFS only level. */
1732 return WERR_ACCESS_DENIED;
1733 default:
1734 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1735 r->in.level));
1736 return WERR_UNKNOWN_LEVEL;
1739 /* check for invalid share names */
1741 if (!share_name_in || !validate_net_name(share_name_in,
1742 INVALID_SHARENAME_CHARS,
1743 strlen(share_name_in))) {
1744 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1745 share_name_in ? share_name_in : ""));
1746 return WERR_INVALID_NAME;
1749 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1750 || (lp_enable_asu_support() &&
1751 strequal(share_name_in,"ADMIN$"))) {
1752 return WERR_ACCESS_DENIED;
1755 snum = find_service(ctx, share_name_in, &share_name);
1756 if (!share_name) {
1757 return WERR_NOMEM;
1760 /* Share already exists. */
1761 if (snum >= 0) {
1762 return WERR_FILE_EXISTS;
1765 /* We can only add disk shares. */
1766 if (type != STYPE_DISKTREE) {
1767 return WERR_ACCESS_DENIED;
1770 /* Check if the pathname is valid. */
1771 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1772 return WERR_OBJECT_PATH_INVALID;
1775 /* Ensure share name, pathname and comment don't contain '"' characters. */
1776 string_replace(share_name_in, '"', ' ');
1777 string_replace(share_name, '"', ' ');
1778 string_replace(path, '"', ' ');
1779 if (comment) {
1780 string_replace(comment, '"', ' ');
1783 command = talloc_asprintf(ctx,
1784 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1785 lp_add_share_cmd(talloc_tos()),
1786 get_dyn_CONFIGFILE(),
1787 share_name_in,
1788 path,
1789 comment ? comment : "",
1790 max_connections);
1791 if (!command) {
1792 return WERR_NOMEM;
1795 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1797 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1799 if ( is_disk_op )
1800 become_root();
1802 /* FIXME: use libnetconf here - gd */
1804 if ( (ret = smbrun(command, NULL)) == 0 ) {
1805 /* Tell everyone we updated smb.conf. */
1806 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1807 NULL);
1810 if ( is_disk_op )
1811 unbecome_root();
1813 /********* END SeDiskOperatorPrivilege BLOCK *********/
1815 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1816 command, ret ));
1818 TALLOC_FREE(command);
1820 if ( ret != 0 )
1821 return WERR_ACCESS_DENIED;
1823 if (psd) {
1824 /* Note we use share_name here, not share_name_in as
1825 we need a canonicalized name for setting security. */
1826 if (!set_share_security(share_name, psd)) {
1827 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1828 share_name ));
1833 * We don't call reload_services() here, the message will
1834 * cause this to be done before the next packet is read
1835 * from the client. JRA.
1838 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1840 return WERR_OK;
1843 /*******************************************************************
1844 _srvsvc_NetShareDel
1845 Call "delete share command" with the share name as
1846 a parameter.
1847 ********************************************************************/
1849 WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
1850 struct srvsvc_NetShareDel *r)
1852 char *command = NULL;
1853 char *share_name = NULL;
1854 int ret;
1855 int snum;
1856 bool is_disk_op;
1857 struct share_params *params;
1858 TALLOC_CTX *ctx = p->mem_ctx;
1860 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1862 if (!r->in.share_name) {
1863 return WERR_NET_NAME_NOT_FOUND;
1866 if ( strequal(r->in.share_name,"IPC$")
1867 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1868 || strequal(r->in.share_name,"global") )
1870 return WERR_ACCESS_DENIED;
1873 snum = find_service(talloc_tos(), r->in.share_name, &share_name);
1874 if (!share_name) {
1875 return WERR_NOMEM;
1878 if (snum < 0) {
1879 return WERR_NO_SUCH_SHARE;
1882 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1883 return WERR_NO_SUCH_SHARE;
1886 /* No change to printer shares. */
1887 if (lp_print_ok(snum))
1888 return WERR_ACCESS_DENIED;
1890 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
1892 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op )
1893 return WERR_ACCESS_DENIED;
1895 if (!lp_delete_share_cmd(talloc_tos()) || !*lp_delete_share_cmd(talloc_tos())) {
1896 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1897 return WERR_ACCESS_DENIED;
1900 command = talloc_asprintf(ctx,
1901 "%s \"%s\" \"%s\"",
1902 lp_delete_share_cmd(talloc_tos()),
1903 get_dyn_CONFIGFILE(),
1904 lp_servicename(talloc_tos(), snum));
1905 if (!command) {
1906 return WERR_NOMEM;
1909 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1911 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1913 if ( is_disk_op )
1914 become_root();
1916 if ( (ret = smbrun(command, NULL)) == 0 ) {
1917 /* Tell everyone we updated smb.conf. */
1918 message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0,
1919 NULL);
1922 if ( is_disk_op )
1923 unbecome_root();
1925 /********* END SeDiskOperatorPrivilege BLOCK *********/
1927 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1929 if ( ret != 0 )
1930 return WERR_ACCESS_DENIED;
1932 /* Delete the SD in the database. */
1933 delete_share_security(lp_servicename(talloc_tos(), params->service));
1935 lp_killservice(params->service);
1937 return WERR_OK;
1940 /*******************************************************************
1941 _srvsvc_NetShareDelSticky
1942 ********************************************************************/
1944 WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
1945 struct srvsvc_NetShareDelSticky *r)
1947 struct srvsvc_NetShareDel q;
1949 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1951 q.in.server_unc = r->in.server_unc;
1952 q.in.share_name = r->in.share_name;
1953 q.in.reserved = r->in.reserved;
1955 return _srvsvc_NetShareDel(p, &q);
1958 /*******************************************************************
1959 _srvsvc_NetRemoteTOD
1960 ********************************************************************/
1962 WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
1963 struct srvsvc_NetRemoteTOD *r)
1965 struct srvsvc_NetRemoteTODInfo *tod;
1966 struct tm *t;
1967 time_t unixdate = time(NULL);
1969 /* We do this call first as if we do it *after* the gmtime call
1970 it overwrites the pointed-to values. JRA */
1972 uint32 zone = get_time_zone(unixdate)/60;
1974 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1976 if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1977 return WERR_NOMEM;
1979 *r->out.info = tod;
1981 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1983 t = gmtime(&unixdate);
1985 /* set up the */
1986 tod->elapsed = unixdate;
1987 tod->msecs = 0;
1988 tod->hours = t->tm_hour;
1989 tod->mins = t->tm_min;
1990 tod->secs = t->tm_sec;
1991 tod->hunds = 0;
1992 tod->timezone = zone;
1993 tod->tinterval = 10000;
1994 tod->day = t->tm_mday;
1995 tod->month = t->tm_mon + 1;
1996 tod->year = 1900+t->tm_year;
1997 tod->weekday = t->tm_wday;
1999 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2001 return WERR_OK;
2004 /***********************************************************************************
2005 _srvsvc_NetGetFileSecurity
2006 Win9x NT tools get security descriptor.
2007 ***********************************************************************************/
2009 WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
2010 struct srvsvc_NetGetFileSecurity *r)
2012 struct smb_filename *smb_fname = NULL;
2013 size_t sd_size;
2014 char *servicename = NULL;
2015 SMB_STRUCT_STAT st;
2016 NTSTATUS nt_status;
2017 WERROR werr;
2018 connection_struct *conn = NULL;
2019 struct sec_desc_buf *sd_buf = NULL;
2020 files_struct *fsp = NULL;
2021 int snum;
2022 char *oldcwd = NULL;
2024 ZERO_STRUCT(st);
2026 if (!r->in.share) {
2027 werr = WERR_NET_NAME_NOT_FOUND;
2028 goto error_exit;
2030 snum = find_service(talloc_tos(), r->in.share, &servicename);
2031 if (!servicename) {
2032 werr = WERR_NOMEM;
2033 goto error_exit;
2035 if (snum == -1) {
2036 DEBUG(10, ("Could not find service %s\n", servicename));
2037 werr = WERR_NET_NAME_NOT_FOUND;
2038 goto error_exit;
2041 nt_status = create_conn_struct_cwd(talloc_tos(),
2042 server_event_context(),
2043 server_messaging_context(),
2044 &conn,
2045 snum, lp_pathname(talloc_tos(), snum),
2046 p->session_info, &oldcwd);
2047 if (!NT_STATUS_IS_OK(nt_status)) {
2048 DEBUG(10, ("create_conn_struct failed: %s\n",
2049 nt_errstr(nt_status)));
2050 werr = ntstatus_to_werror(nt_status);
2051 goto error_exit;
2054 nt_status = filename_convert(talloc_tos(),
2055 conn,
2056 false,
2057 r->in.file,
2059 NULL,
2060 &smb_fname);
2061 if (!NT_STATUS_IS_OK(nt_status)) {
2062 werr = ntstatus_to_werror(nt_status);
2063 goto error_exit;
2066 nt_status = SMB_VFS_CREATE_FILE(
2067 conn, /* conn */
2068 NULL, /* req */
2069 0, /* root_dir_fid */
2070 smb_fname, /* fname */
2071 FILE_READ_ATTRIBUTES, /* access_mask */
2072 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2073 FILE_OPEN, /* create_disposition*/
2074 0, /* create_options */
2075 0, /* file_attributes */
2076 INTERNAL_OPEN_ONLY, /* oplock_request */
2077 0, /* allocation_size */
2078 0, /* private_flags */
2079 NULL, /* sd */
2080 NULL, /* ea_list */
2081 &fsp, /* result */
2082 NULL); /* pinfo */
2084 if (!NT_STATUS_IS_OK(nt_status)) {
2085 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2086 smb_fname_str_dbg(smb_fname)));
2087 werr = ntstatus_to_werror(nt_status);
2088 goto error_exit;
2091 sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
2092 if (!sd_buf) {
2093 werr = WERR_NOMEM;
2094 goto error_exit;
2097 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2098 (SECINFO_OWNER
2099 |SECINFO_GROUP
2100 |SECINFO_DACL), sd_buf, &sd_buf->sd);
2102 if (!NT_STATUS_IS_OK(nt_status)) {
2103 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2104 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2105 werr = ntstatus_to_werror(nt_status);
2106 TALLOC_FREE(sd_buf);
2107 goto error_exit;
2110 if (sd_buf->sd->dacl) {
2111 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
2114 sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
2116 sd_buf->sd_size = sd_size;
2118 *r->out.sd_buf = sd_buf;
2120 close_file(NULL, fsp, NORMAL_CLOSE);
2121 vfs_ChDir(conn, oldcwd);
2122 SMB_VFS_DISCONNECT(conn);
2123 conn_free(conn);
2124 werr = WERR_OK;
2125 goto done;
2127 error_exit:
2129 if (fsp) {
2130 close_file(NULL, fsp, NORMAL_CLOSE);
2133 if (oldcwd) {
2134 vfs_ChDir(conn, oldcwd);
2137 if (conn) {
2138 SMB_VFS_DISCONNECT(conn);
2139 conn_free(conn);
2142 done:
2144 TALLOC_FREE(smb_fname);
2146 return werr;
2149 /***********************************************************************************
2150 _srvsvc_NetSetFileSecurity
2151 Win9x NT tools set security descriptor.
2152 ***********************************************************************************/
2154 WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
2155 struct srvsvc_NetSetFileSecurity *r)
2157 struct smb_filename *smb_fname = NULL;
2158 char *servicename = NULL;
2159 files_struct *fsp = NULL;
2160 SMB_STRUCT_STAT st;
2161 NTSTATUS nt_status;
2162 WERROR werr;
2163 connection_struct *conn = NULL;
2164 int snum;
2165 char *oldcwd = NULL;
2166 struct security_descriptor *psd = NULL;
2167 uint32_t security_info_sent = 0;
2169 ZERO_STRUCT(st);
2171 if (!r->in.share) {
2172 werr = WERR_NET_NAME_NOT_FOUND;
2173 goto error_exit;
2176 snum = find_service(talloc_tos(), r->in.share, &servicename);
2177 if (!servicename) {
2178 werr = WERR_NOMEM;
2179 goto error_exit;
2182 if (snum == -1) {
2183 DEBUG(10, ("Could not find service %s\n", servicename));
2184 werr = WERR_NET_NAME_NOT_FOUND;
2185 goto error_exit;
2188 nt_status = create_conn_struct_cwd(talloc_tos(),
2189 server_event_context(),
2190 server_messaging_context(),
2191 &conn,
2192 snum, lp_pathname(talloc_tos(), snum),
2193 p->session_info, &oldcwd);
2194 if (!NT_STATUS_IS_OK(nt_status)) {
2195 DEBUG(10, ("create_conn_struct failed: %s\n",
2196 nt_errstr(nt_status)));
2197 werr = ntstatus_to_werror(nt_status);
2198 goto error_exit;
2201 nt_status = filename_convert(talloc_tos(),
2202 conn,
2203 false,
2204 r->in.file,
2206 NULL,
2207 &smb_fname);
2208 if (!NT_STATUS_IS_OK(nt_status)) {
2209 werr = ntstatus_to_werror(nt_status);
2210 goto error_exit;
2213 nt_status = SMB_VFS_CREATE_FILE(
2214 conn, /* conn */
2215 NULL, /* req */
2216 0, /* root_dir_fid */
2217 smb_fname, /* fname */
2218 FILE_WRITE_ATTRIBUTES, /* access_mask */
2219 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2220 FILE_OPEN, /* create_disposition*/
2221 0, /* create_options */
2222 0, /* file_attributes */
2223 INTERNAL_OPEN_ONLY, /* oplock_request */
2224 0, /* allocation_size */
2225 0, /* private_flags */
2226 NULL, /* sd */
2227 NULL, /* ea_list */
2228 &fsp, /* result */
2229 NULL); /* pinfo */
2231 if (!NT_STATUS_IS_OK(nt_status)) {
2232 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2233 smb_fname_str_dbg(smb_fname)));
2234 werr = ntstatus_to_werror(nt_status);
2235 goto error_exit;
2238 psd = r->in.sd_buf->sd;
2239 security_info_sent = r->in.securityinformation;
2241 nt_status = set_sd(fsp, psd, security_info_sent);
2243 if (!NT_STATUS_IS_OK(nt_status) ) {
2244 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2245 "on file %s\n", r->in.share));
2246 werr = WERR_ACCESS_DENIED;
2247 goto error_exit;
2250 close_file(NULL, fsp, NORMAL_CLOSE);
2251 vfs_ChDir(conn, oldcwd);
2252 SMB_VFS_DISCONNECT(conn);
2253 conn_free(conn);
2254 werr = WERR_OK;
2255 goto done;
2257 error_exit:
2259 if (fsp) {
2260 close_file(NULL, fsp, NORMAL_CLOSE);
2263 if (oldcwd) {
2264 vfs_ChDir(conn, oldcwd);
2267 if (conn) {
2268 SMB_VFS_DISCONNECT(conn);
2269 conn_free(conn);
2272 done:
2273 TALLOC_FREE(smb_fname);
2275 return werr;
2278 /***********************************************************************************
2279 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2280 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2281 These disks would the disks listed by this function.
2282 Users could then create shares relative to these disks. Watch out for moving these disks around.
2283 "Nigel Williams" <nigel@veritas.com>.
2284 ***********************************************************************************/
2286 static const char *server_disks[] = {"C:"};
2288 static uint32 get_server_disk_count(void)
2290 return sizeof(server_disks)/sizeof(server_disks[0]);
2293 static uint32 init_server_disk_enum(uint32 *resume)
2295 uint32 server_disk_count = get_server_disk_count();
2297 /*resume can be an offset into the list for now*/
2299 if(*resume & 0x80000000)
2300 *resume = 0;
2302 if(*resume > server_disk_count)
2303 *resume = server_disk_count;
2305 return server_disk_count - *resume;
2308 static const char *next_server_disk_enum(uint32 *resume)
2310 const char *disk;
2312 if(init_server_disk_enum(resume) == 0)
2313 return NULL;
2315 disk = server_disks[*resume];
2317 (*resume)++;
2319 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2321 return disk;
2324 /********************************************************************
2325 _srvsvc_NetDiskEnum
2326 ********************************************************************/
2328 WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
2329 struct srvsvc_NetDiskEnum *r)
2331 uint32 i;
2332 const char *disk_name;
2333 TALLOC_CTX *ctx = p->mem_ctx;
2334 WERROR werr;
2335 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2337 werr = WERR_OK;
2339 *r->out.totalentries = init_server_disk_enum(&resume);
2341 r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
2342 MAX_SERVER_DISK_ENTRIES);
2343 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2345 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2347 r->out.info->count = 0;
2349 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2351 r->out.info->count++;
2353 /*copy disk name into a unicode string*/
2355 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2356 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2359 /* add a terminating null string. Is this there if there is more data to come? */
2361 r->out.info->count++;
2363 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2364 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2366 if (r->out.resume_handle) {
2367 *r->out.resume_handle = resume;
2370 return werr;
2373 /********************************************************************
2374 _srvsvc_NetNameValidate
2375 ********************************************************************/
2377 WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
2378 struct srvsvc_NetNameValidate *r)
2380 switch (r->in.name_type) {
2381 case 0x9:
2382 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2383 strlen_m(r->in.name)))
2385 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2386 r->in.name));
2387 return WERR_INVALID_NAME;
2389 break;
2391 default:
2392 return WERR_UNKNOWN_LEVEL;
2395 return WERR_OK;
2398 /*******************************************************************
2399 ********************************************************************/
2401 struct enum_file_close_state {
2402 struct srvsvc_NetFileClose *r;
2403 struct messaging_context *msg_ctx;
2406 static void enum_file_close_fn( const struct share_mode_entry *e,
2407 const char *sharepath, const char *fname,
2408 void *private_data )
2410 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2411 struct enum_file_close_state *state =
2412 (struct enum_file_close_state *)private_data;
2413 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2415 if (fid != state->r->in.fid) {
2416 return; /* Not this file. */
2419 if (!process_exists(e->pid) ) {
2420 return;
2423 /* Ok - send the close message. */
2424 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2425 sharepath,
2426 share_mode_str(talloc_tos(), 0, e) ));
2428 share_mode_entry_to_message(msg, e);
2430 state->r->out.result = ntstatus_to_werror(
2431 messaging_send_buf(state->msg_ctx,
2432 e->pid, MSG_SMB_CLOSE_FILE,
2433 (uint8 *)msg,
2434 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2437 /********************************************************************
2438 Close a file given a 32-bit file id.
2439 ********************************************************************/
2441 WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
2442 struct srvsvc_NetFileClose *r)
2444 struct enum_file_close_state state;
2445 bool is_disk_op;
2447 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2449 is_disk_op = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_DISK_OPERATOR);
2451 if (p->session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
2452 return WERR_ACCESS_DENIED;
2455 /* enum_file_close_fn sends the close message to
2456 * the relevent smbd process. */
2458 r->out.result = WERR_BADFILE;
2459 state.r = r;
2460 state.msg_ctx = p->msg_ctx;
2461 share_mode_forall(enum_file_close_fn, &state);
2462 return r->out.result;
2465 /********************************************************************
2466 ********************************************************************/
2468 WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
2469 struct srvsvc_NetCharDevEnum *r)
2471 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2472 return WERR_NOT_SUPPORTED;
2475 WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
2476 struct srvsvc_NetCharDevGetInfo *r)
2478 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2479 return WERR_NOT_SUPPORTED;
2482 WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
2483 struct srvsvc_NetCharDevControl *r)
2485 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2486 return WERR_NOT_SUPPORTED;
2489 WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
2490 struct srvsvc_NetCharDevQEnum *r)
2492 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2493 return WERR_NOT_SUPPORTED;
2496 WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
2497 struct srvsvc_NetCharDevQGetInfo *r)
2499 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2500 return WERR_NOT_SUPPORTED;
2503 WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
2504 struct srvsvc_NetCharDevQSetInfo *r)
2506 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2507 return WERR_NOT_SUPPORTED;
2510 WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
2511 struct srvsvc_NetCharDevQPurge *r)
2513 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2514 return WERR_NOT_SUPPORTED;
2517 WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
2518 struct srvsvc_NetCharDevQPurgeSelf *r)
2520 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2521 return WERR_NOT_SUPPORTED;
2524 WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
2525 struct srvsvc_NetFileGetInfo *r)
2527 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2528 return WERR_NOT_SUPPORTED;
2531 WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
2532 struct srvsvc_NetShareCheck *r)
2534 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2535 return WERR_NOT_SUPPORTED;
2538 WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
2539 struct srvsvc_NetServerStatisticsGet *r)
2541 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
2546 struct srvsvc_NetTransportAdd *r)
2548 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2549 return WERR_NOT_SUPPORTED;
2552 WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
2553 struct srvsvc_NetTransportEnum *r)
2555 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2556 return WERR_NOT_SUPPORTED;
2559 WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
2560 struct srvsvc_NetTransportDel *r)
2562 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2563 return WERR_NOT_SUPPORTED;
2566 WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
2567 struct srvsvc_NetSetServiceBits *r)
2569 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2570 return WERR_NOT_SUPPORTED;
2573 WERROR _srvsvc_NetPathType(struct pipes_struct *p,
2574 struct srvsvc_NetPathType *r)
2576 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2577 return WERR_NOT_SUPPORTED;
2580 WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
2581 struct srvsvc_NetPathCanonicalize *r)
2583 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
2588 struct srvsvc_NetPathCompare *r)
2590 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2591 return WERR_NOT_SUPPORTED;
2594 WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
2595 struct srvsvc_NETRPRNAMECANONICALIZE *r)
2597 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2598 return WERR_NOT_SUPPORTED;
2601 WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
2602 struct srvsvc_NetPRNameCompare *r)
2604 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2605 return WERR_NOT_SUPPORTED;
2608 WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
2609 struct srvsvc_NetShareDelStart *r)
2611 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2612 return WERR_NOT_SUPPORTED;
2615 WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
2616 struct srvsvc_NetShareDelCommit *r)
2618 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2619 return WERR_NOT_SUPPORTED;
2622 WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
2623 struct srvsvc_NetServerTransportAddEx *r)
2625 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2626 return WERR_NOT_SUPPORTED;
2629 WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
2630 struct srvsvc_NetServerSetServiceBitsEx *r)
2632 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2633 return WERR_NOT_SUPPORTED;
2636 WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
2637 struct srvsvc_NETRDFSGETVERSION *r)
2639 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2640 return WERR_NOT_SUPPORTED;
2643 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
2644 struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2646 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2647 return WERR_NOT_SUPPORTED;
2650 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
2651 struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2653 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2654 return WERR_NOT_SUPPORTED;
2657 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
2658 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2660 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2661 return WERR_NOT_SUPPORTED;
2664 WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
2665 struct srvsvc_NETRDFSSETSERVERINFO *r)
2667 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2668 return WERR_NOT_SUPPORTED;
2671 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
2672 struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2674 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2675 return WERR_NOT_SUPPORTED;
2678 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
2679 struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2681 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2682 return WERR_NOT_SUPPORTED;
2685 WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
2686 struct srvsvc_NETRDFSMODIFYPREFIX *r)
2688 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2689 return WERR_NOT_SUPPORTED;
2692 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
2693 struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2695 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2696 return WERR_NOT_SUPPORTED;
2699 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
2700 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2702 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2703 return WERR_NOT_SUPPORTED;
2706 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
2707 struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2709 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2710 return WERR_NOT_SUPPORTED;