More fix to initialize idmap statuses
[Samba/gbeck.git] / source3 / rpc_server / srv_srvsvc_nt.c
blob056236f22dcff07c5efe1ea1780a8327223a740e
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"
28 extern const struct generic_mapping file_generic_mapping;
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
33 #define MAX_SERVER_DISK_ENTRIES 15
35 /* Use for enumerating connections, pipes, & files */
37 struct file_enum_count {
38 TALLOC_CTX *ctx;
39 const char *username;
40 struct srvsvc_NetFileCtr3 *ctr3;
43 struct sess_file_count {
44 struct server_id pid;
45 uid_t uid;
46 int count;
49 /****************************************************************************
50 Count the entries belonging to a service in the connection db.
51 ****************************************************************************/
53 static int pipe_enum_fn( struct db_record *rec, void *p)
55 struct pipe_open_rec prec;
56 struct file_enum_count *fenum = (struct file_enum_count *)p;
57 struct srvsvc_NetFileInfo3 *f;
58 int i = fenum->ctr3->count;
59 char *fullpath = NULL;
60 const char *username;
62 if (rec->value.dsize != sizeof(struct pipe_open_rec))
63 return 0;
65 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
67 if ( !process_exists(prec.pid) ) {
68 return 0;
71 username = uidtoname(prec.uid);
73 if ((fenum->username != NULL)
74 && !strequal(username, fenum->username)) {
75 return 0;
78 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
79 if (!fullpath) {
80 return 1;
83 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
84 struct srvsvc_NetFileInfo3, i+1);
85 if ( !f ) {
86 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
87 return 1;
89 fenum->ctr3->array = f;
91 fenum->ctr3->array[i].fid =
92 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
93 fenum->ctr3->array[i].permissions =
94 (FILE_READ_DATA|FILE_WRITE_DATA);
95 fenum->ctr3->array[i].num_locks = 0;
96 fenum->ctr3->array[i].path = fullpath;
97 fenum->ctr3->array[i].user = username;
99 fenum->ctr3->count++;
101 return 0;
104 /*******************************************************************
105 ********************************************************************/
107 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
108 const char *username,
109 struct srvsvc_NetFileCtr3 **ctr3,
110 uint32_t resume )
112 struct file_enum_count fenum;
114 fenum.ctx = ctx;
115 fenum.username = username;
116 fenum.ctr3 = *ctr3;
118 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
119 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
120 "failed\n"));
121 return WERR_NOMEM;
124 *ctr3 = fenum.ctr3;
126 return WERR_OK;
129 /*******************************************************************
130 ********************************************************************/
132 static void enum_file_fn( const struct share_mode_entry *e,
133 const char *sharepath, const char *fname,
134 void *private_data )
136 struct file_enum_count *fenum =
137 (struct file_enum_count *)private_data;
139 struct srvsvc_NetFileInfo3 *f;
140 int i = fenum->ctr3->count;
141 files_struct fsp;
142 struct byte_range_lock *brl;
143 int num_locks = 0;
144 char *fullpath = NULL;
145 uint32 permissions;
146 const char *username;
148 /* If the pid was not found delete the entry from connections.tdb */
150 if ( !process_exists(e->pid) ) {
151 return;
154 username = uidtoname(e->uid);
156 if ((fenum->username != NULL)
157 && !strequal(username, fenum->username)) {
158 return;
161 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
162 struct srvsvc_NetFileInfo3, i+1);
163 if ( !f ) {
164 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
165 return;
167 fenum->ctr3->array = f;
169 /* need to count the number of locks on a file */
171 ZERO_STRUCT( fsp );
172 fsp.file_id = e->id;
174 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
175 num_locks = brl->num_locks;
176 TALLOC_FREE(brl);
179 if ( strcmp( fname, "." ) == 0 ) {
180 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
181 } else {
182 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
183 sharepath, fname );
185 if (!fullpath) {
186 return;
188 string_replace( fullpath, '/', '\\' );
190 /* mask out create (what ever that is) */
191 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
193 /* now fill in the srvsvc_NetFileInfo3 struct */
195 fenum->ctr3->array[i].fid =
196 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
197 fenum->ctr3->array[i].permissions = permissions;
198 fenum->ctr3->array[i].num_locks = num_locks;
199 fenum->ctr3->array[i].path = fullpath;
200 fenum->ctr3->array[i].user = username;
202 fenum->ctr3->count++;
205 /*******************************************************************
206 ********************************************************************/
208 static WERROR net_enum_files(TALLOC_CTX *ctx,
209 const char *username,
210 struct srvsvc_NetFileCtr3 **ctr3,
211 uint32_t resume)
213 struct file_enum_count f_enum_cnt;
215 f_enum_cnt.ctx = ctx;
216 f_enum_cnt.username = username;
217 f_enum_cnt.ctr3 = *ctr3;
219 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
221 *ctr3 = f_enum_cnt.ctr3;
223 return WERR_OK;
226 /*******************************************************************
227 Utility function to get the 'type' of a share from an snum.
228 ********************************************************************/
229 static uint32 get_share_type(int snum)
231 /* work out the share type */
232 uint32 type = STYPE_DISKTREE;
234 if (lp_print_ok(snum))
235 type = STYPE_PRINTQ;
236 if (strequal(lp_fstype(snum), "IPC"))
237 type = STYPE_IPC;
238 if (lp_administrative_share(snum))
239 type |= STYPE_HIDDEN;
241 return type;
244 /*******************************************************************
245 Fill in a share info level 0 structure.
246 ********************************************************************/
248 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
250 r->name = lp_servicename(snum);
253 /*******************************************************************
254 Fill in a share info level 1 structure.
255 ********************************************************************/
257 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
259 char *net_name = lp_servicename(snum);
260 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
262 if (remark) {
263 remark = talloc_sub_advanced(
264 p->mem_ctx, lp_servicename(snum),
265 get_current_username(), lp_pathname(snum),
266 p->server_info->utok.uid, get_current_username(),
267 "", remark);
270 r->name = net_name;
271 r->type = get_share_type(snum);
272 r->comment = remark ? remark : "";
275 /*******************************************************************
276 Fill in a share info level 2 structure.
277 ********************************************************************/
279 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
281 char *remark = NULL;
282 char *path = NULL;
283 int max_connections = lp_max_connections(snum);
284 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
285 char *net_name = lp_servicename(snum);
287 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
288 if (remark) {
289 remark = talloc_sub_advanced(
290 p->mem_ctx, lp_servicename(snum),
291 get_current_username(), lp_pathname(snum),
292 p->server_info->utok.uid, get_current_username(),
293 "", remark);
295 path = talloc_asprintf(p->mem_ctx,
296 "C:%s", lp_pathname(snum));
298 if (path) {
300 * Change / to \\ so that win2k will see it as a valid path.
301 * This was added to enable use of browsing in win2k add
302 * share dialog.
305 string_replace(path, '/', '\\');
308 r->name = net_name;
309 r->type = get_share_type(snum);
310 r->comment = remark ? remark : "";
311 r->permissions = 0;
312 r->max_users = max_uses;
313 r->current_users = count_current_connections(net_name, false);
314 r->path = path ? path : "";
315 r->password = "";
318 /*******************************************************************
319 Map any generic bits to file specific bits.
320 ********************************************************************/
322 static void map_generic_share_sd_bits(SEC_DESC *psd)
324 int i;
325 SEC_ACL *ps_dacl = NULL;
327 if (!psd)
328 return;
330 ps_dacl = psd->dacl;
331 if (!ps_dacl)
332 return;
334 for (i = 0; i < ps_dacl->num_aces; i++) {
335 SEC_ACE *psa = &ps_dacl->aces[i];
336 uint32 orig_mask = psa->access_mask;
338 se_map_generic(&psa->access_mask, &file_generic_mapping);
339 psa->access_mask |= orig_mask;
343 /*******************************************************************
344 Fill in a share info level 501 structure.
345 ********************************************************************/
347 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
349 const char *net_name = lp_servicename(snum);
350 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
352 if (remark) {
353 remark = talloc_sub_advanced(
354 p->mem_ctx, lp_servicename(snum),
355 get_current_username(), lp_pathname(snum),
356 p->server_info->utok.uid, get_current_username(),
357 "", remark);
360 r->name = net_name;
361 r->type = get_share_type(snum);
362 r->comment = remark ? remark : "";
363 r->csc_policy = (lp_csc_policy(snum) << 4);
366 /*******************************************************************
367 Fill in a share info level 502 structure.
368 ********************************************************************/
370 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
372 const char *net_name = lp_servicename(snum);
373 char *path = NULL;
374 SEC_DESC *sd = NULL;
375 struct sec_desc_buf *sd_buf = NULL;
376 size_t sd_size = 0;
377 TALLOC_CTX *ctx = p->mem_ctx;
378 char *remark = talloc_strdup(ctx, lp_comment(snum));;
380 if (remark) {
381 remark = talloc_sub_advanced(
382 p->mem_ctx, lp_servicename(snum),
383 get_current_username(), lp_pathname(snum),
384 p->server_info->utok.uid, get_current_username(),
385 "", remark);
387 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
388 if (path) {
390 * Change / to \\ so that win2k will see it as a valid path. This was added to
391 * enable use of browsing in win2k add share dialog.
393 string_replace(path, '/', '\\');
396 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
398 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
400 r->name = net_name;
401 r->type = get_share_type(snum);
402 r->comment = remark ? remark : "";
403 r->permissions = 0;
404 r->max_users = (uint32_t)-1;
405 r->current_users = 1; /* ??? */
406 r->path = path ? path : "";
407 r->password = "";
408 r->sd_buf = *sd_buf;
411 /***************************************************************************
412 Fill in a share info level 1004 structure.
413 ***************************************************************************/
415 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
417 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
419 if (remark) {
420 remark = talloc_sub_advanced(
421 p->mem_ctx, lp_servicename(snum),
422 get_current_username(), lp_pathname(snum),
423 p->server_info->utok.uid, get_current_username(),
424 "", remark);
427 r->comment = remark ? remark : "";
430 /***************************************************************************
431 Fill in a share info level 1005 structure.
432 ***************************************************************************/
434 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
436 uint32_t dfs_flags = 0;
438 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
439 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
442 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
444 r->dfs_flags = dfs_flags;
447 /***************************************************************************
448 Fill in a share info level 1006 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
453 r->max_users = (uint32_t)-1;
456 /***************************************************************************
457 Fill in a share info level 1007 structure.
458 ***************************************************************************/
460 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
462 r->flags = 0;
463 r->alternate_directory_name = "";
466 /*******************************************************************
467 Fill in a share info level 1501 structure.
468 ********************************************************************/
470 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
472 SEC_DESC *sd;
473 size_t sd_size;
474 TALLOC_CTX *ctx = p->mem_ctx;
476 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
478 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
481 /*******************************************************************
482 True if it ends in '$'.
483 ********************************************************************/
485 static bool is_hidden_share(int snum)
487 const char *net_name = lp_servicename(snum);
489 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
492 /*******************************************************************
493 Verify user is allowed to view share, access based enumeration
494 ********************************************************************/
495 static bool is_enumeration_allowed(pipes_struct *p,
496 int snum)
498 if (!lp_access_based_share_enum(snum))
499 return true;
501 return share_access_check(p->server_info->ptok, lp_servicename(snum),
502 FILE_READ_DATA);
505 /*******************************************************************
506 Fill in a share info structure.
507 ********************************************************************/
509 static WERROR init_srv_share_info_ctr(pipes_struct *p,
510 struct srvsvc_NetShareInfoCtr *info_ctr,
511 uint32_t *resume_handle_p,
512 uint32_t *total_entries,
513 bool all_shares)
515 int num_entries = 0;
516 int alloc_entries = 0;
517 int num_services = 0;
518 int snum;
519 TALLOC_CTX *ctx = p->mem_ctx;
520 int i = 0;
521 int valid_share_count = 0;
522 bool *allowed = 0;
523 union srvsvc_NetShareCtr ctr;
524 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
526 DEBUG(5,("init_srv_share_info_ctr\n"));
528 /* Ensure all the usershares are loaded. */
529 become_root();
530 load_usershare_shares();
531 load_registry_shares();
532 num_services = lp_numservices();
533 unbecome_root();
535 allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
536 W_ERROR_HAVE_NO_MEMORY(allowed);
538 /* Count the number of entries. */
539 for (snum = 0; snum < num_services; snum++) {
540 if (lp_browseable(snum) && lp_snum_ok(snum) &&
541 is_enumeration_allowed(p, snum) &&
542 (all_shares || !is_hidden_share(snum)) ) {
543 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
544 allowed[snum] = true;
545 num_entries++;
546 } else {
547 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
551 if (!num_entries || (resume_handle >= num_entries)) {
552 return WERR_OK;
555 /* Calculate alloc entries. */
556 alloc_entries = num_entries - resume_handle;
557 switch (info_ctr->level) {
558 case 0:
559 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
560 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
562 ctr.ctr0->count = alloc_entries;
563 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
564 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
566 for (snum = 0; snum < num_services; snum++) {
567 if (allowed[snum] &&
568 (resume_handle <= (i + valid_share_count++)) ) {
569 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
573 break;
575 case 1:
576 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
577 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
579 ctr.ctr1->count = alloc_entries;
580 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
581 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
583 for (snum = 0; snum < num_services; snum++) {
584 if (allowed[snum] &&
585 (resume_handle <= (i + valid_share_count++)) ) {
586 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
590 break;
592 case 2:
593 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
594 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
596 ctr.ctr2->count = alloc_entries;
597 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
598 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
600 for (snum = 0; snum < num_services; snum++) {
601 if (allowed[snum] &&
602 (resume_handle <= (i + valid_share_count++)) ) {
603 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
607 break;
609 case 501:
610 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
611 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
613 ctr.ctr501->count = alloc_entries;
614 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
615 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
617 for (snum = 0; snum < num_services; snum++) {
618 if (allowed[snum] &&
619 (resume_handle <= (i + valid_share_count++)) ) {
620 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
624 break;
626 case 502:
627 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
628 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
630 ctr.ctr502->count = alloc_entries;
631 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
632 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
634 for (snum = 0; snum < num_services; snum++) {
635 if (allowed[snum] &&
636 (resume_handle <= (i + valid_share_count++)) ) {
637 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
641 break;
643 case 1004:
644 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
645 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
647 ctr.ctr1004->count = alloc_entries;
648 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
649 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
651 for (snum = 0; snum < num_services; snum++) {
652 if (allowed[snum] &&
653 (resume_handle <= (i + valid_share_count++)) ) {
654 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
658 break;
660 case 1005:
661 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
662 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
664 ctr.ctr1005->count = alloc_entries;
665 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
666 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
668 for (snum = 0; snum < num_services; snum++) {
669 if (allowed[snum] &&
670 (resume_handle <= (i + valid_share_count++)) ) {
671 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
675 break;
677 case 1006:
678 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
679 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
681 ctr.ctr1006->count = alloc_entries;
682 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
683 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
685 for (snum = 0; snum < num_services; snum++) {
686 if (allowed[snum] &&
687 (resume_handle <= (i + valid_share_count++)) ) {
688 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
692 break;
694 case 1007:
695 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
696 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
698 ctr.ctr1007->count = alloc_entries;
699 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
700 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
702 for (snum = 0; snum < num_services; snum++) {
703 if (allowed[snum] &&
704 (resume_handle <= (i + valid_share_count++)) ) {
705 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
709 break;
711 case 1501:
712 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
713 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
715 ctr.ctr1501->count = alloc_entries;
716 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
717 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
719 for (snum = 0; snum < num_services; snum++) {
720 if (allowed[snum] &&
721 (resume_handle <= (i + valid_share_count++)) ) {
722 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
726 break;
728 default:
729 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
730 info_ctr->level));
731 return WERR_UNKNOWN_LEVEL;
734 *total_entries = alloc_entries;
735 if (resume_handle_p) {
736 if (all_shares) {
737 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
738 } else {
739 *resume_handle_p = num_entries;
743 info_ctr->ctr = ctr;
745 return WERR_OK;
748 /*******************************************************************
749 fill in a sess info level 0 structure.
750 ********************************************************************/
752 static WERROR init_srv_sess_info_0(pipes_struct *p,
753 struct srvsvc_NetSessCtr0 *ctr0,
754 uint32_t *resume_handle_p,
755 uint32_t *total_entries)
757 struct sessionid *session_list;
758 uint32_t num_entries = 0;
759 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
760 *total_entries = list_sessions(p->mem_ctx, &session_list);
762 DEBUG(5,("init_srv_sess_info_0\n"));
764 if (ctr0 == NULL) {
765 if (resume_handle_p) {
766 *resume_handle_p = 0;
768 return WERR_OK;
771 for (; resume_handle < *total_entries; resume_handle++) {
773 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
774 ctr0->array,
775 struct srvsvc_NetSessInfo0,
776 num_entries+1);
777 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
779 ctr0->array[num_entries].client =
780 session_list[resume_handle].remote_machine;
782 num_entries++;
785 ctr0->count = num_entries;
787 if (resume_handle_p) {
788 if (*resume_handle_p >= *total_entries) {
789 *resume_handle_p = 0;
790 } else {
791 *resume_handle_p = resume_handle;
795 return WERR_OK;
798 /*******************************************************************
799 ********************************************************************/
801 static void sess_file_fn( const struct share_mode_entry *e,
802 const char *sharepath, const char *fname,
803 void *data )
805 struct sess_file_count *sess = (struct sess_file_count *)data;
807 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
808 sess->count++;
811 return;
814 /*******************************************************************
815 ********************************************************************/
817 static int net_count_files( uid_t uid, struct server_id pid )
819 struct sess_file_count s_file_cnt;
821 s_file_cnt.count = 0;
822 s_file_cnt.uid = uid;
823 s_file_cnt.pid = pid;
825 share_mode_forall( sess_file_fn, &s_file_cnt );
827 return s_file_cnt.count;
830 /*******************************************************************
831 fill in a sess info level 1 structure.
832 ********************************************************************/
834 static WERROR init_srv_sess_info_1(pipes_struct *p,
835 struct srvsvc_NetSessCtr1 *ctr1,
836 uint32_t *resume_handle_p,
837 uint32_t *total_entries)
839 struct sessionid *session_list;
840 uint32_t num_entries = 0;
841 time_t now = time(NULL);
842 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
844 ZERO_STRUCTP(ctr1);
846 if (ctr1 == NULL) {
847 if (resume_handle_p) {
848 *resume_handle_p = 0;
850 return WERR_OK;
853 *total_entries = list_sessions(p->mem_ctx, &session_list);
855 for (; resume_handle < *total_entries; resume_handle++) {
856 uint32 num_files;
857 uint32 connect_time;
858 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
859 bool guest;
861 if ( !pw ) {
862 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
863 session_list[resume_handle].username));
864 continue;
867 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
868 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
869 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
871 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
872 ctr1->array,
873 struct srvsvc_NetSessInfo1,
874 num_entries+1);
875 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
877 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
878 ctr1->array[num_entries].user = session_list[resume_handle].username;
879 ctr1->array[num_entries].num_open = num_files;
880 ctr1->array[num_entries].time = connect_time;
881 ctr1->array[num_entries].idle_time = 0;
882 ctr1->array[num_entries].user_flags = guest;
884 num_entries++;
887 ctr1->count = num_entries;
889 if (resume_handle_p) {
890 if (*resume_handle_p >= *total_entries) {
891 *resume_handle_p = 0;
892 } else {
893 *resume_handle_p = resume_handle;
897 return WERR_OK;
900 /*******************************************************************
901 fill in a conn info level 0 structure.
902 ********************************************************************/
904 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
905 uint32_t *resume_handle_p,
906 uint32_t *total_entries)
908 uint32_t num_entries = 0;
909 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
911 DEBUG(5,("init_srv_conn_info_0\n"));
913 if (ctr0 == NULL) {
914 if (resume_handle_p) {
915 *resume_handle_p = 0;
917 return WERR_OK;
920 *total_entries = 1;
922 ZERO_STRUCTP(ctr0);
924 for (; resume_handle < *total_entries; resume_handle++) {
926 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
927 ctr0->array,
928 struct srvsvc_NetConnInfo0,
929 num_entries+1);
930 if (!ctr0->array) {
931 return WERR_NOMEM;
934 ctr0->array[num_entries].conn_id = *total_entries;
936 /* move on to creating next connection */
937 num_entries++;
940 ctr0->count = num_entries;
941 *total_entries = num_entries;
943 if (resume_handle_p) {
944 if (*resume_handle_p >= *total_entries) {
945 *resume_handle_p = 0;
946 } else {
947 *resume_handle_p = resume_handle;
951 return WERR_OK;
954 /*******************************************************************
955 fill in a conn info level 1 structure.
956 ********************************************************************/
958 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
959 uint32_t *resume_handle_p,
960 uint32_t *total_entries)
962 uint32_t num_entries = 0;
963 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
965 DEBUG(5,("init_srv_conn_info_1\n"));
967 if (ctr1 == NULL) {
968 if (resume_handle_p) {
969 *resume_handle_p = 0;
971 return WERR_OK;
974 *total_entries = 1;
976 ZERO_STRUCTP(ctr1);
978 for (; resume_handle < *total_entries; resume_handle++) {
980 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
981 ctr1->array,
982 struct srvsvc_NetConnInfo1,
983 num_entries+1);
984 if (!ctr1->array) {
985 return WERR_NOMEM;
988 ctr1->array[num_entries].conn_id = *total_entries;
989 ctr1->array[num_entries].conn_type = 0x3;
990 ctr1->array[num_entries].num_open = 1;
991 ctr1->array[num_entries].num_users = 1;
992 ctr1->array[num_entries].conn_time = 3;
993 ctr1->array[num_entries].user = "dummy_user";
994 ctr1->array[num_entries].share = "IPC$";
996 /* move on to creating next connection */
997 num_entries++;
1000 ctr1->count = num_entries;
1001 *total_entries = num_entries;
1003 if (resume_handle_p) {
1004 if (*resume_handle_p >= *total_entries) {
1005 *resume_handle_p = 0;
1006 } else {
1007 *resume_handle_p = resume_handle;
1011 return WERR_OK;
1014 /*******************************************************************
1015 _srvsvc_NetFileEnum
1016 *******************************************************************/
1018 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
1019 struct srvsvc_NetFileEnum *r)
1021 TALLOC_CTX *ctx = NULL;
1022 struct srvsvc_NetFileCtr3 *ctr3;
1023 uint32_t resume_hnd = 0;
1024 WERROR werr;
1026 switch (r->in.info_ctr->level) {
1027 case 3:
1028 break;
1029 default:
1030 return WERR_UNKNOWN_LEVEL;
1033 ctx = talloc_tos();
1034 ctr3 = r->in.info_ctr->ctr.ctr3;
1035 if (!ctr3) {
1036 werr = WERR_INVALID_PARAM;
1037 goto done;
1040 /* TODO -- Windows enumerates
1041 (b) active pipes
1042 (c) open directories and files */
1044 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1045 if (!W_ERROR_IS_OK(werr)) {
1046 goto done;
1049 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1050 if (!W_ERROR_IS_OK(werr)) {
1051 goto done;
1054 *r->out.totalentries = ctr3->count;
1055 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1056 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1058 werr = WERR_OK;
1060 done:
1061 return werr;
1064 /*******************************************************************
1065 _srvsvc_NetSrvGetInfo
1066 ********************************************************************/
1068 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1069 struct srvsvc_NetSrvGetInfo *r)
1071 WERROR status = WERR_OK;
1073 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1075 if (!pipe_access_check(p)) {
1076 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1077 return WERR_ACCESS_DENIED;
1080 switch (r->in.level) {
1082 /* Technically level 102 should only be available to
1083 Administrators but there isn't anything super-secret
1084 here, as most of it is made up. */
1086 case 102: {
1087 struct srvsvc_NetSrvInfo102 *info102;
1089 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1090 if (!info102) {
1091 return WERR_NOMEM;
1094 info102->platform_id = PLATFORM_ID_NT;
1095 info102->server_name = global_myname();
1096 info102->version_major = lp_major_announce_version();
1097 info102->version_minor = lp_minor_announce_version();
1098 info102->server_type = lp_default_server_announce();
1099 info102->comment = string_truncate(lp_serverstring(),
1100 MAX_SERVER_STRING_LENGTH);
1101 info102->users = 0xffffffff;
1102 info102->disc = 0xf;
1103 info102->hidden = 0;
1104 info102->announce = 240;
1105 info102->anndelta = 3000;
1106 info102->licenses = 100000;
1107 info102->userpath = "C:\\";
1109 r->out.info->info102 = info102;
1110 break;
1112 case 101: {
1113 struct srvsvc_NetSrvInfo101 *info101;
1115 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1116 if (!info101) {
1117 return WERR_NOMEM;
1120 info101->platform_id = PLATFORM_ID_NT;
1121 info101->server_name = global_myname();
1122 info101->version_major = lp_major_announce_version();
1123 info101->version_minor = lp_minor_announce_version();
1124 info101->server_type = lp_default_server_announce();
1125 info101->comment = string_truncate(lp_serverstring(),
1126 MAX_SERVER_STRING_LENGTH);
1128 r->out.info->info101 = info101;
1129 break;
1131 case 100: {
1132 struct srvsvc_NetSrvInfo100 *info100;
1134 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1135 if (!info100) {
1136 return WERR_NOMEM;
1139 info100->platform_id = PLATFORM_ID_NT;
1140 info100->server_name = global_myname();
1142 r->out.info->info100 = info100;
1144 break;
1146 default:
1147 status = WERR_UNKNOWN_LEVEL;
1148 break;
1151 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1153 return status;
1156 /*******************************************************************
1157 _srvsvc_NetSrvSetInfo
1158 ********************************************************************/
1160 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1161 struct srvsvc_NetSrvSetInfo *r)
1163 WERROR status = WERR_OK;
1165 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1167 /* Set up the net server set info structure. */
1169 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1171 return status;
1174 /*******************************************************************
1175 _srvsvc_NetConnEnum
1176 ********************************************************************/
1178 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1179 struct srvsvc_NetConnEnum *r)
1181 WERROR werr;
1183 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1185 switch (r->in.info_ctr->level) {
1186 case 0:
1187 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1188 r->in.resume_handle,
1189 r->out.totalentries);
1190 break;
1191 case 1:
1192 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1193 r->in.resume_handle,
1194 r->out.totalentries);
1195 break;
1196 default:
1197 return WERR_UNKNOWN_LEVEL;
1200 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1202 return werr;
1205 /*******************************************************************
1206 _srvsvc_NetSessEnum
1207 ********************************************************************/
1209 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1210 struct srvsvc_NetSessEnum *r)
1212 WERROR werr;
1214 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1216 switch (r->in.info_ctr->level) {
1217 case 0:
1218 werr = init_srv_sess_info_0(p,
1219 r->in.info_ctr->ctr.ctr0,
1220 r->in.resume_handle,
1221 r->out.totalentries);
1222 break;
1223 case 1:
1224 werr = init_srv_sess_info_1(p,
1225 r->in.info_ctr->ctr.ctr1,
1226 r->in.resume_handle,
1227 r->out.totalentries);
1228 break;
1229 default:
1230 return WERR_UNKNOWN_LEVEL;
1233 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1235 return werr;
1238 /*******************************************************************
1239 _srvsvc_NetSessDel
1240 ********************************************************************/
1242 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1243 struct srvsvc_NetSessDel *r)
1245 struct sessionid *session_list;
1246 int num_sessions, snum;
1247 const char *username;
1248 const char *machine;
1249 bool not_root = False;
1250 WERROR werr;
1252 username = r->in.user;
1253 machine = r->in.client;
1255 /* strip leading backslashes if any */
1256 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1257 machine += 2;
1260 num_sessions = list_sessions(p->mem_ctx, &session_list);
1262 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1264 werr = WERR_ACCESS_DENIED;
1266 /* fail out now if you are not root or not a domain admin */
1268 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1269 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1270 DOMAIN_GROUP_RID_ADMINS))) {
1272 goto done;
1275 for (snum = 0; snum < num_sessions; snum++) {
1277 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1278 strequal(session_list[snum].remote_machine, machine)) {
1280 NTSTATUS ntstat;
1282 if (p->server_info->utok.uid != sec_initial_uid()) {
1283 not_root = True;
1284 become_root();
1287 ntstat = messaging_send(smbd_messaging_context(),
1288 session_list[snum].pid,
1289 MSG_SHUTDOWN, &data_blob_null);
1291 if (NT_STATUS_IS_OK(ntstat))
1292 werr = WERR_OK;
1294 if (not_root)
1295 unbecome_root();
1299 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1301 done:
1303 return werr;
1306 /*******************************************************************
1307 _srvsvc_NetShareEnumAll
1308 ********************************************************************/
1310 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1311 struct srvsvc_NetShareEnumAll *r)
1313 WERROR werr;
1315 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1317 if (!pipe_access_check(p)) {
1318 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1319 return WERR_ACCESS_DENIED;
1322 /* Create the list of shares for the response. */
1323 werr = init_srv_share_info_ctr(p,
1324 r->in.info_ctr,
1325 r->in.resume_handle,
1326 r->out.totalentries,
1327 true);
1329 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1331 return werr;
1334 /*******************************************************************
1335 _srvsvc_NetShareEnum
1336 ********************************************************************/
1338 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1339 struct srvsvc_NetShareEnum *r)
1341 WERROR werr;
1343 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1345 if (!pipe_access_check(p)) {
1346 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1347 return WERR_ACCESS_DENIED;
1350 /* Create the list of shares for the response. */
1351 werr = init_srv_share_info_ctr(p,
1352 r->in.info_ctr,
1353 r->in.resume_handle,
1354 r->out.totalentries,
1355 false);
1357 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1359 return werr;
1362 /*******************************************************************
1363 _srvsvc_NetShareGetInfo
1364 ********************************************************************/
1366 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1367 struct srvsvc_NetShareGetInfo *r)
1369 WERROR status = WERR_OK;
1370 fstring share_name;
1371 int snum;
1372 union srvsvc_NetShareInfo *info = r->out.info;
1374 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1376 fstrcpy(share_name, r->in.share_name);
1378 snum = find_service(share_name);
1379 if (snum < 0) {
1380 return WERR_INVALID_NAME;
1383 switch (r->in.level) {
1384 case 0:
1385 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1386 W_ERROR_HAVE_NO_MEMORY(info->info0);
1387 init_srv_share_info_0(p, info->info0, snum);
1388 break;
1389 case 1:
1390 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1391 W_ERROR_HAVE_NO_MEMORY(info->info1);
1392 init_srv_share_info_1(p, info->info1, snum);
1393 break;
1394 case 2:
1395 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1396 W_ERROR_HAVE_NO_MEMORY(info->info2);
1397 init_srv_share_info_2(p, info->info2, snum);
1398 break;
1399 case 501:
1400 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1401 W_ERROR_HAVE_NO_MEMORY(info->info501);
1402 init_srv_share_info_501(p, info->info501, snum);
1403 break;
1404 case 502:
1405 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1406 W_ERROR_HAVE_NO_MEMORY(info->info502);
1407 init_srv_share_info_502(p, info->info502, snum);
1408 break;
1409 case 1004:
1410 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1411 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1412 init_srv_share_info_1004(p, info->info1004, snum);
1413 break;
1414 case 1005:
1415 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1416 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1417 init_srv_share_info_1005(p, info->info1005, snum);
1418 break;
1419 case 1006:
1420 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1421 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1422 init_srv_share_info_1006(p, info->info1006, snum);
1423 break;
1424 case 1007:
1425 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1426 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1427 init_srv_share_info_1007(p, info->info1007, snum);
1428 break;
1429 case 1501:
1430 init_srv_share_info_1501(p, info->info1501, snum);
1431 break;
1432 default:
1433 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1434 r->in.level));
1435 status = WERR_UNKNOWN_LEVEL;
1436 break;
1439 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1441 return status;
1444 /*******************************************************************
1445 Check a given DOS pathname is valid for a share.
1446 ********************************************************************/
1448 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1450 char *ptr = NULL;
1452 if (!dos_pathname) {
1453 return NULL;
1456 ptr = talloc_strdup(ctx, dos_pathname);
1457 if (!ptr) {
1458 return NULL;
1460 /* Convert any '\' paths to '/' */
1461 unix_format(ptr);
1462 ptr = unix_clean_name(ctx, ptr);
1463 if (!ptr) {
1464 return NULL;
1467 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1468 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1469 ptr += 2;
1471 /* Only absolute paths allowed. */
1472 if (*ptr != '/')
1473 return NULL;
1475 return ptr;
1478 /*******************************************************************
1479 _srvsvc_NetShareSetInfo. Modify share details.
1480 ********************************************************************/
1482 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1483 struct srvsvc_NetShareSetInfo *r)
1485 char *command = NULL;
1486 char *share_name = NULL;
1487 char *comment = NULL;
1488 const char *pathname = NULL;
1489 int type;
1490 int snum;
1491 int ret;
1492 char *path = NULL;
1493 SEC_DESC *psd = NULL;
1494 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1495 bool is_disk_op = False;
1496 int max_connections = 0;
1497 TALLOC_CTX *ctx = p->mem_ctx;
1498 union srvsvc_NetShareInfo *info = r->in.info;
1500 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1502 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1503 if (!share_name) {
1504 return WERR_NOMEM;
1507 if (r->out.parm_error) {
1508 *r->out.parm_error = 0;
1511 if ( strequal(share_name,"IPC$")
1512 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1513 || strequal(share_name,"global") )
1515 return WERR_ACCESS_DENIED;
1518 snum = find_service(share_name);
1520 /* Does this share exist ? */
1521 if (snum < 0)
1522 return WERR_NET_NAME_NOT_FOUND;
1524 /* No change to printer shares. */
1525 if (lp_print_ok(snum))
1526 return WERR_ACCESS_DENIED;
1528 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1530 /* fail out now if you are not root and not a disk op */
1532 if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1533 return WERR_ACCESS_DENIED;
1535 switch (r->in.level) {
1536 case 1:
1537 pathname = talloc_strdup(ctx, lp_pathname(snum));
1538 comment = talloc_strdup(ctx, info->info1->comment);
1539 type = info->info1->type;
1540 psd = NULL;
1541 break;
1542 case 2:
1543 comment = talloc_strdup(ctx, info->info2->comment);
1544 pathname = info->info2->path;
1545 type = info->info2->type;
1546 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1547 0 : info->info2->max_users;
1548 psd = NULL;
1549 break;
1550 #if 0
1551 /* not supported on set but here for completeness */
1552 case 501:
1553 comment = talloc_strdup(ctx, info->info501->comment);
1554 type = info->info501->type;
1555 psd = NULL;
1556 break;
1557 #endif
1558 case 502:
1559 comment = talloc_strdup(ctx, info->info502->comment);
1560 pathname = info->info502->path;
1561 type = info->info502->type;
1562 psd = info->info502->sd_buf.sd;
1563 map_generic_share_sd_bits(psd);
1564 break;
1565 case 1004:
1566 pathname = talloc_strdup(ctx, lp_pathname(snum));
1567 comment = talloc_strdup(ctx, info->info1004->comment);
1568 type = STYPE_DISKTREE;
1569 break;
1570 case 1005:
1571 /* XP re-sets the csc policy even if it wasn't changed by the
1572 user, so we must compare it to see if it's what is set in
1573 smb.conf, so that we can contine other ops like setting
1574 ACLs on a share */
1575 if (((info->info1005->dfs_flags &
1576 SHARE_1005_CSC_POLICY_MASK) >>
1577 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1578 return WERR_OK;
1579 else {
1580 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1581 return WERR_ACCESS_DENIED;
1583 case 1006:
1584 case 1007:
1585 return WERR_ACCESS_DENIED;
1586 case 1501:
1587 pathname = talloc_strdup(ctx, lp_pathname(snum));
1588 comment = talloc_strdup(ctx, lp_comment(snum));
1589 psd = info->info1501->sd;
1590 map_generic_share_sd_bits(psd);
1591 type = STYPE_DISKTREE;
1592 break;
1593 default:
1594 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1595 r->in.level));
1596 return WERR_UNKNOWN_LEVEL;
1599 /* We can only modify disk shares. */
1600 if (type != STYPE_DISKTREE)
1601 return WERR_ACCESS_DENIED;
1603 if (comment == NULL) {
1604 return WERR_NOMEM;
1607 /* Check if the pathname is valid. */
1608 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1609 return WERR_OBJECT_PATH_INVALID;
1611 /* Ensure share name, pathname and comment don't contain '"' characters. */
1612 string_replace(share_name, '"', ' ');
1613 string_replace(path, '"', ' ');
1614 string_replace(comment, '"', ' ');
1616 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1617 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1619 /* Only call modify function if something changed. */
1621 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1622 || (lp_max_connections(snum) != max_connections)) {
1623 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1624 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1625 return WERR_ACCESS_DENIED;
1628 command = talloc_asprintf(p->mem_ctx,
1629 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1630 lp_change_share_cmd(),
1631 get_dyn_CONFIGFILE(),
1632 share_name,
1633 path,
1634 comment ? comment : "",
1635 max_connections);
1636 if (!command) {
1637 return WERR_NOMEM;
1640 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1642 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1644 if (is_disk_op)
1645 become_root();
1647 if ( (ret = smbrun(command, NULL)) == 0 ) {
1648 /* Tell everyone we updated smb.conf. */
1649 message_send_all(smbd_messaging_context(),
1650 MSG_SMB_CONF_UPDATED, NULL, 0,
1651 NULL);
1654 if ( is_disk_op )
1655 unbecome_root();
1657 /********* END SeDiskOperatorPrivilege BLOCK *********/
1659 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1660 command, ret ));
1662 TALLOC_FREE(command);
1664 if ( ret != 0 )
1665 return WERR_ACCESS_DENIED;
1666 } else {
1667 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1668 share_name ));
1671 /* Replace SD if changed. */
1672 if (psd) {
1673 SEC_DESC *old_sd;
1674 size_t sd_size;
1676 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1678 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1679 if (!set_share_security(share_name, psd))
1680 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1681 share_name ));
1685 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1687 return WERR_OK;
1690 /*******************************************************************
1691 _srvsvc_NetShareAdd.
1692 Call 'add_share_command "sharename" "pathname"
1693 "comment" "max connections = "
1694 ********************************************************************/
1696 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1697 struct srvsvc_NetShareAdd *r)
1699 char *command = NULL;
1700 char *share_name = NULL;
1701 char *comment = NULL;
1702 char *pathname = NULL;
1703 int type;
1704 int snum;
1705 int ret;
1706 char *path;
1707 SEC_DESC *psd = NULL;
1708 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1709 bool is_disk_op;
1710 int max_connections = 0;
1711 TALLOC_CTX *ctx = p->mem_ctx;
1713 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1715 if (r->out.parm_error) {
1716 *r->out.parm_error = 0;
1719 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1721 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1722 return WERR_ACCESS_DENIED;
1724 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1725 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1726 return WERR_ACCESS_DENIED;
1729 switch (r->in.level) {
1730 case 0:
1731 /* No path. Not enough info in a level 0 to do anything. */
1732 return WERR_ACCESS_DENIED;
1733 case 1:
1734 /* Not enough info in a level 1 to do anything. */
1735 return WERR_ACCESS_DENIED;
1736 case 2:
1737 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1738 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1739 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1740 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1741 0 : r->in.info->info2->max_users;
1742 type = r->in.info->info2->type;
1743 break;
1744 case 501:
1745 /* No path. Not enough info in a level 501 to do anything. */
1746 return WERR_ACCESS_DENIED;
1747 case 502:
1748 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1749 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1750 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1751 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1752 0 : r->in.info->info502->max_users;
1753 type = r->in.info->info502->type;
1754 psd = r->in.info->info502->sd_buf.sd;
1755 map_generic_share_sd_bits(psd);
1756 break;
1758 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1760 case 1004:
1761 case 1005:
1762 case 1006:
1763 case 1007:
1764 return WERR_ACCESS_DENIED;
1765 case 1501:
1766 /* DFS only level. */
1767 return WERR_ACCESS_DENIED;
1768 default:
1769 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1770 r->in.level));
1771 return WERR_UNKNOWN_LEVEL;
1774 /* check for invalid share names */
1776 if (!share_name || !validate_net_name(share_name,
1777 INVALID_SHARENAME_CHARS,
1778 strlen(share_name))) {
1779 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1780 share_name ? share_name : ""));
1781 return WERR_INVALID_NAME;
1784 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1785 || (lp_enable_asu_support() &&
1786 strequal(share_name,"ADMIN$"))) {
1787 return WERR_ACCESS_DENIED;
1790 snum = find_service(share_name);
1792 /* Share already exists. */
1793 if (snum >= 0) {
1794 return WERR_FILE_EXISTS;
1797 /* We can only add disk shares. */
1798 if (type != STYPE_DISKTREE) {
1799 return WERR_ACCESS_DENIED;
1802 /* Check if the pathname is valid. */
1803 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1804 return WERR_OBJECT_PATH_INVALID;
1807 /* Ensure share name, pathname and comment don't contain '"' characters. */
1808 string_replace(share_name, '"', ' ');
1809 string_replace(path, '"', ' ');
1810 if (comment) {
1811 string_replace(comment, '"', ' ');
1814 command = talloc_asprintf(ctx,
1815 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1816 lp_add_share_cmd(),
1817 get_dyn_CONFIGFILE(),
1818 share_name,
1819 path,
1820 comment ? comment : "",
1821 max_connections);
1822 if (!command) {
1823 return WERR_NOMEM;
1826 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1828 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1830 if ( is_disk_op )
1831 become_root();
1833 /* FIXME: use libnetconf here - gd */
1835 if ( (ret = smbrun(command, NULL)) == 0 ) {
1836 /* Tell everyone we updated smb.conf. */
1837 message_send_all(smbd_messaging_context(),
1838 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1841 if ( is_disk_op )
1842 unbecome_root();
1844 /********* END SeDiskOperatorPrivilege BLOCK *********/
1846 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1847 command, ret ));
1849 TALLOC_FREE(command);
1851 if ( ret != 0 )
1852 return WERR_ACCESS_DENIED;
1854 if (psd) {
1855 if (!set_share_security(share_name, psd)) {
1856 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1857 share_name ));
1862 * We don't call reload_services() here, the message will
1863 * cause this to be done before the next packet is read
1864 * from the client. JRA.
1867 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1869 return WERR_OK;
1872 /*******************************************************************
1873 _srvsvc_NetShareDel
1874 Call "delete share command" with the share name as
1875 a parameter.
1876 ********************************************************************/
1878 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1879 struct srvsvc_NetShareDel *r)
1881 char *command = NULL;
1882 char *share_name = NULL;
1883 int ret;
1884 int snum;
1885 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1886 bool is_disk_op;
1887 struct share_params *params;
1888 TALLOC_CTX *ctx = p->mem_ctx;
1890 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1892 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1893 if (!share_name) {
1894 return WERR_NET_NAME_NOT_FOUND;
1896 if ( strequal(share_name,"IPC$")
1897 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1898 || strequal(share_name,"global") )
1900 return WERR_ACCESS_DENIED;
1903 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1904 return WERR_NO_SUCH_SHARE;
1907 snum = find_service(share_name);
1909 /* No change to printer shares. */
1910 if (lp_print_ok(snum))
1911 return WERR_ACCESS_DENIED;
1913 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1915 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1916 return WERR_ACCESS_DENIED;
1918 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1919 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1920 return WERR_ACCESS_DENIED;
1923 command = talloc_asprintf(ctx,
1924 "%s \"%s\" \"%s\"",
1925 lp_delete_share_cmd(),
1926 get_dyn_CONFIGFILE(),
1927 lp_servicename(snum));
1928 if (!command) {
1929 return WERR_NOMEM;
1932 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1934 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1936 if ( is_disk_op )
1937 become_root();
1939 if ( (ret = smbrun(command, NULL)) == 0 ) {
1940 /* Tell everyone we updated smb.conf. */
1941 message_send_all(smbd_messaging_context(),
1942 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1945 if ( is_disk_op )
1946 unbecome_root();
1948 /********* END SeDiskOperatorPrivilege BLOCK *********/
1950 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1952 if ( ret != 0 )
1953 return WERR_ACCESS_DENIED;
1955 /* Delete the SD in the database. */
1956 delete_share_security(lp_servicename(params->service));
1958 lp_killservice(params->service);
1960 return WERR_OK;
1963 /*******************************************************************
1964 _srvsvc_NetShareDelSticky
1965 ********************************************************************/
1967 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1968 struct srvsvc_NetShareDelSticky *r)
1970 struct srvsvc_NetShareDel q;
1972 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1974 q.in.server_unc = r->in.server_unc;
1975 q.in.share_name = r->in.share_name;
1976 q.in.reserved = r->in.reserved;
1978 return _srvsvc_NetShareDel(p, &q);
1981 /*******************************************************************
1982 _srvsvc_NetRemoteTOD
1983 ********************************************************************/
1985 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1986 struct srvsvc_NetRemoteTOD *r)
1988 struct srvsvc_NetRemoteTODInfo *tod;
1989 struct tm *t;
1990 time_t unixdate = time(NULL);
1992 /* We do this call first as if we do it *after* the gmtime call
1993 it overwrites the pointed-to values. JRA */
1995 uint32 zone = get_time_zone(unixdate)/60;
1997 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1999 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2000 return WERR_NOMEM;
2002 *r->out.info = tod;
2004 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2006 t = gmtime(&unixdate);
2008 /* set up the */
2009 tod->elapsed = unixdate;
2010 tod->msecs = 0;
2011 tod->hours = t->tm_hour;
2012 tod->mins = t->tm_min;
2013 tod->secs = t->tm_sec;
2014 tod->hunds = 0;
2015 tod->timezone = zone;
2016 tod->tinterval = 10000;
2017 tod->day = t->tm_mday;
2018 tod->month = t->tm_mon + 1;
2019 tod->year = 1900+t->tm_year;
2020 tod->weekday = t->tm_wday;
2022 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2024 return WERR_OK;
2027 /***********************************************************************************
2028 _srvsvc_NetGetFileSecurity
2029 Win9x NT tools get security descriptor.
2030 ***********************************************************************************/
2032 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2033 struct srvsvc_NetGetFileSecurity *r)
2035 SEC_DESC *psd = NULL;
2036 size_t sd_size;
2037 fstring servicename;
2038 SMB_STRUCT_STAT st;
2039 NTSTATUS nt_status;
2040 WERROR werr;
2041 connection_struct *conn = NULL;
2042 struct sec_desc_buf *sd_buf = NULL;
2043 files_struct *fsp = NULL;
2044 int snum;
2045 char *oldcwd = NULL;
2047 ZERO_STRUCT(st);
2049 fstrcpy(servicename, r->in.share);
2051 snum = find_service(servicename);
2052 if (snum == -1) {
2053 DEBUG(10, ("Could not find service %s\n", servicename));
2054 werr = WERR_NET_NAME_NOT_FOUND;
2055 goto error_exit;
2058 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2059 lp_pathname(snum), p->server_info,
2060 &oldcwd);
2061 if (!NT_STATUS_IS_OK(nt_status)) {
2062 DEBUG(10, ("create_conn_struct failed: %s\n",
2063 nt_errstr(nt_status)));
2064 werr = ntstatus_to_werror(nt_status);
2065 goto error_exit;
2068 nt_status = SMB_VFS_CREATE_FILE(
2069 conn, /* conn */
2070 NULL, /* req */
2071 0, /* root_dir_fid */
2072 r->in.file, /* fname */
2073 CFF_DOS_PATH, /* create_file_flags */
2074 FILE_READ_ATTRIBUTES, /* access_mask */
2075 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2076 FILE_OPEN, /* create_disposition*/
2077 0, /* create_options */
2078 0, /* file_attributes */
2079 INTERNAL_OPEN_ONLY, /* oplock_request */
2080 0, /* allocation_size */
2081 NULL, /* sd */
2082 NULL, /* ea_list */
2083 &fsp, /* result */
2084 NULL, /* pinfo */
2085 NULL); /* psbuf */
2087 if (!NT_STATUS_IS_OK(nt_status)) {
2088 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2089 r->in.file));
2090 werr = ntstatus_to_werror(nt_status);
2091 goto error_exit;
2094 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2095 (OWNER_SECURITY_INFORMATION
2096 |GROUP_SECURITY_INFORMATION
2097 |DACL_SECURITY_INFORMATION), &psd);
2099 if (!NT_STATUS_IS_OK(nt_status)) {
2100 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2101 "for file %s\n", r->in.file));
2102 werr = ntstatus_to_werror(nt_status);
2103 goto error_exit;
2106 sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2108 sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2109 if (!sd_buf) {
2110 werr = WERR_NOMEM;
2111 goto error_exit;
2114 sd_buf->sd_size = sd_size;
2115 sd_buf->sd = psd;
2117 *r->out.sd_buf = sd_buf;
2119 psd->dacl->revision = NT4_ACL_REVISION;
2121 close_file(NULL, fsp, NORMAL_CLOSE);
2122 vfs_ChDir(conn, oldcwd);
2123 conn_free_internal(conn);
2124 return WERR_OK;
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 conn_free_internal(conn);
2140 return werr;
2143 /***********************************************************************************
2144 _srvsvc_NetSetFileSecurity
2145 Win9x NT tools set security descriptor.
2146 ***********************************************************************************/
2148 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2149 struct srvsvc_NetSetFileSecurity *r)
2151 fstring servicename;
2152 files_struct *fsp = NULL;
2153 SMB_STRUCT_STAT st;
2154 NTSTATUS nt_status;
2155 WERROR werr;
2156 connection_struct *conn = NULL;
2157 int snum;
2158 char *oldcwd = NULL;
2159 struct security_descriptor *psd = NULL;
2160 uint32_t security_info_sent = 0;
2162 ZERO_STRUCT(st);
2164 fstrcpy(servicename, r->in.share);
2166 snum = find_service(servicename);
2167 if (snum == -1) {
2168 DEBUG(10, ("Could not find service %s\n", servicename));
2169 werr = WERR_NET_NAME_NOT_FOUND;
2170 goto error_exit;
2173 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2174 lp_pathname(snum), p->server_info,
2175 &oldcwd);
2176 if (!NT_STATUS_IS_OK(nt_status)) {
2177 DEBUG(10, ("create_conn_struct failed: %s\n",
2178 nt_errstr(nt_status)));
2179 werr = ntstatus_to_werror(nt_status);
2180 goto error_exit;
2183 nt_status = SMB_VFS_CREATE_FILE(
2184 conn, /* conn */
2185 NULL, /* req */
2186 0, /* root_dir_fid */
2187 r->in.file, /* fname */
2188 CFF_DOS_PATH, /* create_file_flags */
2189 FILE_WRITE_ATTRIBUTES, /* access_mask */
2190 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2191 FILE_OPEN, /* create_disposition*/
2192 0, /* create_options */
2193 0, /* file_attributes */
2194 INTERNAL_OPEN_ONLY, /* oplock_request */
2195 0, /* allocation_size */
2196 NULL, /* sd */
2197 NULL, /* ea_list */
2198 &fsp, /* result */
2199 NULL, /* pinfo */
2200 NULL); /* psbuf */
2202 if (!NT_STATUS_IS_OK(nt_status)) {
2203 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2204 r->in.file));
2205 werr = ntstatus_to_werror(nt_status);
2206 goto error_exit;
2209 psd = r->in.sd_buf->sd;
2210 security_info_sent = r->in.securityinformation;
2212 if (psd->owner_sid==0) {
2213 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2215 if (psd->group_sid==0) {
2216 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2218 if (psd->sacl==0) {
2219 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2221 if (psd->dacl==0) {
2222 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2225 /* Convert all the generic bits. */
2226 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2227 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2229 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2230 security_info_sent,
2231 psd);
2233 if (!NT_STATUS_IS_OK(nt_status) ) {
2234 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2235 "on file %s\n", r->in.share));
2236 werr = WERR_ACCESS_DENIED;
2237 goto error_exit;
2240 close_file(NULL, fsp, NORMAL_CLOSE);
2241 vfs_ChDir(conn, oldcwd);
2242 conn_free_internal(conn);
2243 return WERR_OK;
2245 error_exit:
2247 if (fsp) {
2248 close_file(NULL, fsp, NORMAL_CLOSE);
2251 if (oldcwd) {
2252 vfs_ChDir(conn, oldcwd);
2255 if (conn) {
2256 conn_free_internal(conn);
2259 return werr;
2262 /***********************************************************************************
2263 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2264 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2265 These disks would the disks listed by this function.
2266 Users could then create shares relative to these disks. Watch out for moving these disks around.
2267 "Nigel Williams" <nigel@veritas.com>.
2268 ***********************************************************************************/
2270 static const char *server_disks[] = {"C:"};
2272 static uint32 get_server_disk_count(void)
2274 return sizeof(server_disks)/sizeof(server_disks[0]);
2277 static uint32 init_server_disk_enum(uint32 *resume)
2279 uint32 server_disk_count = get_server_disk_count();
2281 /*resume can be an offset into the list for now*/
2283 if(*resume & 0x80000000)
2284 *resume = 0;
2286 if(*resume > server_disk_count)
2287 *resume = server_disk_count;
2289 return server_disk_count - *resume;
2292 static const char *next_server_disk_enum(uint32 *resume)
2294 const char *disk;
2296 if(init_server_disk_enum(resume) == 0)
2297 return NULL;
2299 disk = server_disks[*resume];
2301 (*resume)++;
2303 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2305 return disk;
2308 /********************************************************************
2309 _srvsvc_NetDiskEnum
2310 ********************************************************************/
2312 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2313 struct srvsvc_NetDiskEnum *r)
2315 uint32 i;
2316 const char *disk_name;
2317 TALLOC_CTX *ctx = p->mem_ctx;
2318 WERROR werr;
2319 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2321 werr = WERR_OK;
2323 *r->out.totalentries = init_server_disk_enum(&resume);
2325 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2326 MAX_SERVER_DISK_ENTRIES);
2327 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2329 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2331 r->out.info->count = 0;
2333 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2335 r->out.info->count++;
2337 /*copy disk name into a unicode string*/
2339 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2340 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2343 /* add a terminating null string. Is this there if there is more data to come? */
2345 r->out.info->count++;
2347 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2348 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2350 if (r->out.resume_handle) {
2351 *r->out.resume_handle = resume;
2354 return werr;
2357 /********************************************************************
2358 _srvsvc_NetNameValidate
2359 ********************************************************************/
2361 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2362 struct srvsvc_NetNameValidate *r)
2364 switch (r->in.name_type) {
2365 case 0x9:
2366 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2367 strlen_m(r->in.name)))
2369 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2370 r->in.name));
2371 return WERR_INVALID_NAME;
2373 break;
2375 default:
2376 return WERR_UNKNOWN_LEVEL;
2379 return WERR_OK;
2382 /*******************************************************************
2383 ********************************************************************/
2385 static void enum_file_close_fn( const struct share_mode_entry *e,
2386 const char *sharepath, const char *fname,
2387 void *private_data )
2389 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2390 struct srvsvc_NetFileClose *r =
2391 (struct srvsvc_NetFileClose *)private_data;
2392 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2394 if (fid != r->in.fid) {
2395 return; /* Not this file. */
2398 if (!process_exists(e->pid) ) {
2399 return;
2402 /* Ok - send the close message. */
2403 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2404 sharepath,
2405 share_mode_str(talloc_tos(), 0, e) ));
2407 share_mode_entry_to_message(msg, e);
2409 r->out.result = ntstatus_to_werror(
2410 messaging_send_buf(smbd_messaging_context(),
2411 e->pid, MSG_SMB_CLOSE_FILE,
2412 (uint8 *)msg,
2413 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2416 /********************************************************************
2417 Close a file given a 32-bit file id.
2418 ********************************************************************/
2420 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2422 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2423 bool is_disk_op;
2425 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2427 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2429 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2430 return WERR_ACCESS_DENIED;
2433 /* enum_file_close_fn sends the close message to
2434 * the relevent smbd process. */
2436 r->out.result = WERR_BADFILE;
2437 share_mode_forall( enum_file_close_fn, (void *)r);
2438 return r->out.result;
2441 /********************************************************************
2442 ********************************************************************/
2444 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2446 p->rng_fault_state = True;
2447 return WERR_NOT_SUPPORTED;
2450 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2452 p->rng_fault_state = True;
2453 return WERR_NOT_SUPPORTED;
2456 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2458 p->rng_fault_state = True;
2459 return WERR_NOT_SUPPORTED;
2462 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2464 p->rng_fault_state = True;
2465 return WERR_NOT_SUPPORTED;
2468 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2470 p->rng_fault_state = True;
2471 return WERR_NOT_SUPPORTED;
2474 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2476 p->rng_fault_state = True;
2477 return WERR_NOT_SUPPORTED;
2480 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2482 p->rng_fault_state = True;
2483 return WERR_NOT_SUPPORTED;
2486 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2488 p->rng_fault_state = True;
2489 return WERR_NOT_SUPPORTED;
2492 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2494 p->rng_fault_state = True;
2495 return WERR_NOT_SUPPORTED;
2498 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2500 p->rng_fault_state = True;
2501 return WERR_NOT_SUPPORTED;
2504 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2506 p->rng_fault_state = True;
2507 return WERR_NOT_SUPPORTED;
2510 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2512 p->rng_fault_state = True;
2513 return WERR_NOT_SUPPORTED;
2516 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2518 p->rng_fault_state = True;
2519 return WERR_NOT_SUPPORTED;
2522 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2524 p->rng_fault_state = True;
2525 return WERR_NOT_SUPPORTED;
2528 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2530 p->rng_fault_state = True;
2531 return WERR_NOT_SUPPORTED;
2534 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2536 p->rng_fault_state = True;
2537 return WERR_NOT_SUPPORTED;
2540 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2542 p->rng_fault_state = True;
2543 return WERR_NOT_SUPPORTED;
2546 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2548 p->rng_fault_state = True;
2549 return WERR_NOT_SUPPORTED;
2552 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2554 p->rng_fault_state = True;
2555 return WERR_NOT_SUPPORTED;
2558 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2560 p->rng_fault_state = True;
2561 return WERR_NOT_SUPPORTED;
2564 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2566 p->rng_fault_state = True;
2567 return WERR_NOT_SUPPORTED;
2570 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2572 p->rng_fault_state = True;
2573 return WERR_NOT_SUPPORTED;
2576 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2578 p->rng_fault_state = True;
2579 return WERR_NOT_SUPPORTED;
2582 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2584 p->rng_fault_state = True;
2585 return WERR_NOT_SUPPORTED;
2588 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2590 p->rng_fault_state = True;
2591 return WERR_NOT_SUPPORTED;
2594 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2596 p->rng_fault_state = True;
2597 return WERR_NOT_SUPPORTED;
2600 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2602 p->rng_fault_state = True;
2603 return WERR_NOT_SUPPORTED;
2606 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2608 p->rng_fault_state = True;
2609 return WERR_NOT_SUPPORTED;
2612 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2614 p->rng_fault_state = True;
2615 return WERR_NOT_SUPPORTED;
2618 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2620 p->rng_fault_state = True;
2621 return WERR_NOT_SUPPORTED;
2624 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2626 p->rng_fault_state = True;
2627 return WERR_NOT_SUPPORTED;
2630 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2632 p->rng_fault_state = True;
2633 return WERR_NOT_SUPPORTED;
2636 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2638 p->rng_fault_state = True;
2639 return WERR_NOT_SUPPORTED;
2642 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2644 p->rng_fault_state = True;
2645 return WERR_NOT_SUPPORTED;
2648 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2650 p->rng_fault_state = True;
2651 return WERR_NOT_SUPPORTED;