s3:smbd map_username() doesn't need sconn anymore
[Samba/ekacnet.git] / source3 / rpc_server / srv_srvsvc_nt.c
blob40c26f68096cc2840207dca0d981fe27a2ca9f67
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"
28 #include "librpc/gen_ndr/messaging.h"
29 #include "../librpc/gen_ndr/ndr_security.h"
31 extern const struct generic_mapping file_generic_mapping;
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
36 #define MAX_SERVER_DISK_ENTRIES 15
38 /* Use for enumerating connections, pipes, & files */
40 struct file_enum_count {
41 TALLOC_CTX *ctx;
42 const char *username;
43 struct srvsvc_NetFileCtr3 *ctr3;
46 struct sess_file_count {
47 struct server_id pid;
48 uid_t uid;
49 int count;
52 /****************************************************************************
53 Count the entries belonging to a service in the connection db.
54 ****************************************************************************/
56 static int pipe_enum_fn( struct db_record *rec, void *p)
58 struct pipe_open_rec prec;
59 struct file_enum_count *fenum = (struct file_enum_count *)p;
60 struct srvsvc_NetFileInfo3 *f;
61 int i = fenum->ctr3->count;
62 char *fullpath = NULL;
63 const char *username;
65 if (rec->value.dsize != sizeof(struct pipe_open_rec))
66 return 0;
68 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
70 if ( !process_exists(prec.pid) ) {
71 return 0;
74 username = uidtoname(prec.uid);
76 if ((fenum->username != NULL)
77 && !strequal(username, fenum->username)) {
78 return 0;
81 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
82 if (!fullpath) {
83 return 1;
86 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
87 struct srvsvc_NetFileInfo3, i+1);
88 if ( !f ) {
89 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
90 return 1;
92 fenum->ctr3->array = f;
94 fenum->ctr3->array[i].fid =
95 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
96 fenum->ctr3->array[i].permissions =
97 (FILE_READ_DATA|FILE_WRITE_DATA);
98 fenum->ctr3->array[i].num_locks = 0;
99 fenum->ctr3->array[i].path = fullpath;
100 fenum->ctr3->array[i].user = username;
102 fenum->ctr3->count++;
104 return 0;
107 /*******************************************************************
108 ********************************************************************/
110 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
111 const char *username,
112 struct srvsvc_NetFileCtr3 **ctr3,
113 uint32_t resume )
115 struct file_enum_count fenum;
117 fenum.ctx = ctx;
118 fenum.username = username;
119 fenum.ctr3 = *ctr3;
121 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
122 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
123 "failed\n"));
124 return WERR_NOMEM;
127 *ctr3 = fenum.ctr3;
129 return WERR_OK;
132 /*******************************************************************
133 ********************************************************************/
135 static void enum_file_fn( const struct share_mode_entry *e,
136 const char *sharepath, const char *fname,
137 void *private_data )
139 struct file_enum_count *fenum =
140 (struct file_enum_count *)private_data;
142 struct srvsvc_NetFileInfo3 *f;
143 int i = fenum->ctr3->count;
144 files_struct fsp;
145 struct byte_range_lock *brl;
146 int num_locks = 0;
147 char *fullpath = NULL;
148 uint32 permissions;
149 const char *username;
151 /* If the pid was not found delete the entry from connections.tdb */
153 if ( !process_exists(e->pid) ) {
154 return;
157 username = uidtoname(e->uid);
159 if ((fenum->username != NULL)
160 && !strequal(username, fenum->username)) {
161 return;
164 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
165 struct srvsvc_NetFileInfo3, i+1);
166 if ( !f ) {
167 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
168 return;
170 fenum->ctr3->array = f;
172 /* need to count the number of locks on a file */
174 ZERO_STRUCT( fsp );
175 fsp.file_id = e->id;
177 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
178 num_locks = brl->num_locks;
179 TALLOC_FREE(brl);
182 if ( strcmp( fname, "." ) == 0 ) {
183 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
184 } else {
185 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
186 sharepath, fname );
188 if (!fullpath) {
189 return;
191 string_replace( fullpath, '/', '\\' );
193 /* mask out create (what ever that is) */
194 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
196 /* now fill in the srvsvc_NetFileInfo3 struct */
198 fenum->ctr3->array[i].fid =
199 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
200 fenum->ctr3->array[i].permissions = permissions;
201 fenum->ctr3->array[i].num_locks = num_locks;
202 fenum->ctr3->array[i].path = fullpath;
203 fenum->ctr3->array[i].user = username;
205 fenum->ctr3->count++;
208 /*******************************************************************
209 ********************************************************************/
211 static WERROR net_enum_files(TALLOC_CTX *ctx,
212 const char *username,
213 struct srvsvc_NetFileCtr3 **ctr3,
214 uint32_t resume)
216 struct file_enum_count f_enum_cnt;
218 f_enum_cnt.ctx = ctx;
219 f_enum_cnt.username = username;
220 f_enum_cnt.ctr3 = *ctr3;
222 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
224 *ctr3 = f_enum_cnt.ctr3;
226 return WERR_OK;
229 /*******************************************************************
230 Utility function to get the 'type' of a share from an snum.
231 ********************************************************************/
232 static uint32 get_share_type(int snum)
234 /* work out the share type */
235 uint32 type = STYPE_DISKTREE;
237 if (lp_print_ok(snum))
238 type = STYPE_PRINTQ;
239 if (strequal(lp_fstype(snum), "IPC"))
240 type = STYPE_IPC;
241 if (lp_administrative_share(snum))
242 type |= STYPE_HIDDEN;
244 return type;
247 /*******************************************************************
248 Fill in a share info level 0 structure.
249 ********************************************************************/
251 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
253 r->name = lp_servicename(snum);
256 /*******************************************************************
257 Fill in a share info level 1 structure.
258 ********************************************************************/
260 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
262 char *net_name = lp_servicename(snum);
263 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
265 if (remark) {
266 remark = talloc_sub_advanced(
267 p->mem_ctx, lp_servicename(snum),
268 get_current_username(), lp_pathname(snum),
269 p->server_info->utok.uid, get_current_username(),
270 "", remark);
273 r->name = net_name;
274 r->type = get_share_type(snum);
275 r->comment = remark ? remark : "";
278 /*******************************************************************
279 Fill in a share info level 2 structure.
280 ********************************************************************/
282 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
284 char *remark = NULL;
285 char *path = NULL;
286 int max_connections = lp_max_connections(snum);
287 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
288 char *net_name = lp_servicename(snum);
290 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
291 if (remark) {
292 remark = talloc_sub_advanced(
293 p->mem_ctx, lp_servicename(snum),
294 get_current_username(), lp_pathname(snum),
295 p->server_info->utok.uid, get_current_username(),
296 "", remark);
298 path = talloc_asprintf(p->mem_ctx,
299 "C:%s", lp_pathname(snum));
301 if (path) {
303 * Change / to \\ so that win2k will see it as a valid path.
304 * This was added to enable use of browsing in win2k add
305 * share dialog.
308 string_replace(path, '/', '\\');
311 r->name = net_name;
312 r->type = get_share_type(snum);
313 r->comment = remark ? remark : "";
314 r->permissions = 0;
315 r->max_users = max_uses;
316 r->current_users = count_current_connections(net_name, false);
317 r->path = path ? path : "";
318 r->password = "";
321 /*******************************************************************
322 Map any generic bits to file specific bits.
323 ********************************************************************/
325 static void map_generic_share_sd_bits(struct security_descriptor *psd)
327 int i;
328 struct security_acl *ps_dacl = NULL;
330 if (!psd)
331 return;
333 ps_dacl = psd->dacl;
334 if (!ps_dacl)
335 return;
337 for (i = 0; i < ps_dacl->num_aces; i++) {
338 struct security_ace *psa = &ps_dacl->aces[i];
339 uint32 orig_mask = psa->access_mask;
341 se_map_generic(&psa->access_mask, &file_generic_mapping);
342 psa->access_mask |= orig_mask;
346 /*******************************************************************
347 Fill in a share info level 501 structure.
348 ********************************************************************/
350 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
352 const char *net_name = lp_servicename(snum);
353 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
355 if (remark) {
356 remark = talloc_sub_advanced(
357 p->mem_ctx, lp_servicename(snum),
358 get_current_username(), lp_pathname(snum),
359 p->server_info->utok.uid, get_current_username(),
360 "", remark);
363 r->name = net_name;
364 r->type = get_share_type(snum);
365 r->comment = remark ? remark : "";
366 r->csc_policy = (lp_csc_policy(snum) << 4);
369 /*******************************************************************
370 Fill in a share info level 502 structure.
371 ********************************************************************/
373 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
375 const char *net_name = lp_servicename(snum);
376 char *path = NULL;
377 struct security_descriptor *sd = NULL;
378 struct sec_desc_buf *sd_buf = NULL;
379 size_t sd_size = 0;
380 TALLOC_CTX *ctx = p->mem_ctx;
381 char *remark = talloc_strdup(ctx, lp_comment(snum));;
383 if (remark) {
384 remark = talloc_sub_advanced(
385 p->mem_ctx, lp_servicename(snum),
386 get_current_username(), lp_pathname(snum),
387 p->server_info->utok.uid, get_current_username(),
388 "", remark);
390 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
391 if (path) {
393 * Change / to \\ so that win2k will see it as a valid path. This was added to
394 * enable use of browsing in win2k add share dialog.
396 string_replace(path, '/', '\\');
399 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
401 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
403 r->name = net_name;
404 r->type = get_share_type(snum);
405 r->comment = remark ? remark : "";
406 r->permissions = 0;
407 r->max_users = (uint32_t)-1;
408 r->current_users = 1; /* ??? */
409 r->path = path ? path : "";
410 r->password = "";
411 r->sd_buf = *sd_buf;
414 /***************************************************************************
415 Fill in a share info level 1004 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
420 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
422 if (remark) {
423 remark = talloc_sub_advanced(
424 p->mem_ctx, lp_servicename(snum),
425 get_current_username(), lp_pathname(snum),
426 p->server_info->utok.uid, get_current_username(),
427 "", remark);
430 r->comment = remark ? remark : "";
433 /***************************************************************************
434 Fill in a share info level 1005 structure.
435 ***************************************************************************/
437 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
439 uint32_t dfs_flags = 0;
441 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
442 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
445 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
447 r->dfs_flags = dfs_flags;
450 /***************************************************************************
451 Fill in a share info level 1006 structure.
452 ***************************************************************************/
454 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
456 r->max_users = (uint32_t)-1;
459 /***************************************************************************
460 Fill in a share info level 1007 structure.
461 ***************************************************************************/
463 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
465 r->flags = 0;
466 r->alternate_directory_name = "";
469 /*******************************************************************
470 Fill in a share info level 1501 structure.
471 ********************************************************************/
473 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
475 struct security_descriptor *sd;
476 size_t sd_size;
477 TALLOC_CTX *ctx = p->mem_ctx;
479 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
481 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
484 /*******************************************************************
485 True if it ends in '$'.
486 ********************************************************************/
488 static bool is_hidden_share(int snum)
490 const char *net_name = lp_servicename(snum);
492 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
495 /*******************************************************************
496 Verify user is allowed to view share, access based enumeration
497 ********************************************************************/
498 static bool is_enumeration_allowed(pipes_struct *p,
499 int snum)
501 if (!lp_access_based_share_enum(snum))
502 return true;
504 return share_access_check(p->server_info->ptok, lp_servicename(snum),
505 FILE_READ_DATA);
508 /*******************************************************************
509 Fill in a share info structure.
510 ********************************************************************/
512 static WERROR init_srv_share_info_ctr(pipes_struct *p,
513 struct srvsvc_NetShareInfoCtr *info_ctr,
514 uint32_t *resume_handle_p,
515 uint32_t *total_entries,
516 bool all_shares)
518 int num_entries = 0;
519 int alloc_entries = 0;
520 int num_services = 0;
521 int snum;
522 TALLOC_CTX *ctx = p->mem_ctx;
523 int i = 0;
524 int valid_share_count = 0;
525 bool *allowed = 0;
526 union srvsvc_NetShareCtr ctr;
527 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
529 DEBUG(5,("init_srv_share_info_ctr\n"));
531 /* Ensure all the usershares are loaded. */
532 become_root();
533 load_usershare_shares();
534 load_registry_shares();
535 num_services = lp_numservices();
536 unbecome_root();
538 allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
539 W_ERROR_HAVE_NO_MEMORY(allowed);
541 /* Count the number of entries. */
542 for (snum = 0; snum < num_services; snum++) {
543 if (lp_browseable(snum) && lp_snum_ok(snum) &&
544 is_enumeration_allowed(p, snum) &&
545 (all_shares || !is_hidden_share(snum)) ) {
546 DEBUG(10, ("counting service %s\n",
547 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
548 allowed[snum] = true;
549 num_entries++;
550 } else {
551 DEBUG(10, ("NOT counting service %s\n",
552 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
556 if (!num_entries || (resume_handle >= num_entries)) {
557 return WERR_OK;
560 /* Calculate alloc entries. */
561 alloc_entries = num_entries - resume_handle;
562 switch (info_ctr->level) {
563 case 0:
564 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
565 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
567 ctr.ctr0->count = alloc_entries;
568 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
569 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
571 for (snum = 0; snum < num_services; snum++) {
572 if (allowed[snum] &&
573 (resume_handle <= (i + valid_share_count++)) ) {
574 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
578 break;
580 case 1:
581 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
582 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
584 ctr.ctr1->count = alloc_entries;
585 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
586 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
588 for (snum = 0; snum < num_services; snum++) {
589 if (allowed[snum] &&
590 (resume_handle <= (i + valid_share_count++)) ) {
591 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
595 break;
597 case 2:
598 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
599 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
601 ctr.ctr2->count = alloc_entries;
602 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
603 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
605 for (snum = 0; snum < num_services; snum++) {
606 if (allowed[snum] &&
607 (resume_handle <= (i + valid_share_count++)) ) {
608 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
612 break;
614 case 501:
615 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
616 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
618 ctr.ctr501->count = alloc_entries;
619 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
620 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
622 for (snum = 0; snum < num_services; snum++) {
623 if (allowed[snum] &&
624 (resume_handle <= (i + valid_share_count++)) ) {
625 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
629 break;
631 case 502:
632 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
633 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
635 ctr.ctr502->count = alloc_entries;
636 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
637 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
639 for (snum = 0; snum < num_services; snum++) {
640 if (allowed[snum] &&
641 (resume_handle <= (i + valid_share_count++)) ) {
642 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
646 break;
648 case 1004:
649 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
650 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
652 ctr.ctr1004->count = alloc_entries;
653 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
654 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
656 for (snum = 0; snum < num_services; snum++) {
657 if (allowed[snum] &&
658 (resume_handle <= (i + valid_share_count++)) ) {
659 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
663 break;
665 case 1005:
666 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
667 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
669 ctr.ctr1005->count = alloc_entries;
670 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
671 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
673 for (snum = 0; snum < num_services; snum++) {
674 if (allowed[snum] &&
675 (resume_handle <= (i + valid_share_count++)) ) {
676 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
680 break;
682 case 1006:
683 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
684 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
686 ctr.ctr1006->count = alloc_entries;
687 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
688 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
690 for (snum = 0; snum < num_services; snum++) {
691 if (allowed[snum] &&
692 (resume_handle <= (i + valid_share_count++)) ) {
693 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
697 break;
699 case 1007:
700 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
701 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
703 ctr.ctr1007->count = alloc_entries;
704 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
705 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
707 for (snum = 0; snum < num_services; snum++) {
708 if (allowed[snum] &&
709 (resume_handle <= (i + valid_share_count++)) ) {
710 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
714 break;
716 case 1501:
717 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
718 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
720 ctr.ctr1501->count = alloc_entries;
721 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
722 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
724 for (snum = 0; snum < num_services; snum++) {
725 if (allowed[snum] &&
726 (resume_handle <= (i + valid_share_count++)) ) {
727 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
731 break;
733 default:
734 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
735 info_ctr->level));
736 return WERR_UNKNOWN_LEVEL;
739 *total_entries = alloc_entries;
740 if (resume_handle_p) {
741 if (all_shares) {
742 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
743 } else {
744 *resume_handle_p = num_entries;
748 info_ctr->ctr = ctr;
750 return WERR_OK;
753 /*******************************************************************
754 fill in a sess info level 0 structure.
755 ********************************************************************/
757 static WERROR init_srv_sess_info_0(pipes_struct *p,
758 struct srvsvc_NetSessCtr0 *ctr0,
759 uint32_t *resume_handle_p,
760 uint32_t *total_entries)
762 struct sessionid *session_list;
763 uint32_t num_entries = 0;
764 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
765 *total_entries = list_sessions(p->mem_ctx, &session_list);
767 DEBUG(5,("init_srv_sess_info_0\n"));
769 if (ctr0 == NULL) {
770 if (resume_handle_p) {
771 *resume_handle_p = 0;
773 return WERR_OK;
776 for (; resume_handle < *total_entries; resume_handle++) {
778 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
779 ctr0->array,
780 struct srvsvc_NetSessInfo0,
781 num_entries+1);
782 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
784 ctr0->array[num_entries].client =
785 session_list[resume_handle].remote_machine;
787 num_entries++;
790 ctr0->count = num_entries;
792 if (resume_handle_p) {
793 if (*resume_handle_p >= *total_entries) {
794 *resume_handle_p = 0;
795 } else {
796 *resume_handle_p = resume_handle;
800 return WERR_OK;
803 /*******************************************************************
804 ********************************************************************/
806 static void sess_file_fn( const struct share_mode_entry *e,
807 const char *sharepath, const char *fname,
808 void *data )
810 struct sess_file_count *sess = (struct sess_file_count *)data;
812 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
813 sess->count++;
816 return;
819 /*******************************************************************
820 ********************************************************************/
822 static int net_count_files( uid_t uid, struct server_id pid )
824 struct sess_file_count s_file_cnt;
826 s_file_cnt.count = 0;
827 s_file_cnt.uid = uid;
828 s_file_cnt.pid = pid;
830 share_mode_forall( sess_file_fn, &s_file_cnt );
832 return s_file_cnt.count;
835 /*******************************************************************
836 fill in a sess info level 1 structure.
837 ********************************************************************/
839 static WERROR init_srv_sess_info_1(pipes_struct *p,
840 struct srvsvc_NetSessCtr1 *ctr1,
841 uint32_t *resume_handle_p,
842 uint32_t *total_entries)
844 struct sessionid *session_list;
845 uint32_t num_entries = 0;
846 time_t now = time(NULL);
847 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
849 ZERO_STRUCTP(ctr1);
851 if (ctr1 == NULL) {
852 if (resume_handle_p) {
853 *resume_handle_p = 0;
855 return WERR_OK;
858 *total_entries = list_sessions(p->mem_ctx, &session_list);
860 for (; resume_handle < *total_entries; resume_handle++) {
861 uint32 num_files;
862 uint32 connect_time;
863 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
864 bool guest;
866 if ( !pw ) {
867 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
868 session_list[resume_handle].username));
869 continue;
872 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
873 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
874 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
876 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
877 ctr1->array,
878 struct srvsvc_NetSessInfo1,
879 num_entries+1);
880 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
882 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
883 ctr1->array[num_entries].user = session_list[resume_handle].username;
884 ctr1->array[num_entries].num_open = num_files;
885 ctr1->array[num_entries].time = connect_time;
886 ctr1->array[num_entries].idle_time = 0;
887 ctr1->array[num_entries].user_flags = guest;
889 num_entries++;
892 ctr1->count = num_entries;
894 if (resume_handle_p) {
895 if (*resume_handle_p >= *total_entries) {
896 *resume_handle_p = 0;
897 } else {
898 *resume_handle_p = resume_handle;
902 return WERR_OK;
905 /*******************************************************************
906 fill in a conn info level 0 structure.
907 ********************************************************************/
909 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
910 uint32_t *resume_handle_p,
911 uint32_t *total_entries)
913 uint32_t num_entries = 0;
914 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
916 DEBUG(5,("init_srv_conn_info_0\n"));
918 if (ctr0 == NULL) {
919 if (resume_handle_p) {
920 *resume_handle_p = 0;
922 return WERR_OK;
925 *total_entries = 1;
927 ZERO_STRUCTP(ctr0);
929 for (; resume_handle < *total_entries; resume_handle++) {
931 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
932 ctr0->array,
933 struct srvsvc_NetConnInfo0,
934 num_entries+1);
935 if (!ctr0->array) {
936 return WERR_NOMEM;
939 ctr0->array[num_entries].conn_id = *total_entries;
941 /* move on to creating next connection */
942 num_entries++;
945 ctr0->count = num_entries;
946 *total_entries = num_entries;
948 if (resume_handle_p) {
949 if (*resume_handle_p >= *total_entries) {
950 *resume_handle_p = 0;
951 } else {
952 *resume_handle_p = resume_handle;
956 return WERR_OK;
959 /*******************************************************************
960 fill in a conn info level 1 structure.
961 ********************************************************************/
963 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
964 uint32_t *resume_handle_p,
965 uint32_t *total_entries)
967 uint32_t num_entries = 0;
968 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
970 DEBUG(5,("init_srv_conn_info_1\n"));
972 if (ctr1 == NULL) {
973 if (resume_handle_p) {
974 *resume_handle_p = 0;
976 return WERR_OK;
979 *total_entries = 1;
981 ZERO_STRUCTP(ctr1);
983 for (; resume_handle < *total_entries; resume_handle++) {
985 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
986 ctr1->array,
987 struct srvsvc_NetConnInfo1,
988 num_entries+1);
989 if (!ctr1->array) {
990 return WERR_NOMEM;
993 ctr1->array[num_entries].conn_id = *total_entries;
994 ctr1->array[num_entries].conn_type = 0x3;
995 ctr1->array[num_entries].num_open = 1;
996 ctr1->array[num_entries].num_users = 1;
997 ctr1->array[num_entries].conn_time = 3;
998 ctr1->array[num_entries].user = "dummy_user";
999 ctr1->array[num_entries].share = "IPC$";
1001 /* move on to creating next connection */
1002 num_entries++;
1005 ctr1->count = num_entries;
1006 *total_entries = num_entries;
1008 if (resume_handle_p) {
1009 if (*resume_handle_p >= *total_entries) {
1010 *resume_handle_p = 0;
1011 } else {
1012 *resume_handle_p = resume_handle;
1016 return WERR_OK;
1019 /*******************************************************************
1020 _srvsvc_NetFileEnum
1021 *******************************************************************/
1023 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
1024 struct srvsvc_NetFileEnum *r)
1026 TALLOC_CTX *ctx = NULL;
1027 struct srvsvc_NetFileCtr3 *ctr3;
1028 uint32_t resume_hnd = 0;
1029 WERROR werr;
1031 switch (r->in.info_ctr->level) {
1032 case 3:
1033 break;
1034 default:
1035 return WERR_UNKNOWN_LEVEL;
1038 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1039 p->server_info->ptok)) {
1040 DEBUG(1, ("Enumerating files only allowed for "
1041 "administrators\n"));
1042 return WERR_ACCESS_DENIED;
1045 ctx = talloc_tos();
1046 ctr3 = r->in.info_ctr->ctr.ctr3;
1047 if (!ctr3) {
1048 werr = WERR_INVALID_PARAM;
1049 goto done;
1052 /* TODO -- Windows enumerates
1053 (b) active pipes
1054 (c) open directories and files */
1056 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1057 if (!W_ERROR_IS_OK(werr)) {
1058 goto done;
1061 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1062 if (!W_ERROR_IS_OK(werr)) {
1063 goto done;
1066 *r->out.totalentries = ctr3->count;
1067 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1068 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1070 werr = WERR_OK;
1072 done:
1073 return werr;
1076 /*******************************************************************
1077 _srvsvc_NetSrvGetInfo
1078 ********************************************************************/
1080 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1081 struct srvsvc_NetSrvGetInfo *r)
1083 WERROR status = WERR_OK;
1085 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1087 if (!pipe_access_check(p)) {
1088 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1089 return WERR_ACCESS_DENIED;
1092 switch (r->in.level) {
1094 /* Technically level 102 should only be available to
1095 Administrators but there isn't anything super-secret
1096 here, as most of it is made up. */
1098 case 102: {
1099 struct srvsvc_NetSrvInfo102 *info102;
1101 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1102 if (!info102) {
1103 return WERR_NOMEM;
1106 info102->platform_id = PLATFORM_ID_NT;
1107 info102->server_name = global_myname();
1108 info102->version_major = lp_major_announce_version();
1109 info102->version_minor = lp_minor_announce_version();
1110 info102->server_type = lp_default_server_announce();
1111 info102->comment = string_truncate(lp_serverstring(),
1112 MAX_SERVER_STRING_LENGTH);
1113 info102->users = 0xffffffff;
1114 info102->disc = 0xf;
1115 info102->hidden = 0;
1116 info102->announce = 240;
1117 info102->anndelta = 3000;
1118 info102->licenses = 100000;
1119 info102->userpath = "C:\\";
1121 r->out.info->info102 = info102;
1122 break;
1124 case 101: {
1125 struct srvsvc_NetSrvInfo101 *info101;
1127 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1128 if (!info101) {
1129 return WERR_NOMEM;
1132 info101->platform_id = PLATFORM_ID_NT;
1133 info101->server_name = global_myname();
1134 info101->version_major = lp_major_announce_version();
1135 info101->version_minor = lp_minor_announce_version();
1136 info101->server_type = lp_default_server_announce();
1137 info101->comment = string_truncate(lp_serverstring(),
1138 MAX_SERVER_STRING_LENGTH);
1140 r->out.info->info101 = info101;
1141 break;
1143 case 100: {
1144 struct srvsvc_NetSrvInfo100 *info100;
1146 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1147 if (!info100) {
1148 return WERR_NOMEM;
1151 info100->platform_id = PLATFORM_ID_NT;
1152 info100->server_name = global_myname();
1154 r->out.info->info100 = info100;
1156 break;
1158 default:
1159 status = WERR_UNKNOWN_LEVEL;
1160 break;
1163 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1165 return status;
1168 /*******************************************************************
1169 _srvsvc_NetSrvSetInfo
1170 ********************************************************************/
1172 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1173 struct srvsvc_NetSrvSetInfo *r)
1175 WERROR status = WERR_OK;
1177 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1179 /* Set up the net server set info structure. */
1181 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1183 return status;
1186 /*******************************************************************
1187 _srvsvc_NetConnEnum
1188 ********************************************************************/
1190 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1191 struct srvsvc_NetConnEnum *r)
1193 WERROR werr;
1195 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1197 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1198 p->server_info->ptok)) {
1199 DEBUG(1, ("Enumerating connections only allowed for "
1200 "administrators\n"));
1201 return WERR_ACCESS_DENIED;
1204 switch (r->in.info_ctr->level) {
1205 case 0:
1206 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1207 r->in.resume_handle,
1208 r->out.totalentries);
1209 break;
1210 case 1:
1211 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1212 r->in.resume_handle,
1213 r->out.totalentries);
1214 break;
1215 default:
1216 return WERR_UNKNOWN_LEVEL;
1219 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1221 return werr;
1224 /*******************************************************************
1225 _srvsvc_NetSessEnum
1226 ********************************************************************/
1228 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1229 struct srvsvc_NetSessEnum *r)
1231 WERROR werr;
1233 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1235 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
1236 p->server_info->ptok)) {
1237 DEBUG(1, ("Enumerating sessions only allowed for "
1238 "administrators\n"));
1239 return WERR_ACCESS_DENIED;
1242 switch (r->in.info_ctr->level) {
1243 case 0:
1244 werr = init_srv_sess_info_0(p,
1245 r->in.info_ctr->ctr.ctr0,
1246 r->in.resume_handle,
1247 r->out.totalentries);
1248 break;
1249 case 1:
1250 werr = init_srv_sess_info_1(p,
1251 r->in.info_ctr->ctr.ctr1,
1252 r->in.resume_handle,
1253 r->out.totalentries);
1254 break;
1255 default:
1256 return WERR_UNKNOWN_LEVEL;
1259 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1261 return werr;
1264 /*******************************************************************
1265 _srvsvc_NetSessDel
1266 ********************************************************************/
1268 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1269 struct srvsvc_NetSessDel *r)
1271 struct sessionid *session_list;
1272 int num_sessions, snum;
1273 const char *username;
1274 const char *machine;
1275 bool not_root = False;
1276 WERROR werr;
1278 username = r->in.user;
1279 machine = r->in.client;
1281 /* strip leading backslashes if any */
1282 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1283 machine += 2;
1286 num_sessions = list_sessions(p->mem_ctx, &session_list);
1288 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1290 werr = WERR_ACCESS_DENIED;
1292 /* fail out now if you are not root or not a domain admin */
1294 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1295 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1296 DOMAIN_RID_ADMINS))) {
1298 goto done;
1301 for (snum = 0; snum < num_sessions; snum++) {
1303 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1304 strequal(session_list[snum].remote_machine, machine)) {
1306 NTSTATUS ntstat;
1308 if (p->server_info->utok.uid != sec_initial_uid()) {
1309 not_root = True;
1310 become_root();
1313 ntstat = messaging_send(smbd_messaging_context(),
1314 session_list[snum].pid,
1315 MSG_SHUTDOWN, &data_blob_null);
1317 if (NT_STATUS_IS_OK(ntstat))
1318 werr = WERR_OK;
1320 if (not_root)
1321 unbecome_root();
1325 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1327 done:
1329 return werr;
1332 /*******************************************************************
1333 _srvsvc_NetShareEnumAll
1334 ********************************************************************/
1336 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1337 struct srvsvc_NetShareEnumAll *r)
1339 WERROR werr;
1341 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1343 if (!pipe_access_check(p)) {
1344 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1345 return WERR_ACCESS_DENIED;
1348 /* Create the list of shares for the response. */
1349 werr = init_srv_share_info_ctr(p,
1350 r->in.info_ctr,
1351 r->in.resume_handle,
1352 r->out.totalentries,
1353 true);
1355 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1357 return werr;
1360 /*******************************************************************
1361 _srvsvc_NetShareEnum
1362 ********************************************************************/
1364 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1365 struct srvsvc_NetShareEnum *r)
1367 WERROR werr;
1369 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1371 if (!pipe_access_check(p)) {
1372 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1373 return WERR_ACCESS_DENIED;
1376 /* Create the list of shares for the response. */
1377 werr = init_srv_share_info_ctr(p,
1378 r->in.info_ctr,
1379 r->in.resume_handle,
1380 r->out.totalentries,
1381 false);
1383 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1385 return werr;
1388 /*******************************************************************
1389 _srvsvc_NetShareGetInfo
1390 ********************************************************************/
1392 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1393 struct srvsvc_NetShareGetInfo *r)
1395 WERROR status = WERR_OK;
1396 fstring share_name;
1397 int snum;
1398 union srvsvc_NetShareInfo *info = r->out.info;
1400 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1402 fstrcpy(share_name, r->in.share_name);
1404 snum = find_service(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 char *share_name = NULL;
1513 char *comment = NULL;
1514 const char *pathname = NULL;
1515 int type;
1516 int snum;
1517 int ret;
1518 char *path = NULL;
1519 struct security_descriptor *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 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1529 if (!share_name) {
1530 return WERR_NOMEM;
1533 if (r->out.parm_error) {
1534 *r->out.parm_error = 0;
1537 if ( strequal(share_name,"IPC$")
1538 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1539 || strequal(share_name,"global") )
1541 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1542 "modified by a remote user.\n",
1543 share_name ));
1544 return WERR_ACCESS_DENIED;
1547 snum = find_service(share_name);
1549 /* Does this share exist ? */
1550 if (snum < 0)
1551 return WERR_NET_NAME_NOT_FOUND;
1553 /* No change to printer shares. */
1554 if (lp_print_ok(snum))
1555 return WERR_ACCESS_DENIED;
1557 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1559 /* fail out now if you are not root and not a disk op */
1561 if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1562 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1563 "SeDiskOperatorPrivilege privilege needed to modify "
1564 "share %s\n",
1565 (unsigned int)p->server_info->utok.uid,
1566 share_name ));
1567 return WERR_ACCESS_DENIED;
1570 switch (r->in.level) {
1571 case 1:
1572 pathname = talloc_strdup(ctx, lp_pathname(snum));
1573 comment = talloc_strdup(ctx, info->info1->comment);
1574 type = info->info1->type;
1575 psd = NULL;
1576 break;
1577 case 2:
1578 comment = talloc_strdup(ctx, info->info2->comment);
1579 pathname = info->info2->path;
1580 type = info->info2->type;
1581 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1582 0 : info->info2->max_users;
1583 psd = NULL;
1584 break;
1585 #if 0
1586 /* not supported on set but here for completeness */
1587 case 501:
1588 comment = talloc_strdup(ctx, info->info501->comment);
1589 type = info->info501->type;
1590 psd = NULL;
1591 break;
1592 #endif
1593 case 502:
1594 comment = talloc_strdup(ctx, info->info502->comment);
1595 pathname = info->info502->path;
1596 type = info->info502->type;
1597 psd = info->info502->sd_buf.sd;
1598 map_generic_share_sd_bits(psd);
1599 break;
1600 case 1004:
1601 pathname = talloc_strdup(ctx, lp_pathname(snum));
1602 comment = talloc_strdup(ctx, info->info1004->comment);
1603 type = STYPE_DISKTREE;
1604 break;
1605 case 1005:
1606 /* XP re-sets the csc policy even if it wasn't changed by the
1607 user, so we must compare it to see if it's what is set in
1608 smb.conf, so that we can contine other ops like setting
1609 ACLs on a share */
1610 if (((info->info1005->dfs_flags &
1611 SHARE_1005_CSC_POLICY_MASK) >>
1612 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1613 return WERR_OK;
1614 else {
1615 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1616 return WERR_ACCESS_DENIED;
1618 case 1006:
1619 case 1007:
1620 return WERR_ACCESS_DENIED;
1621 case 1501:
1622 pathname = talloc_strdup(ctx, lp_pathname(snum));
1623 comment = talloc_strdup(ctx, lp_comment(snum));
1624 psd = info->info1501->sd;
1625 map_generic_share_sd_bits(psd);
1626 type = STYPE_DISKTREE;
1627 break;
1628 default:
1629 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1630 r->in.level));
1631 return WERR_UNKNOWN_LEVEL;
1634 /* We can only modify disk shares. */
1635 if (type != STYPE_DISKTREE) {
1636 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1637 "disk share\n",
1638 share_name ));
1639 return WERR_ACCESS_DENIED;
1642 if (comment == NULL) {
1643 return WERR_NOMEM;
1646 /* Check if the pathname is valid. */
1647 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1648 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1649 pathname ));
1650 return WERR_OBJECT_PATH_INVALID;
1653 /* Ensure share name, pathname and comment don't contain '"' characters. */
1654 string_replace(share_name, '"', ' ');
1655 string_replace(path, '"', ' ');
1656 string_replace(comment, '"', ' ');
1658 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1659 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1661 /* Only call modify function if something changed. */
1663 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1664 || (lp_max_connections(snum) != max_connections)) {
1665 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1666 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1667 return WERR_ACCESS_DENIED;
1670 command = talloc_asprintf(p->mem_ctx,
1671 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1672 lp_change_share_cmd(),
1673 get_dyn_CONFIGFILE(),
1674 share_name,
1675 path,
1676 comment ? comment : "",
1677 max_connections);
1678 if (!command) {
1679 return WERR_NOMEM;
1682 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1684 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1686 if (is_disk_op)
1687 become_root();
1689 if ( (ret = smbrun(command, NULL)) == 0 ) {
1690 /* Tell everyone we updated smb.conf. */
1691 message_send_all(smbd_messaging_context(),
1692 MSG_SMB_CONF_UPDATED, NULL, 0,
1693 NULL);
1696 if ( is_disk_op )
1697 unbecome_root();
1699 /********* END SeDiskOperatorPrivilege BLOCK *********/
1701 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1702 command, ret ));
1704 TALLOC_FREE(command);
1706 if ( ret != 0 )
1707 return WERR_ACCESS_DENIED;
1708 } else {
1709 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1710 share_name ));
1713 /* Replace SD if changed. */
1714 if (psd) {
1715 struct security_descriptor *old_sd;
1716 size_t sd_size;
1718 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1720 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1721 if (!set_share_security(share_name, psd))
1722 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1723 share_name ));
1727 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1729 return WERR_OK;
1732 /*******************************************************************
1733 _srvsvc_NetShareAdd.
1734 Call 'add_share_command "sharename" "pathname"
1735 "comment" "max connections = "
1736 ********************************************************************/
1738 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1739 struct srvsvc_NetShareAdd *r)
1741 char *command = NULL;
1742 char *share_name = NULL;
1743 char *comment = NULL;
1744 char *pathname = NULL;
1745 int type;
1746 int snum;
1747 int ret;
1748 char *path;
1749 struct security_descriptor *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 = 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 = 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 || !validate_net_name(share_name,
1819 INVALID_SHARENAME_CHARS,
1820 strlen(share_name))) {
1821 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1822 share_name ? share_name : ""));
1823 return WERR_INVALID_NAME;
1826 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1827 || (lp_enable_asu_support() &&
1828 strequal(share_name,"ADMIN$"))) {
1829 return WERR_ACCESS_DENIED;
1832 snum = find_service(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, '"', ' ');
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,
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 if (!set_share_security(share_name, psd)) {
1898 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1899 share_name ));
1904 * We don't call reload_services() here, the message will
1905 * cause this to be done before the next packet is read
1906 * from the client. JRA.
1909 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1911 return WERR_OK;
1914 /*******************************************************************
1915 _srvsvc_NetShareDel
1916 Call "delete share command" with the share name as
1917 a parameter.
1918 ********************************************************************/
1920 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1921 struct srvsvc_NetShareDel *r)
1923 char *command = NULL;
1924 char *share_name = NULL;
1925 int ret;
1926 int snum;
1927 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1928 bool is_disk_op;
1929 struct share_params *params;
1930 TALLOC_CTX *ctx = p->mem_ctx;
1932 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1934 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1935 if (!share_name) {
1936 return WERR_NET_NAME_NOT_FOUND;
1938 if ( strequal(share_name,"IPC$")
1939 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1940 || strequal(share_name,"global") )
1942 return WERR_ACCESS_DENIED;
1945 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1946 return WERR_NO_SUCH_SHARE;
1949 snum = find_service(share_name);
1951 /* No change to printer shares. */
1952 if (lp_print_ok(snum))
1953 return WERR_ACCESS_DENIED;
1955 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1957 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1958 return WERR_ACCESS_DENIED;
1960 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1961 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1962 return WERR_ACCESS_DENIED;
1965 command = talloc_asprintf(ctx,
1966 "%s \"%s\" \"%s\"",
1967 lp_delete_share_cmd(),
1968 get_dyn_CONFIGFILE(),
1969 lp_servicename(snum));
1970 if (!command) {
1971 return WERR_NOMEM;
1974 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1976 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1978 if ( is_disk_op )
1979 become_root();
1981 if ( (ret = smbrun(command, NULL)) == 0 ) {
1982 /* Tell everyone we updated smb.conf. */
1983 message_send_all(smbd_messaging_context(),
1984 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1987 if ( is_disk_op )
1988 unbecome_root();
1990 /********* END SeDiskOperatorPrivilege BLOCK *********/
1992 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1994 if ( ret != 0 )
1995 return WERR_ACCESS_DENIED;
1997 /* Delete the SD in the database. */
1998 delete_share_security(lp_servicename(params->service));
2000 lp_killservice(params->service);
2002 return WERR_OK;
2005 /*******************************************************************
2006 _srvsvc_NetShareDelSticky
2007 ********************************************************************/
2009 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
2010 struct srvsvc_NetShareDelSticky *r)
2012 struct srvsvc_NetShareDel q;
2014 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2016 q.in.server_unc = r->in.server_unc;
2017 q.in.share_name = r->in.share_name;
2018 q.in.reserved = r->in.reserved;
2020 return _srvsvc_NetShareDel(p, &q);
2023 /*******************************************************************
2024 _srvsvc_NetRemoteTOD
2025 ********************************************************************/
2027 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2028 struct srvsvc_NetRemoteTOD *r)
2030 struct srvsvc_NetRemoteTODInfo *tod;
2031 struct tm *t;
2032 time_t unixdate = time(NULL);
2034 /* We do this call first as if we do it *after* the gmtime call
2035 it overwrites the pointed-to values. JRA */
2037 uint32 zone = get_time_zone(unixdate)/60;
2039 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2041 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2042 return WERR_NOMEM;
2044 *r->out.info = tod;
2046 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2048 t = gmtime(&unixdate);
2050 /* set up the */
2051 tod->elapsed = unixdate;
2052 tod->msecs = 0;
2053 tod->hours = t->tm_hour;
2054 tod->mins = t->tm_min;
2055 tod->secs = t->tm_sec;
2056 tod->hunds = 0;
2057 tod->timezone = zone;
2058 tod->tinterval = 10000;
2059 tod->day = t->tm_mday;
2060 tod->month = t->tm_mon + 1;
2061 tod->year = 1900+t->tm_year;
2062 tod->weekday = t->tm_wday;
2064 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2066 return WERR_OK;
2069 /***********************************************************************************
2070 _srvsvc_NetGetFileSecurity
2071 Win9x NT tools get security descriptor.
2072 ***********************************************************************************/
2074 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2075 struct srvsvc_NetGetFileSecurity *r)
2077 struct smb_filename *smb_fname = NULL;
2078 struct security_descriptor *psd = NULL;
2079 size_t sd_size;
2080 fstring servicename;
2081 SMB_STRUCT_STAT st;
2082 NTSTATUS nt_status;
2083 WERROR werr;
2084 connection_struct *conn = NULL;
2085 struct sec_desc_buf *sd_buf = NULL;
2086 files_struct *fsp = NULL;
2087 int snum;
2088 char *oldcwd = NULL;
2090 ZERO_STRUCT(st);
2092 fstrcpy(servicename, r->in.share);
2094 snum = find_service(servicename);
2095 if (snum == -1) {
2096 DEBUG(10, ("Could not find service %s\n", servicename));
2097 werr = WERR_NET_NAME_NOT_FOUND;
2098 goto error_exit;
2101 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2102 lp_pathname(snum), p->server_info,
2103 &oldcwd);
2104 if (!NT_STATUS_IS_OK(nt_status)) {
2105 DEBUG(10, ("create_conn_struct failed: %s\n",
2106 nt_errstr(nt_status)));
2107 werr = ntstatus_to_werror(nt_status);
2108 goto error_exit;
2111 nt_status = filename_convert(talloc_tos(),
2112 conn,
2113 false,
2114 r->in.file,
2116 NULL,
2117 &smb_fname);
2118 if (!NT_STATUS_IS_OK(nt_status)) {
2119 werr = ntstatus_to_werror(nt_status);
2120 goto error_exit;
2123 nt_status = SMB_VFS_CREATE_FILE(
2124 conn, /* conn */
2125 NULL, /* req */
2126 0, /* root_dir_fid */
2127 smb_fname, /* fname */
2128 FILE_READ_ATTRIBUTES, /* access_mask */
2129 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2130 FILE_OPEN, /* create_disposition*/
2131 0, /* create_options */
2132 0, /* file_attributes */
2133 INTERNAL_OPEN_ONLY, /* oplock_request */
2134 0, /* allocation_size */
2135 0, /* private_flags */
2136 NULL, /* sd */
2137 NULL, /* ea_list */
2138 &fsp, /* result */
2139 NULL); /* pinfo */
2141 if (!NT_STATUS_IS_OK(nt_status)) {
2142 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2143 smb_fname_str_dbg(smb_fname)));
2144 werr = ntstatus_to_werror(nt_status);
2145 goto error_exit;
2148 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2149 (OWNER_SECURITY_INFORMATION
2150 |GROUP_SECURITY_INFORMATION
2151 |DACL_SECURITY_INFORMATION), &psd);
2153 if (!NT_STATUS_IS_OK(nt_status)) {
2154 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2155 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2156 werr = ntstatus_to_werror(nt_status);
2157 goto error_exit;
2160 sd_size = ndr_size_security_descriptor(psd, 0);
2162 sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2163 if (!sd_buf) {
2164 werr = WERR_NOMEM;
2165 goto error_exit;
2168 sd_buf->sd_size = sd_size;
2169 sd_buf->sd = psd;
2171 *r->out.sd_buf = sd_buf;
2173 psd->dacl->revision = NT4_ACL_REVISION;
2175 close_file(NULL, fsp, NORMAL_CLOSE);
2176 vfs_ChDir(conn, oldcwd);
2177 conn_free(conn);
2178 werr = WERR_OK;
2179 goto done;
2181 error_exit:
2183 if (fsp) {
2184 close_file(NULL, fsp, NORMAL_CLOSE);
2187 if (oldcwd) {
2188 vfs_ChDir(conn, oldcwd);
2191 if (conn) {
2192 conn_free(conn);
2195 done:
2196 TALLOC_FREE(smb_fname);
2198 return werr;
2201 /***********************************************************************************
2202 _srvsvc_NetSetFileSecurity
2203 Win9x NT tools set security descriptor.
2204 ***********************************************************************************/
2206 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2207 struct srvsvc_NetSetFileSecurity *r)
2209 struct smb_filename *smb_fname = NULL;
2210 fstring servicename;
2211 files_struct *fsp = NULL;
2212 SMB_STRUCT_STAT st;
2213 NTSTATUS nt_status;
2214 WERROR werr;
2215 connection_struct *conn = NULL;
2216 int snum;
2217 char *oldcwd = NULL;
2218 struct security_descriptor *psd = NULL;
2219 uint32_t security_info_sent = 0;
2221 ZERO_STRUCT(st);
2223 fstrcpy(servicename, r->in.share);
2225 snum = find_service(servicename);
2226 if (snum == -1) {
2227 DEBUG(10, ("Could not find service %s\n", servicename));
2228 werr = WERR_NET_NAME_NOT_FOUND;
2229 goto error_exit;
2232 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2233 lp_pathname(snum), p->server_info,
2234 &oldcwd);
2235 if (!NT_STATUS_IS_OK(nt_status)) {
2236 DEBUG(10, ("create_conn_struct failed: %s\n",
2237 nt_errstr(nt_status)));
2238 werr = ntstatus_to_werror(nt_status);
2239 goto error_exit;
2242 nt_status = filename_convert(talloc_tos(),
2243 conn,
2244 false,
2245 r->in.file,
2247 NULL,
2248 &smb_fname);
2249 if (!NT_STATUS_IS_OK(nt_status)) {
2250 werr = ntstatus_to_werror(nt_status);
2251 goto error_exit;
2254 nt_status = SMB_VFS_CREATE_FILE(
2255 conn, /* conn */
2256 NULL, /* req */
2257 0, /* root_dir_fid */
2258 smb_fname, /* fname */
2259 FILE_WRITE_ATTRIBUTES, /* access_mask */
2260 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2261 FILE_OPEN, /* create_disposition*/
2262 0, /* create_options */
2263 0, /* file_attributes */
2264 INTERNAL_OPEN_ONLY, /* oplock_request */
2265 0, /* allocation_size */
2266 0, /* private_flags */
2267 NULL, /* sd */
2268 NULL, /* ea_list */
2269 &fsp, /* result */
2270 NULL); /* pinfo */
2272 if (!NT_STATUS_IS_OK(nt_status)) {
2273 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2274 smb_fname_str_dbg(smb_fname)));
2275 werr = ntstatus_to_werror(nt_status);
2276 goto error_exit;
2279 psd = r->in.sd_buf->sd;
2280 security_info_sent = r->in.securityinformation;
2282 if (psd->owner_sid==0) {
2283 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2285 if (psd->group_sid==0) {
2286 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2288 if (psd->sacl==0) {
2289 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2291 if (psd->dacl==0) {
2292 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2295 /* Convert all the generic bits. */
2296 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2297 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2299 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2300 security_info_sent,
2301 psd);
2303 if (!NT_STATUS_IS_OK(nt_status) ) {
2304 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2305 "on file %s\n", r->in.share));
2306 werr = WERR_ACCESS_DENIED;
2307 goto error_exit;
2310 close_file(NULL, fsp, NORMAL_CLOSE);
2311 vfs_ChDir(conn, oldcwd);
2312 conn_free(conn);
2313 werr = WERR_OK;
2314 goto done;
2316 error_exit:
2318 if (fsp) {
2319 close_file(NULL, fsp, NORMAL_CLOSE);
2322 if (oldcwd) {
2323 vfs_ChDir(conn, oldcwd);
2326 if (conn) {
2327 conn_free(conn);
2330 done:
2331 TALLOC_FREE(smb_fname);
2333 return werr;
2336 /***********************************************************************************
2337 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2338 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2339 These disks would the disks listed by this function.
2340 Users could then create shares relative to these disks. Watch out for moving these disks around.
2341 "Nigel Williams" <nigel@veritas.com>.
2342 ***********************************************************************************/
2344 static const char *server_disks[] = {"C:"};
2346 static uint32 get_server_disk_count(void)
2348 return sizeof(server_disks)/sizeof(server_disks[0]);
2351 static uint32 init_server_disk_enum(uint32 *resume)
2353 uint32 server_disk_count = get_server_disk_count();
2355 /*resume can be an offset into the list for now*/
2357 if(*resume & 0x80000000)
2358 *resume = 0;
2360 if(*resume > server_disk_count)
2361 *resume = server_disk_count;
2363 return server_disk_count - *resume;
2366 static const char *next_server_disk_enum(uint32 *resume)
2368 const char *disk;
2370 if(init_server_disk_enum(resume) == 0)
2371 return NULL;
2373 disk = server_disks[*resume];
2375 (*resume)++;
2377 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2379 return disk;
2382 /********************************************************************
2383 _srvsvc_NetDiskEnum
2384 ********************************************************************/
2386 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2387 struct srvsvc_NetDiskEnum *r)
2389 uint32 i;
2390 const char *disk_name;
2391 TALLOC_CTX *ctx = p->mem_ctx;
2392 WERROR werr;
2393 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2395 werr = WERR_OK;
2397 *r->out.totalentries = init_server_disk_enum(&resume);
2399 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2400 MAX_SERVER_DISK_ENTRIES);
2401 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2403 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2405 r->out.info->count = 0;
2407 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2409 r->out.info->count++;
2411 /*copy disk name into a unicode string*/
2413 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2414 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2417 /* add a terminating null string. Is this there if there is more data to come? */
2419 r->out.info->count++;
2421 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2422 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2424 if (r->out.resume_handle) {
2425 *r->out.resume_handle = resume;
2428 return werr;
2431 /********************************************************************
2432 _srvsvc_NetNameValidate
2433 ********************************************************************/
2435 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2436 struct srvsvc_NetNameValidate *r)
2438 switch (r->in.name_type) {
2439 case 0x9:
2440 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2441 strlen_m(r->in.name)))
2443 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2444 r->in.name));
2445 return WERR_INVALID_NAME;
2447 break;
2449 default:
2450 return WERR_UNKNOWN_LEVEL;
2453 return WERR_OK;
2456 /*******************************************************************
2457 ********************************************************************/
2459 static void enum_file_close_fn( const struct share_mode_entry *e,
2460 const char *sharepath, const char *fname,
2461 void *private_data )
2463 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2464 struct srvsvc_NetFileClose *r =
2465 (struct srvsvc_NetFileClose *)private_data;
2466 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2468 if (fid != r->in.fid) {
2469 return; /* Not this file. */
2472 if (!process_exists(e->pid) ) {
2473 return;
2476 /* Ok - send the close message. */
2477 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2478 sharepath,
2479 share_mode_str(talloc_tos(), 0, e) ));
2481 share_mode_entry_to_message(msg, e);
2483 r->out.result = ntstatus_to_werror(
2484 messaging_send_buf(smbd_messaging_context(),
2485 e->pid, MSG_SMB_CLOSE_FILE,
2486 (uint8 *)msg,
2487 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2490 /********************************************************************
2491 Close a file given a 32-bit file id.
2492 ********************************************************************/
2494 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2496 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2497 bool is_disk_op;
2499 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2501 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2503 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2504 return WERR_ACCESS_DENIED;
2507 /* enum_file_close_fn sends the close message to
2508 * the relevent smbd process. */
2510 r->out.result = WERR_BADFILE;
2511 share_mode_forall( enum_file_close_fn, (void *)r);
2512 return r->out.result;
2515 /********************************************************************
2516 ********************************************************************/
2518 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2520 p->rng_fault_state = True;
2521 return WERR_NOT_SUPPORTED;
2524 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2526 p->rng_fault_state = True;
2527 return WERR_NOT_SUPPORTED;
2530 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2532 p->rng_fault_state = True;
2533 return WERR_NOT_SUPPORTED;
2536 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2538 p->rng_fault_state = True;
2539 return WERR_NOT_SUPPORTED;
2542 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2544 p->rng_fault_state = True;
2545 return WERR_NOT_SUPPORTED;
2548 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2550 p->rng_fault_state = True;
2551 return WERR_NOT_SUPPORTED;
2554 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2556 p->rng_fault_state = True;
2557 return WERR_NOT_SUPPORTED;
2560 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2562 p->rng_fault_state = True;
2563 return WERR_NOT_SUPPORTED;
2566 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2568 p->rng_fault_state = True;
2569 return WERR_NOT_SUPPORTED;
2572 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2574 p->rng_fault_state = True;
2575 return WERR_NOT_SUPPORTED;
2578 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2580 p->rng_fault_state = True;
2581 return WERR_NOT_SUPPORTED;
2584 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2586 p->rng_fault_state = True;
2587 return WERR_NOT_SUPPORTED;
2590 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2592 p->rng_fault_state = True;
2593 return WERR_NOT_SUPPORTED;
2596 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2598 p->rng_fault_state = True;
2599 return WERR_NOT_SUPPORTED;
2602 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2604 p->rng_fault_state = True;
2605 return WERR_NOT_SUPPORTED;
2608 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2610 p->rng_fault_state = True;
2611 return WERR_NOT_SUPPORTED;
2614 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2616 p->rng_fault_state = True;
2617 return WERR_NOT_SUPPORTED;
2620 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2622 p->rng_fault_state = True;
2623 return WERR_NOT_SUPPORTED;
2626 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2628 p->rng_fault_state = True;
2629 return WERR_NOT_SUPPORTED;
2632 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2634 p->rng_fault_state = True;
2635 return WERR_NOT_SUPPORTED;
2638 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2640 p->rng_fault_state = True;
2641 return WERR_NOT_SUPPORTED;
2644 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2646 p->rng_fault_state = True;
2647 return WERR_NOT_SUPPORTED;
2650 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2652 p->rng_fault_state = True;
2653 return WERR_NOT_SUPPORTED;
2656 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2658 p->rng_fault_state = True;
2659 return WERR_NOT_SUPPORTED;
2662 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2664 p->rng_fault_state = True;
2665 return WERR_NOT_SUPPORTED;
2668 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2670 p->rng_fault_state = True;
2671 return WERR_NOT_SUPPORTED;
2674 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2676 p->rng_fault_state = True;
2677 return WERR_NOT_SUPPORTED;
2680 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2682 p->rng_fault_state = True;
2683 return WERR_NOT_SUPPORTED;
2686 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2688 p->rng_fault_state = True;
2689 return WERR_NOT_SUPPORTED;
2692 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2694 p->rng_fault_state = True;
2695 return WERR_NOT_SUPPORTED;
2698 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2700 p->rng_fault_state = True;
2701 return WERR_NOT_SUPPORTED;
2704 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2706 p->rng_fault_state = True;
2707 return WERR_NOT_SUPPORTED;
2710 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2712 p->rng_fault_state = True;
2713 return WERR_NOT_SUPPORTED;
2716 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2718 p->rng_fault_state = True;
2719 return WERR_NOT_SUPPORTED;
2722 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2724 p->rng_fault_state = True;
2725 return WERR_NOT_SUPPORTED;