Fix bug #7781 (Samba transforms "ShareName" to lowercase when adding new share via...
[Samba.git] / source3 / rpc_server / srv_srvsvc_nt.c
blobb51c7e2f2f9be771ba11448195c21760f065213e
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 "../librpc/gen_ndr/srv_srvsvc.h"
29 extern const struct generic_mapping file_generic_mapping;
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_SRV
34 #define MAX_SERVER_DISK_ENTRIES 15
36 /* Use for enumerating connections, pipes, & files */
38 struct file_enum_count {
39 TALLOC_CTX *ctx;
40 const char *username;
41 struct srvsvc_NetFileCtr3 *ctr3;
44 struct sess_file_count {
45 struct server_id pid;
46 uid_t uid;
47 int count;
50 /****************************************************************************
51 Count the entries belonging to a service in the connection db.
52 ****************************************************************************/
54 static int pipe_enum_fn( struct db_record *rec, void *p)
56 struct pipe_open_rec prec;
57 struct file_enum_count *fenum = (struct file_enum_count *)p;
58 struct srvsvc_NetFileInfo3 *f;
59 int i = fenum->ctr3->count;
60 char *fullpath = NULL;
61 const char *username;
63 if (rec->value.dsize != sizeof(struct pipe_open_rec))
64 return 0;
66 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
68 if ( !process_exists(prec.pid) ) {
69 return 0;
72 username = uidtoname(prec.uid);
74 if ((fenum->username != NULL)
75 && !strequal(username, fenum->username)) {
76 return 0;
79 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
80 if (!fullpath) {
81 return 1;
84 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
85 struct srvsvc_NetFileInfo3, i+1);
86 if ( !f ) {
87 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
88 return 1;
90 fenum->ctr3->array = f;
92 fenum->ctr3->array[i].fid =
93 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
94 fenum->ctr3->array[i].permissions =
95 (FILE_READ_DATA|FILE_WRITE_DATA);
96 fenum->ctr3->array[i].num_locks = 0;
97 fenum->ctr3->array[i].path = fullpath;
98 fenum->ctr3->array[i].user = username;
100 fenum->ctr3->count++;
102 return 0;
105 /*******************************************************************
106 ********************************************************************/
108 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
109 const char *username,
110 struct srvsvc_NetFileCtr3 **ctr3,
111 uint32_t resume )
113 struct file_enum_count fenum;
115 fenum.ctx = ctx;
116 fenum.username = username;
117 fenum.ctr3 = *ctr3;
119 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
120 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
121 "failed\n"));
122 return WERR_NOMEM;
125 *ctr3 = fenum.ctr3;
127 return WERR_OK;
130 /*******************************************************************
131 ********************************************************************/
133 static void enum_file_fn( const struct share_mode_entry *e,
134 const char *sharepath, const char *fname,
135 void *private_data )
137 struct file_enum_count *fenum =
138 (struct file_enum_count *)private_data;
140 struct srvsvc_NetFileInfo3 *f;
141 int i = fenum->ctr3->count;
142 files_struct fsp;
143 struct byte_range_lock *brl;
144 int num_locks = 0;
145 char *fullpath = NULL;
146 uint32 permissions;
147 const char *username;
149 /* If the pid was not found delete the entry from connections.tdb */
151 if ( !process_exists(e->pid) ) {
152 return;
155 username = uidtoname(e->uid);
157 if ((fenum->username != NULL)
158 && !strequal(username, fenum->username)) {
159 return;
162 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
163 struct srvsvc_NetFileInfo3, i+1);
164 if ( !f ) {
165 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
166 return;
168 fenum->ctr3->array = f;
170 /* need to count the number of locks on a file */
172 ZERO_STRUCT( fsp );
173 fsp.file_id = e->id;
175 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
176 num_locks = brl->num_locks;
177 TALLOC_FREE(brl);
180 if ( strcmp( fname, "." ) == 0 ) {
181 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
182 } else {
183 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
184 sharepath, fname );
186 if (!fullpath) {
187 return;
189 string_replace( fullpath, '/', '\\' );
191 /* mask out create (what ever that is) */
192 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
194 /* now fill in the srvsvc_NetFileInfo3 struct */
196 fenum->ctr3->array[i].fid =
197 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
198 fenum->ctr3->array[i].permissions = permissions;
199 fenum->ctr3->array[i].num_locks = num_locks;
200 fenum->ctr3->array[i].path = fullpath;
201 fenum->ctr3->array[i].user = username;
203 fenum->ctr3->count++;
206 /*******************************************************************
207 ********************************************************************/
209 static WERROR net_enum_files(TALLOC_CTX *ctx,
210 const char *username,
211 struct srvsvc_NetFileCtr3 **ctr3,
212 uint32_t resume)
214 struct file_enum_count f_enum_cnt;
216 f_enum_cnt.ctx = ctx;
217 f_enum_cnt.username = username;
218 f_enum_cnt.ctr3 = *ctr3;
220 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
222 *ctr3 = f_enum_cnt.ctr3;
224 return WERR_OK;
227 /*******************************************************************
228 Utility function to get the 'type' of a share from an snum.
229 ********************************************************************/
230 static uint32 get_share_type(int snum)
232 /* work out the share type */
233 uint32 type = STYPE_DISKTREE;
235 if (lp_print_ok(snum))
236 type = STYPE_PRINTQ;
237 if (strequal(lp_fstype(snum), "IPC"))
238 type = STYPE_IPC;
239 if (lp_administrative_share(snum))
240 type |= STYPE_HIDDEN;
242 return type;
245 /*******************************************************************
246 Fill in a share info level 0 structure.
247 ********************************************************************/
249 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
251 r->name = lp_servicename(snum);
254 /*******************************************************************
255 Fill in a share info level 1 structure.
256 ********************************************************************/
258 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
260 char *net_name = lp_servicename(snum);
261 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
263 if (remark) {
264 remark = talloc_sub_advanced(
265 p->mem_ctx, lp_servicename(snum),
266 get_current_username(), lp_pathname(snum),
267 p->server_info->utok.uid, get_current_username(),
268 "", remark);
271 r->name = net_name;
272 r->type = get_share_type(snum);
273 r->comment = remark ? remark : "";
276 /*******************************************************************
277 Fill in a share info level 2 structure.
278 ********************************************************************/
280 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
282 char *remark = NULL;
283 char *path = NULL;
284 int max_connections = lp_max_connections(snum);
285 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
286 char *net_name = lp_servicename(snum);
288 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
289 if (remark) {
290 remark = talloc_sub_advanced(
291 p->mem_ctx, lp_servicename(snum),
292 get_current_username(), lp_pathname(snum),
293 p->server_info->utok.uid, get_current_username(),
294 "", remark);
296 path = talloc_asprintf(p->mem_ctx,
297 "C:%s", lp_pathname(snum));
299 if (path) {
301 * Change / to \\ so that win2k will see it as a valid path.
302 * This was added to enable use of browsing in win2k add
303 * share dialog.
306 string_replace(path, '/', '\\');
309 r->name = net_name;
310 r->type = get_share_type(snum);
311 r->comment = remark ? remark : "";
312 r->permissions = 0;
313 r->max_users = max_uses;
314 r->current_users = count_current_connections(net_name, false);
315 r->path = path ? path : "";
316 r->password = "";
319 /*******************************************************************
320 Map any generic bits to file specific bits.
321 ********************************************************************/
323 static void map_generic_share_sd_bits(SEC_DESC *psd)
325 int i;
326 SEC_ACL *ps_dacl = NULL;
328 if (!psd)
329 return;
331 ps_dacl = psd->dacl;
332 if (!ps_dacl)
333 return;
335 for (i = 0; i < ps_dacl->num_aces; i++) {
336 SEC_ACE *psa = &ps_dacl->aces[i];
337 uint32 orig_mask = psa->access_mask;
339 se_map_generic(&psa->access_mask, &file_generic_mapping);
340 psa->access_mask |= orig_mask;
344 /*******************************************************************
345 Fill in a share info level 501 structure.
346 ********************************************************************/
348 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
350 const char *net_name = lp_servicename(snum);
351 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
353 if (remark) {
354 remark = talloc_sub_advanced(
355 p->mem_ctx, lp_servicename(snum),
356 get_current_username(), lp_pathname(snum),
357 p->server_info->utok.uid, get_current_username(),
358 "", remark);
361 r->name = net_name;
362 r->type = get_share_type(snum);
363 r->comment = remark ? remark : "";
364 r->csc_policy = (lp_csc_policy(snum) << 4);
367 /*******************************************************************
368 Fill in a share info level 502 structure.
369 ********************************************************************/
371 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
373 const char *net_name = lp_servicename(snum);
374 char *path = NULL;
375 SEC_DESC *sd = NULL;
376 struct sec_desc_buf *sd_buf = NULL;
377 size_t sd_size = 0;
378 TALLOC_CTX *ctx = p->mem_ctx;
379 char *remark = talloc_strdup(ctx, lp_comment(snum));;
381 if (remark) {
382 remark = talloc_sub_advanced(
383 p->mem_ctx, lp_servicename(snum),
384 get_current_username(), lp_pathname(snum),
385 p->server_info->utok.uid, get_current_username(),
386 "", remark);
388 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
389 if (path) {
391 * Change / to \\ so that win2k will see it as a valid path. This was added to
392 * enable use of browsing in win2k add share dialog.
394 string_replace(path, '/', '\\');
397 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
399 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
401 r->name = net_name;
402 r->type = get_share_type(snum);
403 r->comment = remark ? remark : "";
404 r->permissions = 0;
405 r->max_users = (uint32_t)-1;
406 r->current_users = 1; /* ??? */
407 r->path = path ? path : "";
408 r->password = "";
409 r->sd_buf = *sd_buf;
412 /***************************************************************************
413 Fill in a share info level 1004 structure.
414 ***************************************************************************/
416 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
418 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
420 if (remark) {
421 remark = talloc_sub_advanced(
422 p->mem_ctx, lp_servicename(snum),
423 get_current_username(), lp_pathname(snum),
424 p->server_info->utok.uid, get_current_username(),
425 "", remark);
428 r->comment = remark ? remark : "";
431 /***************************************************************************
432 Fill in a share info level 1005 structure.
433 ***************************************************************************/
435 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
437 uint32_t dfs_flags = 0;
439 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
440 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
443 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
445 r->dfs_flags = dfs_flags;
448 /***************************************************************************
449 Fill in a share info level 1006 structure.
450 ***************************************************************************/
452 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
454 r->max_users = (uint32_t)-1;
457 /***************************************************************************
458 Fill in a share info level 1007 structure.
459 ***************************************************************************/
461 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
463 r->flags = 0;
464 r->alternate_directory_name = "";
467 /*******************************************************************
468 Fill in a share info level 1501 structure.
469 ********************************************************************/
471 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
473 SEC_DESC *sd;
474 size_t sd_size;
475 TALLOC_CTX *ctx = p->mem_ctx;
477 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
479 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
482 /*******************************************************************
483 True if it ends in '$'.
484 ********************************************************************/
486 static bool is_hidden_share(int snum)
488 const char *net_name = lp_servicename(snum);
490 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
493 /*******************************************************************
494 Verify user is allowed to view share, access based enumeration
495 ********************************************************************/
496 static bool is_enumeration_allowed(pipes_struct *p,
497 int snum)
499 if (!lp_access_based_share_enum(snum))
500 return true;
502 return share_access_check(p->server_info->ptok, lp_servicename(snum),
503 FILE_READ_DATA);
506 /*******************************************************************
507 Fill in a share info structure.
508 ********************************************************************/
510 static WERROR init_srv_share_info_ctr(pipes_struct *p,
511 struct srvsvc_NetShareInfoCtr *info_ctr,
512 uint32_t *resume_handle_p,
513 uint32_t *total_entries,
514 bool all_shares)
516 int num_entries = 0;
517 int alloc_entries = 0;
518 int num_services = 0;
519 int snum;
520 TALLOC_CTX *ctx = p->mem_ctx;
521 int i = 0;
522 int valid_share_count = 0;
523 bool *allowed = 0;
524 union srvsvc_NetShareCtr ctr;
525 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
527 DEBUG(5,("init_srv_share_info_ctr\n"));
529 /* Ensure all the usershares are loaded. */
530 become_root();
531 load_usershare_shares();
532 load_registry_shares();
533 num_services = lp_numservices();
534 unbecome_root();
536 allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
537 W_ERROR_HAVE_NO_MEMORY(allowed);
539 /* Count the number of entries. */
540 for (snum = 0; snum < num_services; snum++) {
541 if (lp_browseable(snum) && lp_snum_ok(snum) &&
542 is_enumeration_allowed(p, snum) &&
543 (all_shares || !is_hidden_share(snum)) ) {
544 DEBUG(10, ("counting service %s\n",
545 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
546 allowed[snum] = true;
547 num_entries++;
548 } else {
549 DEBUG(10, ("NOT counting service %s\n",
550 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
554 if (!num_entries || (resume_handle >= num_entries)) {
555 return WERR_OK;
558 /* Calculate alloc entries. */
559 alloc_entries = num_entries - resume_handle;
560 switch (info_ctr->level) {
561 case 0:
562 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
563 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
565 ctr.ctr0->count = alloc_entries;
566 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
567 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
569 for (snum = 0; snum < num_services; snum++) {
570 if (allowed[snum] &&
571 (resume_handle <= (i + valid_share_count++)) ) {
572 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
576 break;
578 case 1:
579 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
580 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
582 ctr.ctr1->count = alloc_entries;
583 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
584 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
586 for (snum = 0; snum < num_services; snum++) {
587 if (allowed[snum] &&
588 (resume_handle <= (i + valid_share_count++)) ) {
589 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
593 break;
595 case 2:
596 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
597 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
599 ctr.ctr2->count = alloc_entries;
600 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
601 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
603 for (snum = 0; snum < num_services; snum++) {
604 if (allowed[snum] &&
605 (resume_handle <= (i + valid_share_count++)) ) {
606 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
610 break;
612 case 501:
613 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
614 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
616 ctr.ctr501->count = alloc_entries;
617 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
618 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
620 for (snum = 0; snum < num_services; snum++) {
621 if (allowed[snum] &&
622 (resume_handle <= (i + valid_share_count++)) ) {
623 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
627 break;
629 case 502:
630 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
631 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
633 ctr.ctr502->count = alloc_entries;
634 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
635 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
637 for (snum = 0; snum < num_services; snum++) {
638 if (allowed[snum] &&
639 (resume_handle <= (i + valid_share_count++)) ) {
640 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
644 break;
646 case 1004:
647 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
648 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
650 ctr.ctr1004->count = alloc_entries;
651 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
652 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
654 for (snum = 0; snum < num_services; snum++) {
655 if (allowed[snum] &&
656 (resume_handle <= (i + valid_share_count++)) ) {
657 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
661 break;
663 case 1005:
664 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
665 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
667 ctr.ctr1005->count = alloc_entries;
668 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
669 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
671 for (snum = 0; snum < num_services; snum++) {
672 if (allowed[snum] &&
673 (resume_handle <= (i + valid_share_count++)) ) {
674 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
678 break;
680 case 1006:
681 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
682 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
684 ctr.ctr1006->count = alloc_entries;
685 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
686 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
688 for (snum = 0; snum < num_services; snum++) {
689 if (allowed[snum] &&
690 (resume_handle <= (i + valid_share_count++)) ) {
691 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
695 break;
697 case 1007:
698 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
699 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
701 ctr.ctr1007->count = alloc_entries;
702 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
703 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
705 for (snum = 0; snum < num_services; snum++) {
706 if (allowed[snum] &&
707 (resume_handle <= (i + valid_share_count++)) ) {
708 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
712 break;
714 case 1501:
715 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
716 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
718 ctr.ctr1501->count = alloc_entries;
719 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
720 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
722 for (snum = 0; snum < num_services; snum++) {
723 if (allowed[snum] &&
724 (resume_handle <= (i + valid_share_count++)) ) {
725 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
729 break;
731 default:
732 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
733 info_ctr->level));
734 return WERR_UNKNOWN_LEVEL;
737 *total_entries = alloc_entries;
738 if (resume_handle_p) {
739 if (all_shares) {
740 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
741 } else {
742 *resume_handle_p = num_entries;
746 info_ctr->ctr = ctr;
748 return WERR_OK;
751 /*******************************************************************
752 fill in a sess info level 0 structure.
753 ********************************************************************/
755 static WERROR init_srv_sess_info_0(pipes_struct *p,
756 struct srvsvc_NetSessCtr0 *ctr0,
757 uint32_t *resume_handle_p,
758 uint32_t *total_entries)
760 struct sessionid *session_list;
761 uint32_t num_entries = 0;
762 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
763 *total_entries = list_sessions(p->mem_ctx, &session_list);
765 DEBUG(5,("init_srv_sess_info_0\n"));
767 if (ctr0 == NULL) {
768 if (resume_handle_p) {
769 *resume_handle_p = 0;
771 return WERR_OK;
774 for (; resume_handle < *total_entries; resume_handle++) {
776 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
777 ctr0->array,
778 struct srvsvc_NetSessInfo0,
779 num_entries+1);
780 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
782 ctr0->array[num_entries].client =
783 session_list[resume_handle].remote_machine;
785 num_entries++;
788 ctr0->count = num_entries;
790 if (resume_handle_p) {
791 if (*resume_handle_p >= *total_entries) {
792 *resume_handle_p = 0;
793 } else {
794 *resume_handle_p = resume_handle;
798 return WERR_OK;
801 /*******************************************************************
802 ********************************************************************/
804 static void sess_file_fn( const struct share_mode_entry *e,
805 const char *sharepath, const char *fname,
806 void *data )
808 struct sess_file_count *sess = (struct sess_file_count *)data;
810 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
811 sess->count++;
814 return;
817 /*******************************************************************
818 ********************************************************************/
820 static int net_count_files( uid_t uid, struct server_id pid )
822 struct sess_file_count s_file_cnt;
824 s_file_cnt.count = 0;
825 s_file_cnt.uid = uid;
826 s_file_cnt.pid = pid;
828 share_mode_forall( sess_file_fn, &s_file_cnt );
830 return s_file_cnt.count;
833 /*******************************************************************
834 fill in a sess info level 1 structure.
835 ********************************************************************/
837 static WERROR init_srv_sess_info_1(pipes_struct *p,
838 struct srvsvc_NetSessCtr1 *ctr1,
839 uint32_t *resume_handle_p,
840 uint32_t *total_entries)
842 struct sessionid *session_list;
843 uint32_t num_entries = 0;
844 time_t now = time(NULL);
845 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
847 ZERO_STRUCTP(ctr1);
849 if (ctr1 == NULL) {
850 if (resume_handle_p) {
851 *resume_handle_p = 0;
853 return WERR_OK;
856 *total_entries = list_sessions(p->mem_ctx, &session_list);
858 for (; resume_handle < *total_entries; resume_handle++) {
859 uint32 num_files;
860 uint32 connect_time;
861 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
862 bool guest;
864 if ( !pw ) {
865 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
866 session_list[resume_handle].username));
867 continue;
870 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
871 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
872 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
874 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
875 ctr1->array,
876 struct srvsvc_NetSessInfo1,
877 num_entries+1);
878 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
880 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
881 ctr1->array[num_entries].user = session_list[resume_handle].username;
882 ctr1->array[num_entries].num_open = num_files;
883 ctr1->array[num_entries].time = connect_time;
884 ctr1->array[num_entries].idle_time = 0;
885 ctr1->array[num_entries].user_flags = guest;
887 num_entries++;
890 ctr1->count = num_entries;
892 if (resume_handle_p) {
893 if (*resume_handle_p >= *total_entries) {
894 *resume_handle_p = 0;
895 } else {
896 *resume_handle_p = resume_handle;
900 return WERR_OK;
903 /*******************************************************************
904 fill in a conn info level 0 structure.
905 ********************************************************************/
907 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
908 uint32_t *resume_handle_p,
909 uint32_t *total_entries)
911 uint32_t num_entries = 0;
912 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
914 DEBUG(5,("init_srv_conn_info_0\n"));
916 if (ctr0 == NULL) {
917 if (resume_handle_p) {
918 *resume_handle_p = 0;
920 return WERR_OK;
923 *total_entries = 1;
925 ZERO_STRUCTP(ctr0);
927 for (; resume_handle < *total_entries; resume_handle++) {
929 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
930 ctr0->array,
931 struct srvsvc_NetConnInfo0,
932 num_entries+1);
933 if (!ctr0->array) {
934 return WERR_NOMEM;
937 ctr0->array[num_entries].conn_id = *total_entries;
939 /* move on to creating next connection */
940 num_entries++;
943 ctr0->count = num_entries;
944 *total_entries = num_entries;
946 if (resume_handle_p) {
947 if (*resume_handle_p >= *total_entries) {
948 *resume_handle_p = 0;
949 } else {
950 *resume_handle_p = resume_handle;
954 return WERR_OK;
957 /*******************************************************************
958 fill in a conn info level 1 structure.
959 ********************************************************************/
961 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
962 uint32_t *resume_handle_p,
963 uint32_t *total_entries)
965 uint32_t num_entries = 0;
966 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
968 DEBUG(5,("init_srv_conn_info_1\n"));
970 if (ctr1 == NULL) {
971 if (resume_handle_p) {
972 *resume_handle_p = 0;
974 return WERR_OK;
977 *total_entries = 1;
979 ZERO_STRUCTP(ctr1);
981 for (; resume_handle < *total_entries; resume_handle++) {
983 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
984 ctr1->array,
985 struct srvsvc_NetConnInfo1,
986 num_entries+1);
987 if (!ctr1->array) {
988 return WERR_NOMEM;
991 ctr1->array[num_entries].conn_id = *total_entries;
992 ctr1->array[num_entries].conn_type = 0x3;
993 ctr1->array[num_entries].num_open = 1;
994 ctr1->array[num_entries].num_users = 1;
995 ctr1->array[num_entries].conn_time = 3;
996 ctr1->array[num_entries].user = "dummy_user";
997 ctr1->array[num_entries].share = "IPC$";
999 /* move on to creating next connection */
1000 num_entries++;
1003 ctr1->count = num_entries;
1004 *total_entries = num_entries;
1006 if (resume_handle_p) {
1007 if (*resume_handle_p >= *total_entries) {
1008 *resume_handle_p = 0;
1009 } else {
1010 *resume_handle_p = resume_handle;
1014 return WERR_OK;
1017 /*******************************************************************
1018 _srvsvc_NetFileEnum
1019 *******************************************************************/
1021 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
1022 struct srvsvc_NetFileEnum *r)
1024 TALLOC_CTX *ctx = NULL;
1025 struct srvsvc_NetFileCtr3 *ctr3;
1026 uint32_t resume_hnd = 0;
1027 WERROR werr;
1029 switch (r->in.info_ctr->level) {
1030 case 3:
1031 break;
1032 default:
1033 return WERR_UNKNOWN_LEVEL;
1036 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1037 p->server_info->ptok)) {
1038 DEBUG(1, ("Enumerating files only allowed for "
1039 "administrators\n"));
1040 return WERR_ACCESS_DENIED;
1043 ctx = talloc_tos();
1044 ctr3 = r->in.info_ctr->ctr.ctr3;
1045 if (!ctr3) {
1046 werr = WERR_INVALID_PARAM;
1047 goto done;
1050 /* TODO -- Windows enumerates
1051 (b) active pipes
1052 (c) open directories and files */
1054 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1055 if (!W_ERROR_IS_OK(werr)) {
1056 goto done;
1059 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1060 if (!W_ERROR_IS_OK(werr)) {
1061 goto done;
1064 *r->out.totalentries = ctr3->count;
1065 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1066 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1068 werr = WERR_OK;
1070 done:
1071 return werr;
1074 /*******************************************************************
1075 _srvsvc_NetSrvGetInfo
1076 ********************************************************************/
1078 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1079 struct srvsvc_NetSrvGetInfo *r)
1081 WERROR status = WERR_OK;
1083 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1085 if (!pipe_access_check(p)) {
1086 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1087 return WERR_ACCESS_DENIED;
1090 switch (r->in.level) {
1092 /* Technically level 102 should only be available to
1093 Administrators but there isn't anything super-secret
1094 here, as most of it is made up. */
1096 case 102: {
1097 struct srvsvc_NetSrvInfo102 *info102;
1099 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1100 if (!info102) {
1101 return WERR_NOMEM;
1104 info102->platform_id = PLATFORM_ID_NT;
1105 info102->server_name = global_myname();
1106 info102->version_major = lp_major_announce_version();
1107 info102->version_minor = lp_minor_announce_version();
1108 info102->server_type = lp_default_server_announce();
1109 info102->comment = string_truncate(lp_serverstring(),
1110 MAX_SERVER_STRING_LENGTH);
1111 info102->users = 0xffffffff;
1112 info102->disc = 0xf;
1113 info102->hidden = 0;
1114 info102->announce = 240;
1115 info102->anndelta = 3000;
1116 info102->licenses = 100000;
1117 info102->userpath = "C:\\";
1119 r->out.info->info102 = info102;
1120 break;
1122 case 101: {
1123 struct srvsvc_NetSrvInfo101 *info101;
1125 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1126 if (!info101) {
1127 return WERR_NOMEM;
1130 info101->platform_id = PLATFORM_ID_NT;
1131 info101->server_name = global_myname();
1132 info101->version_major = lp_major_announce_version();
1133 info101->version_minor = lp_minor_announce_version();
1134 info101->server_type = lp_default_server_announce();
1135 info101->comment = string_truncate(lp_serverstring(),
1136 MAX_SERVER_STRING_LENGTH);
1138 r->out.info->info101 = info101;
1139 break;
1141 case 100: {
1142 struct srvsvc_NetSrvInfo100 *info100;
1144 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1145 if (!info100) {
1146 return WERR_NOMEM;
1149 info100->platform_id = PLATFORM_ID_NT;
1150 info100->server_name = global_myname();
1152 r->out.info->info100 = info100;
1154 break;
1156 default:
1157 status = WERR_UNKNOWN_LEVEL;
1158 break;
1161 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1163 return status;
1166 /*******************************************************************
1167 _srvsvc_NetSrvSetInfo
1168 ********************************************************************/
1170 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1171 struct srvsvc_NetSrvSetInfo *r)
1173 WERROR status = WERR_OK;
1175 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1177 /* Set up the net server set info structure. */
1179 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1181 return status;
1184 /*******************************************************************
1185 _srvsvc_NetConnEnum
1186 ********************************************************************/
1188 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1189 struct srvsvc_NetConnEnum *r)
1191 WERROR werr;
1193 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1195 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1196 p->server_info->ptok)) {
1197 DEBUG(1, ("Enumerating connections only allowed for "
1198 "administrators\n"));
1199 return WERR_ACCESS_DENIED;
1202 switch (r->in.info_ctr->level) {
1203 case 0:
1204 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1205 r->in.resume_handle,
1206 r->out.totalentries);
1207 break;
1208 case 1:
1209 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1210 r->in.resume_handle,
1211 r->out.totalentries);
1212 break;
1213 default:
1214 return WERR_UNKNOWN_LEVEL;
1217 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1219 return werr;
1222 /*******************************************************************
1223 _srvsvc_NetSessEnum
1224 ********************************************************************/
1226 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1227 struct srvsvc_NetSessEnum *r)
1229 WERROR werr;
1231 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1233 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1234 p->server_info->ptok)) {
1235 DEBUG(1, ("Enumerating sessions only allowed for "
1236 "administrators\n"));
1237 return WERR_ACCESS_DENIED;
1240 switch (r->in.info_ctr->level) {
1241 case 0:
1242 werr = init_srv_sess_info_0(p,
1243 r->in.info_ctr->ctr.ctr0,
1244 r->in.resume_handle,
1245 r->out.totalentries);
1246 break;
1247 case 1:
1248 werr = init_srv_sess_info_1(p,
1249 r->in.info_ctr->ctr.ctr1,
1250 r->in.resume_handle,
1251 r->out.totalentries);
1252 break;
1253 default:
1254 return WERR_UNKNOWN_LEVEL;
1257 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1259 return werr;
1262 /*******************************************************************
1263 _srvsvc_NetSessDel
1264 ********************************************************************/
1266 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1267 struct srvsvc_NetSessDel *r)
1269 struct sessionid *session_list;
1270 int num_sessions, snum;
1271 const char *username;
1272 const char *machine;
1273 bool not_root = False;
1274 WERROR werr;
1276 username = r->in.user;
1277 machine = r->in.client;
1279 /* strip leading backslashes if any */
1280 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1281 machine += 2;
1284 num_sessions = list_sessions(p->mem_ctx, &session_list);
1286 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1288 werr = WERR_ACCESS_DENIED;
1290 /* fail out now if you are not root or not a domain admin */
1292 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1293 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1294 DOMAIN_GROUP_RID_ADMINS))) {
1296 goto done;
1299 for (snum = 0; snum < num_sessions; snum++) {
1301 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1302 strequal(session_list[snum].remote_machine, machine)) {
1304 NTSTATUS ntstat;
1306 if (p->server_info->utok.uid != sec_initial_uid()) {
1307 not_root = True;
1308 become_root();
1311 ntstat = messaging_send(smbd_messaging_context(),
1312 session_list[snum].pid,
1313 MSG_SHUTDOWN, &data_blob_null);
1315 if (NT_STATUS_IS_OK(ntstat))
1316 werr = WERR_OK;
1318 if (not_root)
1319 unbecome_root();
1323 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1325 done:
1327 return werr;
1330 /*******************************************************************
1331 _srvsvc_NetShareEnumAll
1332 ********************************************************************/
1334 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1335 struct srvsvc_NetShareEnumAll *r)
1337 WERROR werr;
1339 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1341 if (!pipe_access_check(p)) {
1342 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1343 return WERR_ACCESS_DENIED;
1346 /* Create the list of shares for the response. */
1347 werr = init_srv_share_info_ctr(p,
1348 r->in.info_ctr,
1349 r->in.resume_handle,
1350 r->out.totalentries,
1351 true);
1353 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1355 return werr;
1358 /*******************************************************************
1359 _srvsvc_NetShareEnum
1360 ********************************************************************/
1362 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1363 struct srvsvc_NetShareEnum *r)
1365 WERROR werr;
1367 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1369 if (!pipe_access_check(p)) {
1370 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1371 return WERR_ACCESS_DENIED;
1374 /* Create the list of shares for the response. */
1375 werr = init_srv_share_info_ctr(p,
1376 r->in.info_ctr,
1377 r->in.resume_handle,
1378 r->out.totalentries,
1379 false);
1381 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1383 return werr;
1386 /*******************************************************************
1387 _srvsvc_NetShareGetInfo
1388 ********************************************************************/
1390 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1391 struct srvsvc_NetShareGetInfo *r)
1393 WERROR status = WERR_OK;
1394 fstring share_name;
1395 int snum;
1396 union srvsvc_NetShareInfo *info = r->out.info;
1398 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1400 if (!r->in.share_name) {
1401 return WERR_INVALID_NAME;
1404 snum = find_service(r->in.share_name, share_name);
1405 if (snum < 0) {
1406 return WERR_INVALID_NAME;
1409 switch (r->in.level) {
1410 case 0:
1411 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1412 W_ERROR_HAVE_NO_MEMORY(info->info0);
1413 init_srv_share_info_0(p, info->info0, snum);
1414 break;
1415 case 1:
1416 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1417 W_ERROR_HAVE_NO_MEMORY(info->info1);
1418 init_srv_share_info_1(p, info->info1, snum);
1419 break;
1420 case 2:
1421 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1422 W_ERROR_HAVE_NO_MEMORY(info->info2);
1423 init_srv_share_info_2(p, info->info2, snum);
1424 break;
1425 case 501:
1426 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1427 W_ERROR_HAVE_NO_MEMORY(info->info501);
1428 init_srv_share_info_501(p, info->info501, snum);
1429 break;
1430 case 502:
1431 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1432 W_ERROR_HAVE_NO_MEMORY(info->info502);
1433 init_srv_share_info_502(p, info->info502, snum);
1434 break;
1435 case 1004:
1436 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1437 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1438 init_srv_share_info_1004(p, info->info1004, snum);
1439 break;
1440 case 1005:
1441 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1442 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1443 init_srv_share_info_1005(p, info->info1005, snum);
1444 break;
1445 case 1006:
1446 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1447 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1448 init_srv_share_info_1006(p, info->info1006, snum);
1449 break;
1450 case 1007:
1451 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1452 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1453 init_srv_share_info_1007(p, info->info1007, snum);
1454 break;
1455 case 1501:
1456 init_srv_share_info_1501(p, info->info1501, snum);
1457 break;
1458 default:
1459 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1460 r->in.level));
1461 status = WERR_UNKNOWN_LEVEL;
1462 break;
1465 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1467 return status;
1470 /*******************************************************************
1471 Check a given DOS pathname is valid for a share.
1472 ********************************************************************/
1474 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1476 char *ptr = NULL;
1478 if (!dos_pathname) {
1479 return NULL;
1482 ptr = talloc_strdup(ctx, dos_pathname);
1483 if (!ptr) {
1484 return NULL;
1486 /* Convert any '\' paths to '/' */
1487 unix_format(ptr);
1488 ptr = unix_clean_name(ctx, ptr);
1489 if (!ptr) {
1490 return NULL;
1493 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1494 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1495 ptr += 2;
1497 /* Only absolute paths allowed. */
1498 if (*ptr != '/')
1499 return NULL;
1501 return ptr;
1504 /*******************************************************************
1505 _srvsvc_NetShareSetInfo. Modify share details.
1506 ********************************************************************/
1508 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1509 struct srvsvc_NetShareSetInfo *r)
1511 char *command = NULL;
1512 fstring share_name;
1513 char *comment = NULL;
1514 const char *pathname = NULL;
1515 int type;
1516 int snum;
1517 int ret;
1518 char *path = NULL;
1519 SEC_DESC *psd = NULL;
1520 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1521 bool is_disk_op = False;
1522 int max_connections = 0;
1523 TALLOC_CTX *ctx = p->mem_ctx;
1524 union srvsvc_NetShareInfo *info = r->in.info;
1526 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1528 if (!r->in.share_name) {
1529 return WERR_INVALID_NAME;
1532 if (r->out.parm_error) {
1533 *r->out.parm_error = 0;
1536 if ( strequal(r->in.share_name,"IPC$")
1537 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1538 || strequal(r->in.share_name,"global") )
1540 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1541 "modified by a remote user.\n",
1542 r->in.share_name ));
1543 return WERR_ACCESS_DENIED;
1546 snum = find_service(r->in.share_name, share_name);
1548 /* Does this share exist ? */
1549 if (snum < 0)
1550 return WERR_NET_NAME_NOT_FOUND;
1552 /* No change to printer shares. */
1553 if (lp_print_ok(snum))
1554 return WERR_ACCESS_DENIED;
1556 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1558 /* fail out now if you are not root and not a disk op */
1560 if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1561 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1562 "SeDiskOperatorPrivilege privilege needed to modify "
1563 "share %s\n",
1564 (unsigned int)p->server_info->utok.uid,
1565 share_name ));
1566 return WERR_ACCESS_DENIED;
1569 switch (r->in.level) {
1570 case 1:
1571 pathname = talloc_strdup(ctx, lp_pathname(snum));
1572 comment = talloc_strdup(ctx, info->info1->comment);
1573 type = info->info1->type;
1574 psd = NULL;
1575 break;
1576 case 2:
1577 comment = talloc_strdup(ctx, info->info2->comment);
1578 pathname = info->info2->path;
1579 type = info->info2->type;
1580 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1581 0 : info->info2->max_users;
1582 psd = NULL;
1583 break;
1584 #if 0
1585 /* not supported on set but here for completeness */
1586 case 501:
1587 comment = talloc_strdup(ctx, info->info501->comment);
1588 type = info->info501->type;
1589 psd = NULL;
1590 break;
1591 #endif
1592 case 502:
1593 comment = talloc_strdup(ctx, info->info502->comment);
1594 pathname = info->info502->path;
1595 type = info->info502->type;
1596 psd = info->info502->sd_buf.sd;
1597 map_generic_share_sd_bits(psd);
1598 break;
1599 case 1004:
1600 pathname = talloc_strdup(ctx, lp_pathname(snum));
1601 comment = talloc_strdup(ctx, info->info1004->comment);
1602 type = STYPE_DISKTREE;
1603 break;
1604 case 1005:
1605 /* XP re-sets the csc policy even if it wasn't changed by the
1606 user, so we must compare it to see if it's what is set in
1607 smb.conf, so that we can contine other ops like setting
1608 ACLs on a share */
1609 if (((info->info1005->dfs_flags &
1610 SHARE_1005_CSC_POLICY_MASK) >>
1611 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1612 return WERR_OK;
1613 else {
1614 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1615 return WERR_ACCESS_DENIED;
1617 case 1006:
1618 case 1007:
1619 return WERR_ACCESS_DENIED;
1620 case 1501:
1621 pathname = talloc_strdup(ctx, lp_pathname(snum));
1622 comment = talloc_strdup(ctx, lp_comment(snum));
1623 psd = info->info1501->sd;
1624 map_generic_share_sd_bits(psd);
1625 type = STYPE_DISKTREE;
1626 break;
1627 default:
1628 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1629 r->in.level));
1630 return WERR_UNKNOWN_LEVEL;
1633 /* We can only modify disk shares. */
1634 if (type != STYPE_DISKTREE) {
1635 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1636 "disk share\n",
1637 share_name ));
1638 return WERR_ACCESS_DENIED;
1641 if (comment == NULL) {
1642 return WERR_NOMEM;
1645 /* Check if the pathname is valid. */
1646 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1647 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1648 pathname ));
1649 return WERR_OBJECT_PATH_INVALID;
1652 /* Ensure share name, pathname and comment don't contain '"' characters. */
1653 string_replace(share_name, '"', ' ');
1654 string_replace(path, '"', ' ');
1655 string_replace(comment, '"', ' ');
1657 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1658 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1660 /* Only call modify function if something changed. */
1662 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1663 || (lp_max_connections(snum) != max_connections)) {
1664 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1665 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1666 return WERR_ACCESS_DENIED;
1669 command = talloc_asprintf(p->mem_ctx,
1670 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1671 lp_change_share_cmd(),
1672 get_dyn_CONFIGFILE(),
1673 share_name,
1674 path,
1675 comment ? comment : "",
1676 max_connections);
1677 if (!command) {
1678 return WERR_NOMEM;
1681 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1683 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1685 if (is_disk_op)
1686 become_root();
1688 if ( (ret = smbrun(command, NULL)) == 0 ) {
1689 /* Tell everyone we updated smb.conf. */
1690 message_send_all(smbd_messaging_context(),
1691 MSG_SMB_CONF_UPDATED, NULL, 0,
1692 NULL);
1695 if ( is_disk_op )
1696 unbecome_root();
1698 /********* END SeDiskOperatorPrivilege BLOCK *********/
1700 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1701 command, ret ));
1703 TALLOC_FREE(command);
1705 if ( ret != 0 )
1706 return WERR_ACCESS_DENIED;
1707 } else {
1708 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1709 share_name ));
1712 /* Replace SD if changed. */
1713 if (psd) {
1714 SEC_DESC *old_sd;
1715 size_t sd_size;
1717 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1719 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1720 if (!set_share_security(share_name, psd))
1721 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1722 share_name ));
1726 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1728 return WERR_OK;
1731 /*******************************************************************
1732 _srvsvc_NetShareAdd.
1733 Call 'add_share_command "sharename" "pathname"
1734 "comment" "max connections = "
1735 ********************************************************************/
1737 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1738 struct srvsvc_NetShareAdd *r)
1740 char *command = NULL;
1741 char *share_name_in = NULL;
1742 fstring share_name;
1743 char *comment = NULL;
1744 char *pathname = NULL;
1745 int type;
1746 int snum;
1747 int ret;
1748 char *path;
1749 SEC_DESC *psd = NULL;
1750 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1751 bool is_disk_op;
1752 int max_connections = 0;
1753 TALLOC_CTX *ctx = p->mem_ctx;
1755 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1757 if (r->out.parm_error) {
1758 *r->out.parm_error = 0;
1761 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1763 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1764 return WERR_ACCESS_DENIED;
1766 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1767 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1768 return WERR_ACCESS_DENIED;
1771 switch (r->in.level) {
1772 case 0:
1773 /* No path. Not enough info in a level 0 to do anything. */
1774 return WERR_ACCESS_DENIED;
1775 case 1:
1776 /* Not enough info in a level 1 to do anything. */
1777 return WERR_ACCESS_DENIED;
1778 case 2:
1779 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
1780 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1781 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1782 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1783 0 : r->in.info->info2->max_users;
1784 type = r->in.info->info2->type;
1785 break;
1786 case 501:
1787 /* No path. Not enough info in a level 501 to do anything. */
1788 return WERR_ACCESS_DENIED;
1789 case 502:
1790 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
1791 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1792 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1793 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1794 0 : r->in.info->info502->max_users;
1795 type = r->in.info->info502->type;
1796 psd = r->in.info->info502->sd_buf.sd;
1797 map_generic_share_sd_bits(psd);
1798 break;
1800 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1802 case 1004:
1803 case 1005:
1804 case 1006:
1805 case 1007:
1806 return WERR_ACCESS_DENIED;
1807 case 1501:
1808 /* DFS only level. */
1809 return WERR_ACCESS_DENIED;
1810 default:
1811 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1812 r->in.level));
1813 return WERR_UNKNOWN_LEVEL;
1816 /* check for invalid share names */
1818 if (!share_name_in || !validate_net_name(share_name_in,
1819 INVALID_SHARENAME_CHARS,
1820 strlen(share_name_in))) {
1821 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1822 share_name_in ? share_name_in : ""));
1823 return WERR_INVALID_NAME;
1826 if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
1827 || (lp_enable_asu_support() &&
1828 strequal(share_name_in,"ADMIN$"))) {
1829 return WERR_ACCESS_DENIED;
1832 snum = find_service(share_name_in, share_name);
1834 /* Share already exists. */
1835 if (snum >= 0) {
1836 return WERR_FILE_EXISTS;
1839 /* We can only add disk shares. */
1840 if (type != STYPE_DISKTREE) {
1841 return WERR_ACCESS_DENIED;
1844 /* Check if the pathname is valid. */
1845 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1846 return WERR_OBJECT_PATH_INVALID;
1849 /* Ensure share name, pathname and comment don't contain '"' characters. */
1850 string_replace(share_name_in, '"', ' ');
1851 string_replace(path, '"', ' ');
1852 if (comment) {
1853 string_replace(comment, '"', ' ');
1856 command = talloc_asprintf(ctx,
1857 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1858 lp_add_share_cmd(),
1859 get_dyn_CONFIGFILE(),
1860 share_name_in,
1861 path,
1862 comment ? comment : "",
1863 max_connections);
1864 if (!command) {
1865 return WERR_NOMEM;
1868 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1870 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1872 if ( is_disk_op )
1873 become_root();
1875 /* FIXME: use libnetconf here - gd */
1877 if ( (ret = smbrun(command, NULL)) == 0 ) {
1878 /* Tell everyone we updated smb.conf. */
1879 message_send_all(smbd_messaging_context(),
1880 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1883 if ( is_disk_op )
1884 unbecome_root();
1886 /********* END SeDiskOperatorPrivilege BLOCK *********/
1888 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1889 command, ret ));
1891 TALLOC_FREE(command);
1893 if ( ret != 0 )
1894 return WERR_ACCESS_DENIED;
1896 if (psd) {
1897 /* Note we use share_name here, not share_name_in as
1898 we need a canonicalized name for setting security. */
1899 if (!set_share_security(share_name, psd)) {
1900 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1901 share_name ));
1906 * We don't call reload_services() here, the message will
1907 * cause this to be done before the next packet is read
1908 * from the client. JRA.
1911 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1913 return WERR_OK;
1916 /*******************************************************************
1917 _srvsvc_NetShareDel
1918 Call "delete share command" with the share name as
1919 a parameter.
1920 ********************************************************************/
1922 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1923 struct srvsvc_NetShareDel *r)
1925 char *command = NULL;
1926 fstring share_name;
1927 int ret;
1928 int snum;
1929 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1930 bool is_disk_op;
1931 struct share_params *params;
1932 TALLOC_CTX *ctx = p->mem_ctx;
1934 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1936 if (!r->in.share_name) {
1937 return WERR_NET_NAME_NOT_FOUND;
1939 if ( strequal(r->in.share_name,"IPC$")
1940 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1941 || strequal(r->in.share_name,"global") )
1943 return WERR_ACCESS_DENIED;
1946 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1947 return WERR_NO_SUCH_SHARE;
1950 snum = find_service(r->in.share_name, share_name);
1952 /* No change to printer shares. */
1953 if (lp_print_ok(snum))
1954 return WERR_ACCESS_DENIED;
1956 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1958 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1959 return WERR_ACCESS_DENIED;
1961 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1962 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1963 return WERR_ACCESS_DENIED;
1966 command = talloc_asprintf(ctx,
1967 "%s \"%s\" \"%s\"",
1968 lp_delete_share_cmd(),
1969 get_dyn_CONFIGFILE(),
1970 lp_servicename(snum));
1971 if (!command) {
1972 return WERR_NOMEM;
1975 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1977 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1979 if ( is_disk_op )
1980 become_root();
1982 if ( (ret = smbrun(command, NULL)) == 0 ) {
1983 /* Tell everyone we updated smb.conf. */
1984 message_send_all(smbd_messaging_context(),
1985 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1988 if ( is_disk_op )
1989 unbecome_root();
1991 /********* END SeDiskOperatorPrivilege BLOCK *********/
1993 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1995 if ( ret != 0 )
1996 return WERR_ACCESS_DENIED;
1998 /* Delete the SD in the database. */
1999 delete_share_security(lp_servicename(params->service));
2001 lp_killservice(params->service);
2003 return WERR_OK;
2006 /*******************************************************************
2007 _srvsvc_NetShareDelSticky
2008 ********************************************************************/
2010 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
2011 struct srvsvc_NetShareDelSticky *r)
2013 struct srvsvc_NetShareDel q;
2015 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2017 q.in.server_unc = r->in.server_unc;
2018 q.in.share_name = r->in.share_name;
2019 q.in.reserved = r->in.reserved;
2021 return _srvsvc_NetShareDel(p, &q);
2024 /*******************************************************************
2025 _srvsvc_NetRemoteTOD
2026 ********************************************************************/
2028 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2029 struct srvsvc_NetRemoteTOD *r)
2031 struct srvsvc_NetRemoteTODInfo *tod;
2032 struct tm *t;
2033 time_t unixdate = time(NULL);
2035 /* We do this call first as if we do it *after* the gmtime call
2036 it overwrites the pointed-to values. JRA */
2038 uint32 zone = get_time_zone(unixdate)/60;
2040 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2042 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2043 return WERR_NOMEM;
2045 *r->out.info = tod;
2047 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2049 t = gmtime(&unixdate);
2051 /* set up the */
2052 tod->elapsed = unixdate;
2053 tod->msecs = 0;
2054 tod->hours = t->tm_hour;
2055 tod->mins = t->tm_min;
2056 tod->secs = t->tm_sec;
2057 tod->hunds = 0;
2058 tod->timezone = zone;
2059 tod->tinterval = 10000;
2060 tod->day = t->tm_mday;
2061 tod->month = t->tm_mon + 1;
2062 tod->year = 1900+t->tm_year;
2063 tod->weekday = t->tm_wday;
2065 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2067 return WERR_OK;
2070 /***********************************************************************************
2071 _srvsvc_NetGetFileSecurity
2072 Win9x NT tools get security descriptor.
2073 ***********************************************************************************/
2075 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2076 struct srvsvc_NetGetFileSecurity *r)
2078 struct smb_filename *smb_fname = NULL;
2079 SEC_DESC *psd = NULL;
2080 size_t sd_size;
2081 fstring servicename;
2082 SMB_STRUCT_STAT st;
2083 NTSTATUS nt_status;
2084 WERROR werr;
2085 connection_struct *conn = NULL;
2086 struct sec_desc_buf *sd_buf = NULL;
2087 files_struct *fsp = NULL;
2088 int snum;
2089 char *oldcwd = NULL;
2091 ZERO_STRUCT(st);
2093 if (!r->in.share) {
2094 return WERR_INVALID_NAME;
2097 snum = find_service(r->in.share, servicename);
2098 if (snum == -1) {
2099 DEBUG(10, ("Could not find service %s\n", servicename));
2100 werr = WERR_NET_NAME_NOT_FOUND;
2101 goto error_exit;
2104 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2105 lp_pathname(snum), p->server_info,
2106 &oldcwd);
2107 if (!NT_STATUS_IS_OK(nt_status)) {
2108 DEBUG(10, ("create_conn_struct failed: %s\n",
2109 nt_errstr(nt_status)));
2110 werr = ntstatus_to_werror(nt_status);
2111 goto error_exit;
2114 nt_status = filename_convert(talloc_tos(),
2115 conn,
2116 false,
2117 r->in.file,
2119 NULL,
2120 &smb_fname);
2121 if (!NT_STATUS_IS_OK(nt_status)) {
2122 werr = ntstatus_to_werror(nt_status);
2123 goto error_exit;
2126 nt_status = SMB_VFS_CREATE_FILE(
2127 conn, /* conn */
2128 NULL, /* req */
2129 0, /* root_dir_fid */
2130 smb_fname, /* fname */
2131 FILE_READ_ATTRIBUTES, /* access_mask */
2132 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2133 FILE_OPEN, /* create_disposition*/
2134 0, /* create_options */
2135 0, /* file_attributes */
2136 INTERNAL_OPEN_ONLY, /* oplock_request */
2137 0, /* allocation_size */
2138 NULL, /* sd */
2139 NULL, /* ea_list */
2140 &fsp, /* result */
2141 NULL); /* pinfo */
2143 if (!NT_STATUS_IS_OK(nt_status)) {
2144 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2145 smb_fname_str_dbg(smb_fname)));
2146 werr = ntstatus_to_werror(nt_status);
2147 goto error_exit;
2150 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2151 (OWNER_SECURITY_INFORMATION
2152 |GROUP_SECURITY_INFORMATION
2153 |DACL_SECURITY_INFORMATION), &psd);
2155 if (!NT_STATUS_IS_OK(nt_status)) {
2156 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2157 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2158 werr = ntstatus_to_werror(nt_status);
2159 goto error_exit;
2162 sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2164 sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2165 if (!sd_buf) {
2166 werr = WERR_NOMEM;
2167 goto error_exit;
2170 sd_buf->sd_size = sd_size;
2171 sd_buf->sd = psd;
2173 *r->out.sd_buf = sd_buf;
2175 psd->dacl->revision = NT4_ACL_REVISION;
2177 close_file(NULL, fsp, NORMAL_CLOSE);
2178 vfs_ChDir(conn, oldcwd);
2179 conn_free(conn);
2180 werr = WERR_OK;
2181 goto done;
2183 error_exit:
2185 if (fsp) {
2186 close_file(NULL, fsp, NORMAL_CLOSE);
2189 if (oldcwd) {
2190 vfs_ChDir(conn, oldcwd);
2193 if (conn) {
2194 conn_free(conn);
2197 done:
2198 TALLOC_FREE(smb_fname);
2200 return werr;
2203 /***********************************************************************************
2204 _srvsvc_NetSetFileSecurity
2205 Win9x NT tools set security descriptor.
2206 ***********************************************************************************/
2208 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2209 struct srvsvc_NetSetFileSecurity *r)
2211 struct smb_filename *smb_fname = NULL;
2212 fstring servicename;
2213 files_struct *fsp = NULL;
2214 SMB_STRUCT_STAT st;
2215 NTSTATUS nt_status;
2216 WERROR werr;
2217 connection_struct *conn = NULL;
2218 int snum;
2219 char *oldcwd = NULL;
2220 struct security_descriptor *psd = NULL;
2221 uint32_t security_info_sent = 0;
2223 ZERO_STRUCT(st);
2225 if (!r->in.share) {
2226 return WERR_INVALID_NAME;
2229 snum = find_service(r->in.share, servicename);
2230 if (snum == -1) {
2231 DEBUG(10, ("Could not find service %s\n", servicename));
2232 werr = WERR_NET_NAME_NOT_FOUND;
2233 goto error_exit;
2236 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2237 lp_pathname(snum), p->server_info,
2238 &oldcwd);
2239 if (!NT_STATUS_IS_OK(nt_status)) {
2240 DEBUG(10, ("create_conn_struct failed: %s\n",
2241 nt_errstr(nt_status)));
2242 werr = ntstatus_to_werror(nt_status);
2243 goto error_exit;
2246 nt_status = filename_convert(talloc_tos(),
2247 conn,
2248 false,
2249 r->in.file,
2251 NULL,
2252 &smb_fname);
2253 if (!NT_STATUS_IS_OK(nt_status)) {
2254 werr = ntstatus_to_werror(nt_status);
2255 goto error_exit;
2258 nt_status = SMB_VFS_CREATE_FILE(
2259 conn, /* conn */
2260 NULL, /* req */
2261 0, /* root_dir_fid */
2262 smb_fname, /* fname */
2263 FILE_WRITE_ATTRIBUTES, /* access_mask */
2264 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2265 FILE_OPEN, /* create_disposition*/
2266 0, /* create_options */
2267 0, /* file_attributes */
2268 INTERNAL_OPEN_ONLY, /* oplock_request */
2269 0, /* allocation_size */
2270 NULL, /* sd */
2271 NULL, /* ea_list */
2272 &fsp, /* result */
2273 NULL); /* pinfo */
2275 if (!NT_STATUS_IS_OK(nt_status)) {
2276 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2277 smb_fname_str_dbg(smb_fname)));
2278 werr = ntstatus_to_werror(nt_status);
2279 goto error_exit;
2282 psd = r->in.sd_buf->sd;
2283 security_info_sent = r->in.securityinformation;
2285 if (psd->owner_sid==0) {
2286 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2288 if (psd->group_sid==0) {
2289 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2291 if (psd->sacl==0) {
2292 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2294 if (psd->dacl==0) {
2295 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2298 /* Convert all the generic bits. */
2299 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2300 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2302 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2303 security_info_sent,
2304 psd);
2306 if (!NT_STATUS_IS_OK(nt_status) ) {
2307 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2308 "on file %s\n", r->in.share));
2309 werr = WERR_ACCESS_DENIED;
2310 goto error_exit;
2313 close_file(NULL, fsp, NORMAL_CLOSE);
2314 vfs_ChDir(conn, oldcwd);
2315 conn_free(conn);
2316 werr = WERR_OK;
2317 goto done;
2319 error_exit:
2321 if (fsp) {
2322 close_file(NULL, fsp, NORMAL_CLOSE);
2325 if (oldcwd) {
2326 vfs_ChDir(conn, oldcwd);
2329 if (conn) {
2330 conn_free(conn);
2333 done:
2334 TALLOC_FREE(smb_fname);
2336 return werr;
2339 /***********************************************************************************
2340 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2341 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2342 These disks would the disks listed by this function.
2343 Users could then create shares relative to these disks. Watch out for moving these disks around.
2344 "Nigel Williams" <nigel@veritas.com>.
2345 ***********************************************************************************/
2347 static const char *server_disks[] = {"C:"};
2349 static uint32 get_server_disk_count(void)
2351 return sizeof(server_disks)/sizeof(server_disks[0]);
2354 static uint32 init_server_disk_enum(uint32 *resume)
2356 uint32 server_disk_count = get_server_disk_count();
2358 /*resume can be an offset into the list for now*/
2360 if(*resume & 0x80000000)
2361 *resume = 0;
2363 if(*resume > server_disk_count)
2364 *resume = server_disk_count;
2366 return server_disk_count - *resume;
2369 static const char *next_server_disk_enum(uint32 *resume)
2371 const char *disk;
2373 if(init_server_disk_enum(resume) == 0)
2374 return NULL;
2376 disk = server_disks[*resume];
2378 (*resume)++;
2380 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2382 return disk;
2385 /********************************************************************
2386 _srvsvc_NetDiskEnum
2387 ********************************************************************/
2389 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2390 struct srvsvc_NetDiskEnum *r)
2392 uint32 i;
2393 const char *disk_name;
2394 TALLOC_CTX *ctx = p->mem_ctx;
2395 WERROR werr;
2396 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2398 werr = WERR_OK;
2400 *r->out.totalentries = init_server_disk_enum(&resume);
2402 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2403 MAX_SERVER_DISK_ENTRIES);
2404 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2406 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2408 r->out.info->count = 0;
2410 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2412 r->out.info->count++;
2414 /*copy disk name into a unicode string*/
2416 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2417 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2420 /* add a terminating null string. Is this there if there is more data to come? */
2422 r->out.info->count++;
2424 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2425 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2427 if (r->out.resume_handle) {
2428 *r->out.resume_handle = resume;
2431 return werr;
2434 /********************************************************************
2435 _srvsvc_NetNameValidate
2436 ********************************************************************/
2438 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2439 struct srvsvc_NetNameValidate *r)
2441 switch (r->in.name_type) {
2442 case 0x9:
2443 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2444 strlen_m(r->in.name)))
2446 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2447 r->in.name));
2448 return WERR_INVALID_NAME;
2450 break;
2452 default:
2453 return WERR_UNKNOWN_LEVEL;
2456 return WERR_OK;
2459 /*******************************************************************
2460 ********************************************************************/
2462 static void enum_file_close_fn( const struct share_mode_entry *e,
2463 const char *sharepath, const char *fname,
2464 void *private_data )
2466 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2467 struct srvsvc_NetFileClose *r =
2468 (struct srvsvc_NetFileClose *)private_data;
2469 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2471 if (fid != r->in.fid) {
2472 return; /* Not this file. */
2475 if (!process_exists(e->pid) ) {
2476 return;
2479 /* Ok - send the close message. */
2480 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2481 sharepath,
2482 share_mode_str(talloc_tos(), 0, e) ));
2484 share_mode_entry_to_message(msg, e);
2486 r->out.result = ntstatus_to_werror(
2487 messaging_send_buf(smbd_messaging_context(),
2488 e->pid, MSG_SMB_CLOSE_FILE,
2489 (uint8 *)msg,
2490 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2493 /********************************************************************
2494 Close a file given a 32-bit file id.
2495 ********************************************************************/
2497 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2499 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2500 bool is_disk_op;
2502 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2504 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2506 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2507 return WERR_ACCESS_DENIED;
2510 /* enum_file_close_fn sends the close message to
2511 * the relevent smbd process. */
2513 r->out.result = WERR_BADFILE;
2514 share_mode_forall( enum_file_close_fn, (void *)r);
2515 return r->out.result;
2518 /********************************************************************
2519 ********************************************************************/
2521 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2523 p->rng_fault_state = True;
2524 return WERR_NOT_SUPPORTED;
2527 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2529 p->rng_fault_state = True;
2530 return WERR_NOT_SUPPORTED;
2533 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2535 p->rng_fault_state = True;
2536 return WERR_NOT_SUPPORTED;
2539 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2541 p->rng_fault_state = True;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2547 p->rng_fault_state = True;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2553 p->rng_fault_state = True;
2554 return WERR_NOT_SUPPORTED;
2557 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2559 p->rng_fault_state = True;
2560 return WERR_NOT_SUPPORTED;
2563 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;
2569 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2571 p->rng_fault_state = True;
2572 return WERR_NOT_SUPPORTED;
2575 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2577 p->rng_fault_state = True;
2578 return WERR_NOT_SUPPORTED;
2581 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2583 p->rng_fault_state = True;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2589 p->rng_fault_state = True;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2595 p->rng_fault_state = True;
2596 return WERR_NOT_SUPPORTED;
2599 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2601 p->rng_fault_state = True;
2602 return WERR_NOT_SUPPORTED;
2605 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2607 p->rng_fault_state = True;
2608 return WERR_NOT_SUPPORTED;
2611 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2613 p->rng_fault_state = True;
2614 return WERR_NOT_SUPPORTED;
2617 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2619 p->rng_fault_state = True;
2620 return WERR_NOT_SUPPORTED;
2623 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2625 p->rng_fault_state = True;
2626 return WERR_NOT_SUPPORTED;
2629 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2631 p->rng_fault_state = True;
2632 return WERR_NOT_SUPPORTED;
2635 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2637 p->rng_fault_state = True;
2638 return WERR_NOT_SUPPORTED;
2641 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2643 p->rng_fault_state = True;
2644 return WERR_NOT_SUPPORTED;
2647 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2649 p->rng_fault_state = True;
2650 return WERR_NOT_SUPPORTED;
2653 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2655 p->rng_fault_state = True;
2656 return WERR_NOT_SUPPORTED;
2659 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2661 p->rng_fault_state = True;
2662 return WERR_NOT_SUPPORTED;
2665 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2667 p->rng_fault_state = True;
2668 return WERR_NOT_SUPPORTED;
2671 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2673 p->rng_fault_state = True;
2674 return WERR_NOT_SUPPORTED;
2677 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2679 p->rng_fault_state = True;
2680 return WERR_NOT_SUPPORTED;
2683 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2685 p->rng_fault_state = True;
2686 return WERR_NOT_SUPPORTED;
2689 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2691 p->rng_fault_state = True;
2692 return WERR_NOT_SUPPORTED;
2695 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2697 p->rng_fault_state = True;
2698 return WERR_NOT_SUPPORTED;
2701 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2703 p->rng_fault_state = True;
2704 return WERR_NOT_SUPPORTED;
2707 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2709 p->rng_fault_state = True;
2710 return WERR_NOT_SUPPORTED;
2713 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2715 p->rng_fault_state = True;
2716 return WERR_NOT_SUPPORTED;
2719 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2721 p->rng_fault_state = True;
2722 return WERR_NOT_SUPPORTED;
2725 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2727 p->rng_fault_state = True;
2728 return WERR_NOT_SUPPORTED;