Fix SRVSVC ShareInfo max_users handling server side.
[Samba/bb.git] / source / rpc_server / srv_srvsvc_nt.c
blob57b42af4e5dc5d75c2e020a61557d45d38325c11
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Guenther Deschner 2008.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
26 #include "includes.h"
28 extern const struct generic_mapping file_generic_mapping;
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
33 #define MAX_SERVER_DISK_ENTRIES 15
35 /***************************/
37 /* oops - this is going to take up a *massive* amount of stack. */
38 /* the UNISTR2s already have 1024 uint16 chars in them... */
40 #define MAX_SESS_ENTRIES 32
42 /***************************/
44 /* oops - this is going to take up a *massive* amount of stack. */
45 /* the UNISTR2s already have 1024 uint16 chars in them... */
46 #define MAX_CONN_ENTRIES 32
48 /* Use for enumerating connections, pipes, & files */
50 struct file_enum_count {
51 TALLOC_CTX *ctx;
52 const char *username;
53 struct srvsvc_NetFileCtr3 *ctr3;
56 struct sess_file_count {
57 struct server_id pid;
58 uid_t uid;
59 int count;
62 /****************************************************************************
63 Count the entries belonging to a service in the connection db.
64 ****************************************************************************/
66 static int pipe_enum_fn( struct db_record *rec, void *p)
68 struct pipe_open_rec prec;
69 struct file_enum_count *fenum = (struct file_enum_count *)p;
70 struct srvsvc_NetFileInfo3 *f;
71 int i = fenum->ctr3->count;
72 char *fullpath = NULL;
73 const char *username;
75 if (rec->value.dsize != sizeof(struct pipe_open_rec))
76 return 0;
78 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
80 if ( !process_exists(prec.pid) ) {
81 return 0;
84 username = uidtoname(prec.uid);
86 if ((fenum->username != NULL)
87 && !strequal(username, fenum->username)) {
88 return 0;
91 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
92 if (!fullpath) {
93 return 1;
96 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
97 struct srvsvc_NetFileInfo3, i+1);
98 if ( !f ) {
99 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
100 return 1;
102 fenum->ctr3->array = f;
104 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
105 (uint32_t)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
106 (FILE_READ_DATA|FILE_WRITE_DATA),
108 fullpath,
109 username);
111 fenum->ctr3->count++;
113 return 0;
116 /*******************************************************************
117 ********************************************************************/
119 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
120 const char *username,
121 struct srvsvc_NetFileCtr3 **ctr3,
122 uint32_t resume )
124 struct file_enum_count fenum;
126 fenum.ctx = ctx;
127 fenum.username = username;
128 fenum.ctr3 = *ctr3;
130 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
131 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
132 "failed\n"));
133 return WERR_NOMEM;
136 *ctr3 = fenum.ctr3;
138 return WERR_OK;
141 /*******************************************************************
142 ********************************************************************/
144 static void enum_file_fn( const struct share_mode_entry *e,
145 const char *sharepath, const char *fname,
146 void *private_data )
148 struct file_enum_count *fenum =
149 (struct file_enum_count *)private_data;
151 struct srvsvc_NetFileInfo3 *f;
152 int i = fenum->ctr3->count;
153 files_struct fsp;
154 struct byte_range_lock *brl;
155 int num_locks = 0;
156 char *fullpath = NULL;
157 uint32 permissions;
158 const char *username;
160 /* If the pid was not found delete the entry from connections.tdb */
162 if ( !process_exists(e->pid) ) {
163 return;
166 username = uidtoname(e->uid);
168 if ((fenum->username != NULL)
169 && !strequal(username, fenum->username)) {
170 return;
173 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
174 struct srvsvc_NetFileInfo3, i+1);
175 if ( !f ) {
176 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
177 return;
179 fenum->ctr3->array = f;
181 /* need to count the number of locks on a file */
183 ZERO_STRUCT( fsp );
184 fsp.file_id = e->id;
186 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
187 num_locks = brl->num_locks;
188 TALLOC_FREE(brl);
191 if ( strcmp( fname, "." ) == 0 ) {
192 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
193 } else {
194 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
195 sharepath, fname );
197 if (!fullpath) {
198 return;
200 string_replace( fullpath, '/', '\\' );
202 /* mask out create (what ever that is) */
203 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
205 /* now fill in the srvsvc_NetFileInfo3 struct */
206 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
207 e->share_file_id,
208 permissions,
209 num_locks,
210 username,
211 fullpath);
212 fenum->ctr3->count++;
215 /*******************************************************************
216 ********************************************************************/
218 static WERROR net_enum_files(TALLOC_CTX *ctx,
219 const char *username,
220 struct srvsvc_NetFileCtr3 **ctr3,
221 uint32_t resume)
223 struct file_enum_count f_enum_cnt;
225 f_enum_cnt.ctx = ctx;
226 f_enum_cnt.username = username;
227 f_enum_cnt.ctr3 = *ctr3;
229 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
231 *ctr3 = f_enum_cnt.ctr3;
233 return WERR_OK;
236 /*******************************************************************
237 Utility function to get the 'type' of a share from an snum.
238 ********************************************************************/
239 static uint32 get_share_type(int snum)
241 /* work out the share type */
242 uint32 type = STYPE_DISKTREE;
244 if (lp_print_ok(snum))
245 type = STYPE_PRINTQ;
246 if (strequal(lp_fstype(snum), "IPC"))
247 type = STYPE_IPC;
248 if (lp_administrative_share(snum))
249 type |= STYPE_HIDDEN;
251 return type;
254 /*******************************************************************
255 Fill in a share info level 0 structure.
256 ********************************************************************/
258 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
260 const char *net_name = lp_servicename(snum);
262 init_srvsvc_NetShareInfo0(r, net_name);
265 /*******************************************************************
266 Fill in a share info level 1 structure.
267 ********************************************************************/
269 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
271 char *net_name = lp_servicename(snum);
272 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
274 if (remark) {
275 remark = standard_sub_conn(p->mem_ctx,
276 p->conn,
277 remark);
280 init_srvsvc_NetShareInfo1(r, net_name,
281 get_share_type(snum),
282 remark ? remark : "");
285 /*******************************************************************
286 Fill in a share info level 2 structure.
287 ********************************************************************/
289 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
291 char *remark = NULL;
292 char *path = NULL;
293 int max_connections = lp_max_connections(snum);
294 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
295 int count = 0;
296 char *net_name = lp_servicename(snum);
298 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
299 if (remark) {
300 remark = standard_sub_conn(p->mem_ctx,
301 p->conn,
302 remark);
304 path = talloc_asprintf(p->mem_ctx,
305 "C:%s", lp_pathname(snum));
307 if (path) {
309 * Change / to \\ so that win2k will see it as a valid path.
310 * This was added to enable use of browsing in win2k add
311 * share dialog.
314 string_replace(path, '/', '\\');
317 count = count_current_connections(net_name, false);
319 init_srvsvc_NetShareInfo2(r, net_name,
320 get_share_type(snum),
321 remark ? remark : "",
323 max_uses,
324 count,
325 path ? path : "",
326 "");
329 /*******************************************************************
330 Map any generic bits to file specific bits.
331 ********************************************************************/
333 static void map_generic_share_sd_bits(SEC_DESC *psd)
335 int i;
336 SEC_ACL *ps_dacl = NULL;
338 if (!psd)
339 return;
341 ps_dacl = psd->dacl;
342 if (!ps_dacl)
343 return;
345 for (i = 0; i < ps_dacl->num_aces; i++) {
346 SEC_ACE *psa = &ps_dacl->aces[i];
347 uint32 orig_mask = psa->access_mask;
349 se_map_generic(&psa->access_mask, &file_generic_mapping);
350 psa->access_mask |= orig_mask;
354 /*******************************************************************
355 Fill in a share info level 501 structure.
356 ********************************************************************/
358 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
360 const char *net_name = lp_servicename(snum);
361 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
363 if (remark) {
364 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
367 init_srvsvc_NetShareInfo501(r, net_name,
368 get_share_type(snum),
369 remark ? remark : "",
370 (lp_csc_policy(snum) << 4));
373 /*******************************************************************
374 Fill in a share info level 502 structure.
375 ********************************************************************/
377 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
379 const char *net_name = lp_servicename(snum);
380 char *path = NULL;
381 SEC_DESC *sd = NULL;
382 size_t sd_size = 0;
383 TALLOC_CTX *ctx = p->mem_ctx;
384 char *remark = talloc_strdup(ctx, lp_comment(snum));;
386 if (remark) {
387 remark = standard_sub_conn(ctx, p->conn, remark);
389 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
390 if (path) {
392 * Change / to \\ so that win2k will see it as a valid path. This was added to
393 * enable use of browsing in win2k add share dialog.
395 string_replace(path, '/', '\\');
398 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
400 init_srvsvc_NetShareInfo502(r, net_name,
401 get_share_type(snum),
402 remark ? remark : "",
404 (uint32_t)-1,
406 path ? path : "",
409 sd);
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 = standard_sub_conn(p->mem_ctx, p->conn, remark);
424 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
427 /***************************************************************************
428 Fill in a share info level 1005 structure.
429 ***************************************************************************/
431 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
433 uint32_t dfs_flags = 0;
435 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
436 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
439 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
441 init_srvsvc_NetShareInfo1005(r, dfs_flags);
444 /***************************************************************************
445 Fill in a share info level 1006 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
450 init_srvsvc_NetShareInfo1006(r, (uint32_t)-1);
453 /***************************************************************************
454 Fill in a share info level 1007 structure.
455 ***************************************************************************/
457 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
459 uint32 flags = 0;
461 init_srvsvc_NetShareInfo1007(r, flags, "");
464 /*******************************************************************
465 Fill in a share info level 1501 structure.
466 ********************************************************************/
468 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
470 SEC_DESC *sd;
471 size_t sd_size;
472 TALLOC_CTX *ctx = p->mem_ctx;
474 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
476 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
479 /*******************************************************************
480 True if it ends in '$'.
481 ********************************************************************/
483 static bool is_hidden_share(int snum)
485 const char *net_name = lp_servicename(snum);
487 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
490 /*******************************************************************
491 Fill in a share info structure.
492 ********************************************************************/
494 static WERROR init_srv_share_info_ctr(pipes_struct *p,
495 struct srvsvc_NetShareInfoCtr *info_ctr,
496 uint32_t *resume_handle_p,
497 uint32_t *total_entries,
498 bool all_shares)
500 int num_entries = 0;
501 int alloc_entries = 0;
502 int num_services = 0;
503 int snum;
504 TALLOC_CTX *ctx = p->mem_ctx;
505 int i = 0;
506 int valid_share_count = 0;
507 union srvsvc_NetShareCtr ctr;
508 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
510 DEBUG(5,("init_srv_share_info_ctr\n"));
512 /* Ensure all the usershares are loaded. */
513 become_root();
514 load_usershare_shares();
515 load_registry_shares();
516 num_services = lp_numservices();
517 unbecome_root();
519 /* Count the number of entries. */
520 for (snum = 0; snum < num_services; snum++) {
521 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
522 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
523 num_entries++;
524 } else {
525 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
529 if (!num_entries || (resume_handle >= num_entries)) {
530 return WERR_OK;
533 /* Calculate alloc entries. */
534 alloc_entries = num_entries - resume_handle;
535 switch (info_ctr->level) {
536 case 0:
537 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
538 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
540 ctr.ctr0->count = alloc_entries;
541 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
542 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
544 for (snum = 0; snum < num_services; snum++) {
545 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
546 (resume_handle <= (i + valid_share_count++)) ) {
547 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
551 break;
553 case 1:
554 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
555 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
557 ctr.ctr1->count = alloc_entries;
558 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
559 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
561 for (snum = 0; snum < num_services; snum++) {
562 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
563 (resume_handle <= (i + valid_share_count++)) ) {
564 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
568 break;
570 case 2:
571 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
572 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
574 ctr.ctr2->count = alloc_entries;
575 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
576 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
578 for (snum = 0; snum < num_services; snum++) {
579 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
580 (resume_handle <= (i + valid_share_count++)) ) {
581 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
585 break;
587 case 501:
588 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
589 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
591 ctr.ctr501->count = alloc_entries;
592 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
593 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
595 for (snum = 0; snum < num_services; snum++) {
596 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
597 (resume_handle <= (i + valid_share_count++)) ) {
598 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
602 break;
604 case 502:
605 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
606 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
608 ctr.ctr502->count = alloc_entries;
609 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
610 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
612 for (snum = 0; snum < num_services; snum++) {
613 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
614 (resume_handle <= (i + valid_share_count++)) ) {
615 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
619 break;
621 case 1004:
622 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
623 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
625 ctr.ctr1004->count = alloc_entries;
626 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
627 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
629 for (snum = 0; snum < num_services; snum++) {
630 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
631 (resume_handle <= (i + valid_share_count++)) ) {
632 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
636 break;
638 case 1005:
639 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
640 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
642 ctr.ctr1005->count = alloc_entries;
643 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
644 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
646 for (snum = 0; snum < num_services; snum++) {
647 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
648 (resume_handle <= (i + valid_share_count++)) ) {
649 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
653 break;
655 case 1006:
656 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
657 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
659 ctr.ctr1006->count = alloc_entries;
660 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
661 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
663 for (snum = 0; snum < num_services; snum++) {
664 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
665 (resume_handle <= (i + valid_share_count++)) ) {
666 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
670 break;
672 case 1007:
673 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
674 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
676 ctr.ctr1007->count = alloc_entries;
677 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
678 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
680 for (snum = 0; snum < num_services; snum++) {
681 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
682 (resume_handle <= (i + valid_share_count++)) ) {
683 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
687 break;
689 case 1501:
690 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
691 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
693 ctr.ctr1501->count = alloc_entries;
694 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
695 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
697 for (snum = 0; snum < num_services; snum++) {
698 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
699 (resume_handle <= (i + valid_share_count++)) ) {
700 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
704 break;
706 default:
707 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
708 info_ctr->level));
709 return WERR_UNKNOWN_LEVEL;
712 *total_entries = alloc_entries;
713 if (resume_handle_p) {
714 if (all_shares) {
715 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
716 } else {
717 *resume_handle_p = num_entries;
721 info_ctr->ctr = ctr;
723 return WERR_OK;
726 /*******************************************************************
727 fill in a sess info level 0 structure.
728 ********************************************************************/
730 static WERROR init_srv_sess_info_0(pipes_struct *p,
731 struct srvsvc_NetSessCtr0 *ctr0,
732 uint32_t *resume_handle_p,
733 uint32_t *total_entries)
735 struct sessionid *session_list;
736 uint32_t num_entries = 0;
737 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
738 *total_entries = list_sessions(p->mem_ctx, &session_list);
740 DEBUG(5,("init_srv_sess_info_0\n"));
742 if (ctr0 == NULL) {
743 if (resume_handle_p) {
744 *resume_handle_p = 0;
746 return WERR_OK;
749 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
751 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
752 ctr0->array,
753 struct srvsvc_NetSessInfo0,
754 num_entries+1);
755 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
757 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
758 session_list[resume_handle].remote_machine);
759 num_entries++;
762 ctr0->count = num_entries;
764 if (resume_handle_p) {
765 if (*resume_handle_p >= *total_entries) {
766 *resume_handle_p = 0;
767 } else {
768 *resume_handle_p = resume_handle;
772 return WERR_OK;
775 /*******************************************************************
776 ********************************************************************/
778 static void sess_file_fn( const struct share_mode_entry *e,
779 const char *sharepath, const char *fname,
780 void *data )
782 struct sess_file_count *sess = (struct sess_file_count *)data;
784 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
785 sess->count++;
788 return;
791 /*******************************************************************
792 ********************************************************************/
794 static int net_count_files( uid_t uid, struct server_id pid )
796 struct sess_file_count s_file_cnt;
798 s_file_cnt.count = 0;
799 s_file_cnt.uid = uid;
800 s_file_cnt.pid = pid;
802 share_mode_forall( sess_file_fn, &s_file_cnt );
804 return s_file_cnt.count;
807 /*******************************************************************
808 fill in a sess info level 1 structure.
809 ********************************************************************/
811 static WERROR init_srv_sess_info_1(pipes_struct *p,
812 struct srvsvc_NetSessCtr1 *ctr1,
813 uint32_t *resume_handle_p,
814 uint32_t *total_entries)
816 struct sessionid *session_list;
817 uint32_t num_entries = 0;
818 time_t now = time(NULL);
819 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
821 ZERO_STRUCTP(ctr1);
823 if (ctr1 == NULL) {
824 if (resume_handle_p) {
825 *resume_handle_p = 0;
827 return WERR_OK;
830 *total_entries = list_sessions(p->mem_ctx, &session_list);
832 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
833 uint32 num_files;
834 uint32 connect_time;
835 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
836 bool guest;
838 if ( !pw ) {
839 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
840 session_list[resume_handle].username));
841 continue;
844 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
845 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
846 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
848 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
849 ctr1->array,
850 struct srvsvc_NetSessInfo1,
851 num_entries+1);
852 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
854 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
855 session_list[resume_handle].remote_machine,
856 session_list[resume_handle].username,
857 num_files,
858 connect_time,
860 guest);
861 num_entries++;
864 ctr1->count = num_entries;
866 if (resume_handle_p) {
867 if (*resume_handle_p >= *total_entries) {
868 *resume_handle_p = 0;
869 } else {
870 *resume_handle_p = resume_handle;
874 return WERR_OK;
877 /*******************************************************************
878 fill in a conn info level 0 structure.
879 ********************************************************************/
881 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
882 uint32_t *resume_handle_p,
883 uint32_t *total_entries)
885 uint32_t num_entries = 0;
886 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
888 DEBUG(5,("init_srv_conn_info_0\n"));
890 if (ctr0 == NULL) {
891 if (resume_handle_p) {
892 *resume_handle_p = 0;
894 return WERR_OK;
897 *total_entries = 1;
899 ZERO_STRUCTP(ctr0);
901 for (; resume_handle < *total_entries && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
903 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
904 ctr0->array,
905 struct srvsvc_NetConnInfo0,
906 num_entries+1);
907 if (!ctr0->array) {
908 return WERR_NOMEM;
911 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
912 (*total_entries));
914 /* move on to creating next connection */
915 num_entries++;
918 ctr0->count = num_entries;
919 *total_entries = num_entries;
921 if (resume_handle_p) {
922 if (*resume_handle_p >= *total_entries) {
923 *resume_handle_p = 0;
924 } else {
925 *resume_handle_p = resume_handle;
929 return WERR_OK;
932 /*******************************************************************
933 fill in a conn info level 1 structure.
934 ********************************************************************/
936 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
937 uint32_t *resume_handle_p,
938 uint32_t *total_entries)
940 uint32_t num_entries = 0;
941 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
943 DEBUG(5,("init_srv_conn_info_1\n"));
945 if (ctr1 == NULL) {
946 if (resume_handle_p) {
947 *resume_handle_p = 0;
949 return WERR_OK;
952 *total_entries = 1;
954 ZERO_STRUCTP(ctr1);
956 for (; (resume_handle < *total_entries) && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
958 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
959 ctr1->array,
960 struct srvsvc_NetConnInfo1,
961 num_entries+1);
962 if (!ctr1->array) {
963 return WERR_NOMEM;
966 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
967 (*total_entries),
968 0x3,
972 "dummy_user",
973 "IPC$");
975 /* move on to creating next connection */
976 num_entries++;
979 ctr1->count = num_entries;
980 *total_entries = num_entries;
982 if (resume_handle_p) {
983 if (*resume_handle_p >= *total_entries) {
984 *resume_handle_p = 0;
985 } else {
986 *resume_handle_p = resume_handle;
990 return WERR_OK;
993 /*******************************************************************
994 _srvsvc_NetFileEnum
995 *******************************************************************/
997 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
998 struct srvsvc_NetFileEnum *r)
1000 TALLOC_CTX *ctx = NULL;
1001 struct srvsvc_NetFileCtr3 *ctr3;
1002 uint32_t resume_hnd = 0;
1003 WERROR werr;
1005 switch (r->in.info_ctr->level) {
1006 case 3:
1007 break;
1008 default:
1009 return WERR_UNKNOWN_LEVEL;
1012 ctx = talloc_tos();
1013 ctr3 = r->in.info_ctr->ctr.ctr3;
1014 if (!ctr3) {
1015 werr = WERR_INVALID_PARAM;
1016 goto done;
1019 /* TODO -- Windows enumerates
1020 (b) active pipes
1021 (c) open directories and files */
1023 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1024 if (!W_ERROR_IS_OK(werr)) {
1025 goto done;
1028 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1029 if (!W_ERROR_IS_OK(werr)) {
1030 goto done;
1033 *r->out.totalentries = ctr3->count;
1034 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1035 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1037 werr = WERR_OK;
1039 done:
1040 return werr;
1043 /*******************************************************************
1044 _srvsvc_NetSrvGetInfo
1045 ********************************************************************/
1047 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1048 struct srvsvc_NetSrvGetInfo *r)
1050 WERROR status = WERR_OK;
1052 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1054 if (!pipe_access_check(p)) {
1055 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1056 return WERR_ACCESS_DENIED;
1059 switch (r->in.level) {
1061 /* Technically level 102 should only be available to
1062 Administrators but there isn't anything super-secret
1063 here, as most of it is made up. */
1065 case 102: {
1066 struct srvsvc_NetSrvInfo102 *info102;
1068 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1069 if (!info102) {
1070 return WERR_NOMEM;
1073 init_srvsvc_NetSrvInfo102(info102,
1074 PLATFORM_ID_NT,
1075 global_myname(),
1076 lp_major_announce_version(),
1077 lp_minor_announce_version(),
1078 lp_default_server_announce(),
1079 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1080 0xffffffff, /* users */
1081 0xf, /* disc */
1082 0, /* hidden */
1083 240, /* announce */
1084 3000, /* announce delta */
1085 100000, /* licenses */
1086 "c:\\"); /* user path */
1087 r->out.info->info102 = info102;
1088 break;
1090 case 101: {
1091 struct srvsvc_NetSrvInfo101 *info101;
1093 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1094 if (!info101) {
1095 return WERR_NOMEM;
1098 init_srvsvc_NetSrvInfo101(info101,
1099 PLATFORM_ID_NT,
1100 global_myname(),
1101 lp_major_announce_version(),
1102 lp_minor_announce_version(),
1103 lp_default_server_announce(),
1104 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1105 r->out.info->info101 = info101;
1106 break;
1108 case 100: {
1109 struct srvsvc_NetSrvInfo100 *info100;
1111 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1112 if (!info100) {
1113 return WERR_NOMEM;
1116 init_srvsvc_NetSrvInfo100(info100,
1117 PLATFORM_ID_NT,
1118 global_myname());
1119 r->out.info->info100 = info100;
1121 break;
1123 default:
1124 status = WERR_UNKNOWN_LEVEL;
1125 break;
1128 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1130 return status;
1133 /*******************************************************************
1134 _srvsvc_NetSrvSetInfo
1135 ********************************************************************/
1137 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1138 struct srvsvc_NetSrvSetInfo *r)
1140 WERROR status = WERR_OK;
1142 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1144 /* Set up the net server set info structure. */
1146 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1148 return status;
1151 /*******************************************************************
1152 _srvsvc_NetConnEnum
1153 ********************************************************************/
1155 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1156 struct srvsvc_NetConnEnum *r)
1158 WERROR werr;
1160 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1162 switch (r->in.info_ctr->level) {
1163 case 0:
1164 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1165 r->in.resume_handle,
1166 r->out.totalentries);
1167 break;
1168 case 1:
1169 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1170 r->in.resume_handle,
1171 r->out.totalentries);
1172 break;
1173 default:
1174 return WERR_UNKNOWN_LEVEL;
1177 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1179 return werr;
1182 /*******************************************************************
1183 _srvsvc_NetSessEnum
1184 ********************************************************************/
1186 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1187 struct srvsvc_NetSessEnum *r)
1189 WERROR werr;
1191 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1193 switch (r->in.info_ctr->level) {
1194 case 0:
1195 werr = init_srv_sess_info_0(p,
1196 r->in.info_ctr->ctr.ctr0,
1197 r->in.resume_handle,
1198 r->out.totalentries);
1199 break;
1200 case 1:
1201 werr = init_srv_sess_info_1(p,
1202 r->in.info_ctr->ctr.ctr1,
1203 r->in.resume_handle,
1204 r->out.totalentries);
1205 break;
1206 default:
1207 return WERR_UNKNOWN_LEVEL;
1210 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1212 return werr;
1215 /*******************************************************************
1216 _srvsvc_NetSessDel
1217 ********************************************************************/
1219 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1220 struct srvsvc_NetSessDel *r)
1222 struct sessionid *session_list;
1223 struct current_user user;
1224 int num_sessions, snum;
1225 const char *username;
1226 const char *machine;
1227 bool not_root = False;
1228 WERROR werr;
1230 username = r->in.user;
1231 machine = r->in.client;
1233 /* strip leading backslashes if any */
1234 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1235 machine += 2;
1238 num_sessions = list_sessions(p->mem_ctx, &session_list);
1240 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1242 werr = WERR_ACCESS_DENIED;
1244 get_current_user(&user, p);
1246 /* fail out now if you are not root or not a domain admin */
1248 if ((user.ut.uid != sec_initial_uid()) &&
1249 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1251 goto done;
1254 for (snum = 0; snum < num_sessions; snum++) {
1256 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1257 strequal(session_list[snum].remote_machine, machine)) {
1259 NTSTATUS ntstat;
1261 if (user.ut.uid != sec_initial_uid()) {
1262 not_root = True;
1263 become_root();
1266 ntstat = messaging_send(smbd_messaging_context(),
1267 session_list[snum].pid,
1268 MSG_SHUTDOWN, &data_blob_null);
1270 if (NT_STATUS_IS_OK(ntstat))
1271 werr = WERR_OK;
1273 if (not_root)
1274 unbecome_root();
1278 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1280 done:
1282 return werr;
1285 /*******************************************************************
1286 _srvsvc_NetShareEnumAll
1287 ********************************************************************/
1289 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1290 struct srvsvc_NetShareEnumAll *r)
1292 WERROR werr;
1294 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1296 if (!pipe_access_check(p)) {
1297 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1298 return WERR_ACCESS_DENIED;
1301 /* Create the list of shares for the response. */
1302 werr = init_srv_share_info_ctr(p,
1303 r->in.info_ctr,
1304 r->in.resume_handle,
1305 r->out.totalentries,
1306 true);
1308 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1310 return werr;
1313 /*******************************************************************
1314 _srvsvc_NetShareEnum
1315 ********************************************************************/
1317 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1318 struct srvsvc_NetShareEnum *r)
1320 WERROR werr;
1322 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1324 if (!pipe_access_check(p)) {
1325 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1326 return WERR_ACCESS_DENIED;
1329 /* Create the list of shares for the response. */
1330 werr = init_srv_share_info_ctr(p,
1331 r->in.info_ctr,
1332 r->in.resume_handle,
1333 r->out.totalentries,
1334 false);
1336 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1338 return werr;
1341 /*******************************************************************
1342 _srvsvc_NetShareGetInfo
1343 ********************************************************************/
1345 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1346 struct srvsvc_NetShareGetInfo *r)
1348 WERROR status = WERR_OK;
1349 fstring share_name;
1350 int snum;
1351 union srvsvc_NetShareInfo *info = r->out.info;
1353 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1355 fstrcpy(share_name, r->in.share_name);
1357 snum = find_service(share_name);
1358 if (snum < 0) {
1359 return WERR_INVALID_NAME;
1362 switch (r->in.level) {
1363 case 0:
1364 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1365 W_ERROR_HAVE_NO_MEMORY(info->info0);
1366 init_srv_share_info_0(p, info->info0, snum);
1367 break;
1368 case 1:
1369 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1370 W_ERROR_HAVE_NO_MEMORY(info->info1);
1371 init_srv_share_info_1(p, info->info1, snum);
1372 break;
1373 case 2:
1374 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1375 W_ERROR_HAVE_NO_MEMORY(info->info2);
1376 init_srv_share_info_2(p, info->info2, snum);
1377 break;
1378 case 501:
1379 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1380 W_ERROR_HAVE_NO_MEMORY(info->info501);
1381 init_srv_share_info_501(p, info->info501, snum);
1382 break;
1383 case 502:
1384 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1385 W_ERROR_HAVE_NO_MEMORY(info->info502);
1386 init_srv_share_info_502(p, info->info502, snum);
1387 break;
1388 case 1004:
1389 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1390 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1391 init_srv_share_info_1004(p, info->info1004, snum);
1392 break;
1393 case 1005:
1394 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1395 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1396 init_srv_share_info_1005(p, info->info1005, snum);
1397 break;
1398 case 1006:
1399 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1400 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1401 init_srv_share_info_1006(p, info->info1006, snum);
1402 break;
1403 case 1007:
1404 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1405 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1406 init_srv_share_info_1007(p, info->info1007, snum);
1407 break;
1408 case 1501:
1409 init_srv_share_info_1501(p, info->info1501, snum);
1410 break;
1411 default:
1412 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1413 r->in.level));
1414 status = WERR_UNKNOWN_LEVEL;
1415 break;
1418 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1420 return status;
1423 /*******************************************************************
1424 Check a given DOS pathname is valid for a share.
1425 ********************************************************************/
1427 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1429 char *ptr = NULL;
1431 if (!dos_pathname) {
1432 return NULL;
1435 ptr = talloc_strdup(ctx, dos_pathname);
1436 if (!ptr) {
1437 return NULL;
1439 /* Convert any '\' paths to '/' */
1440 unix_format(ptr);
1441 ptr = unix_clean_name(ctx, ptr);
1442 if (!ptr) {
1443 return NULL;
1446 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1447 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1448 ptr += 2;
1450 /* Only absolute paths allowed. */
1451 if (*ptr != '/')
1452 return NULL;
1454 return ptr;
1457 /*******************************************************************
1458 _srvsvc_NetShareSetInfo. Modify share details.
1459 ********************************************************************/
1461 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1462 struct srvsvc_NetShareSetInfo *r)
1464 struct current_user user;
1465 char *command = NULL;
1466 char *share_name = NULL;
1467 char *comment = NULL;
1468 const char *pathname = NULL;
1469 int type;
1470 int snum;
1471 int ret;
1472 char *path = NULL;
1473 SEC_DESC *psd = NULL;
1474 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1475 bool is_disk_op = False;
1476 int max_connections = 0;
1477 TALLOC_CTX *ctx = p->mem_ctx;
1478 union srvsvc_NetShareInfo *info = r->in.info;
1480 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1482 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1483 if (!share_name) {
1484 return WERR_NOMEM;
1487 if (r->out.parm_error) {
1488 *r->out.parm_error = 0;
1491 if ( strequal(share_name,"IPC$")
1492 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1493 || strequal(share_name,"global") )
1495 return WERR_ACCESS_DENIED;
1498 snum = find_service(share_name);
1500 /* Does this share exist ? */
1501 if (snum < 0)
1502 return WERR_NET_NAME_NOT_FOUND;
1504 /* No change to printer shares. */
1505 if (lp_print_ok(snum))
1506 return WERR_ACCESS_DENIED;
1508 get_current_user(&user,p);
1510 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1512 /* fail out now if you are not root and not a disk op */
1514 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1515 return WERR_ACCESS_DENIED;
1517 switch (r->in.level) {
1518 case 1:
1519 pathname = talloc_strdup(ctx, lp_pathname(snum));
1520 comment = talloc_strdup(ctx, info->info1->comment);
1521 type = info->info1->type;
1522 psd = NULL;
1523 break;
1524 case 2:
1525 comment = talloc_strdup(ctx, info->info2->comment);
1526 pathname = info->info2->path;
1527 type = info->info2->type;
1528 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1529 0 : info->info2->max_users;
1530 psd = NULL;
1531 break;
1532 #if 0
1533 /* not supported on set but here for completeness */
1534 case 501:
1535 comment = talloc_strdup(ctx, info->info501->comment);
1536 type = info->info501->type;
1537 psd = NULL;
1538 break;
1539 #endif
1540 case 502:
1541 comment = talloc_strdup(ctx, info->info502->comment);
1542 pathname = info->info502->path;
1543 type = info->info502->type;
1544 psd = info->info502->sd;
1545 map_generic_share_sd_bits(psd);
1546 break;
1547 case 1004:
1548 pathname = talloc_strdup(ctx, lp_pathname(snum));
1549 comment = talloc_strdup(ctx, info->info1004->comment);
1550 type = STYPE_DISKTREE;
1551 break;
1552 case 1005:
1553 /* XP re-sets the csc policy even if it wasn't changed by the
1554 user, so we must compare it to see if it's what is set in
1555 smb.conf, so that we can contine other ops like setting
1556 ACLs on a share */
1557 if (((info->info1005->dfs_flags &
1558 SHARE_1005_CSC_POLICY_MASK) >>
1559 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1560 return WERR_OK;
1561 else {
1562 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1563 return WERR_ACCESS_DENIED;
1565 case 1006:
1566 case 1007:
1567 return WERR_ACCESS_DENIED;
1568 case 1501:
1569 pathname = talloc_strdup(ctx, lp_pathname(snum));
1570 comment = talloc_strdup(ctx, lp_comment(snum));
1571 psd = info->info1501->sd;
1572 map_generic_share_sd_bits(psd);
1573 type = STYPE_DISKTREE;
1574 break;
1575 default:
1576 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1577 r->in.level));
1578 return WERR_UNKNOWN_LEVEL;
1581 /* We can only modify disk shares. */
1582 if (type != STYPE_DISKTREE)
1583 return WERR_ACCESS_DENIED;
1585 if (comment == NULL) {
1586 return WERR_NOMEM;
1589 /* Check if the pathname is valid. */
1590 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1591 return WERR_OBJECT_PATH_INVALID;
1593 /* Ensure share name, pathname and comment don't contain '"' characters. */
1594 string_replace(share_name, '"', ' ');
1595 string_replace(path, '"', ' ');
1596 string_replace(comment, '"', ' ');
1598 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1599 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1601 /* Only call modify function if something changed. */
1603 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1604 || (lp_max_connections(snum) != max_connections)) {
1605 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1606 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1607 return WERR_ACCESS_DENIED;
1610 command = talloc_asprintf(p->mem_ctx,
1611 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1612 lp_change_share_cmd(),
1613 get_dyn_CONFIGFILE(),
1614 share_name,
1615 path,
1616 comment ? comment : "",
1617 max_connections);
1618 if (!command) {
1619 return WERR_NOMEM;
1622 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1624 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1626 if (is_disk_op)
1627 become_root();
1629 if ( (ret = smbrun(command, NULL)) == 0 ) {
1630 /* Tell everyone we updated smb.conf. */
1631 message_send_all(smbd_messaging_context(),
1632 MSG_SMB_CONF_UPDATED, NULL, 0,
1633 NULL);
1636 if ( is_disk_op )
1637 unbecome_root();
1639 /********* END SeDiskOperatorPrivilege BLOCK *********/
1641 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1642 command, ret ));
1644 TALLOC_FREE(command);
1646 if ( ret != 0 )
1647 return WERR_ACCESS_DENIED;
1648 } else {
1649 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1650 share_name ));
1653 /* Replace SD if changed. */
1654 if (psd) {
1655 SEC_DESC *old_sd;
1656 size_t sd_size;
1658 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1660 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1661 if (!set_share_security(share_name, psd))
1662 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1663 share_name ));
1667 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1669 return WERR_OK;
1672 /*******************************************************************
1673 _srvsvc_NetShareAdd.
1674 Call 'add_share_command "sharename" "pathname"
1675 "comment" "max connections = "
1676 ********************************************************************/
1678 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1679 struct srvsvc_NetShareAdd *r)
1681 struct current_user user;
1682 char *command = NULL;
1683 char *share_name = NULL;
1684 char *comment = NULL;
1685 char *pathname = NULL;
1686 int type;
1687 int snum;
1688 int ret;
1689 char *path;
1690 SEC_DESC *psd = NULL;
1691 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1692 bool is_disk_op;
1693 int max_connections = 0;
1694 TALLOC_CTX *ctx = p->mem_ctx;
1696 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1698 *r->out.parm_error = 0;
1700 get_current_user(&user,p);
1702 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1704 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1705 return WERR_ACCESS_DENIED;
1707 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1708 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1709 return WERR_ACCESS_DENIED;
1712 switch (r->in.level) {
1713 case 0:
1714 /* No path. Not enough info in a level 0 to do anything. */
1715 return WERR_ACCESS_DENIED;
1716 case 1:
1717 /* Not enough info in a level 1 to do anything. */
1718 return WERR_ACCESS_DENIED;
1719 case 2:
1720 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1721 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1722 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1723 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1724 0 : r->in.info->info2->max_users;
1725 type = r->in.info->info2->type;
1726 break;
1727 case 501:
1728 /* No path. Not enough info in a level 501 to do anything. */
1729 return WERR_ACCESS_DENIED;
1730 case 502:
1731 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1732 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1733 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1734 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1735 0 : r->in.info->info502->max_users;
1736 type = r->in.info->info502->type;
1737 psd = r->in.info->info502->sd;
1738 map_generic_share_sd_bits(psd);
1739 break;
1741 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1743 case 1004:
1744 case 1005:
1745 case 1006:
1746 case 1007:
1747 return WERR_ACCESS_DENIED;
1748 case 1501:
1749 /* DFS only level. */
1750 return WERR_ACCESS_DENIED;
1751 default:
1752 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1753 r->in.level));
1754 return WERR_UNKNOWN_LEVEL;
1757 /* check for invalid share names */
1759 if (!share_name || !validate_net_name(share_name,
1760 INVALID_SHARENAME_CHARS,
1761 strlen(share_name))) {
1762 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1763 share_name ? share_name : ""));
1764 return WERR_INVALID_NAME;
1767 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1768 || (lp_enable_asu_support() &&
1769 strequal(share_name,"ADMIN$"))) {
1770 return WERR_ACCESS_DENIED;
1773 snum = find_service(share_name);
1775 /* Share already exists. */
1776 if (snum >= 0) {
1777 return WERR_ALREADY_EXISTS;
1780 /* We can only add disk shares. */
1781 if (type != STYPE_DISKTREE) {
1782 return WERR_ACCESS_DENIED;
1785 /* Check if the pathname is valid. */
1786 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1787 return WERR_OBJECT_PATH_INVALID;
1790 /* Ensure share name, pathname and comment don't contain '"' characters. */
1791 string_replace(share_name, '"', ' ');
1792 string_replace(path, '"', ' ');
1793 if (comment) {
1794 string_replace(comment, '"', ' ');
1797 command = talloc_asprintf(ctx,
1798 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1799 lp_add_share_cmd(),
1800 get_dyn_CONFIGFILE(),
1801 share_name,
1802 path,
1803 comment ? comment : "",
1804 max_connections);
1805 if (!command) {
1806 return WERR_NOMEM;
1809 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1811 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1813 if ( is_disk_op )
1814 become_root();
1816 /* FIXME: use libnetconf here - gd */
1818 if ( (ret = smbrun(command, NULL)) == 0 ) {
1819 /* Tell everyone we updated smb.conf. */
1820 message_send_all(smbd_messaging_context(),
1821 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1824 if ( is_disk_op )
1825 unbecome_root();
1827 /********* END SeDiskOperatorPrivilege BLOCK *********/
1829 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1830 command, ret ));
1832 TALLOC_FREE(command);
1834 if ( ret != 0 )
1835 return WERR_ACCESS_DENIED;
1837 if (psd) {
1838 if (!set_share_security(share_name, psd)) {
1839 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1840 share_name ));
1845 * We don't call reload_services() here, the message will
1846 * cause this to be done before the next packet is read
1847 * from the client. JRA.
1850 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1852 return WERR_OK;
1855 /*******************************************************************
1856 _srvsvc_NetShareDel
1857 Call "delete share command" with the share name as
1858 a parameter.
1859 ********************************************************************/
1861 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1862 struct srvsvc_NetShareDel *r)
1864 struct current_user user;
1865 char *command = NULL;
1866 char *share_name = NULL;
1867 int ret;
1868 int snum;
1869 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1870 bool is_disk_op;
1871 struct share_params *params;
1872 TALLOC_CTX *ctx = p->mem_ctx;
1874 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1876 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1877 if (!share_name) {
1878 return WERR_NET_NAME_NOT_FOUND;
1880 if ( strequal(share_name,"IPC$")
1881 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1882 || strequal(share_name,"global") )
1884 return WERR_ACCESS_DENIED;
1887 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1888 return WERR_NO_SUCH_SHARE;
1891 snum = find_service(share_name);
1893 /* No change to printer shares. */
1894 if (lp_print_ok(snum))
1895 return WERR_ACCESS_DENIED;
1897 get_current_user(&user,p);
1899 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1901 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1902 return WERR_ACCESS_DENIED;
1904 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1905 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1906 return WERR_ACCESS_DENIED;
1909 command = talloc_asprintf(ctx,
1910 "%s \"%s\" \"%s\"",
1911 lp_delete_share_cmd(),
1912 get_dyn_CONFIGFILE(),
1913 lp_servicename(snum));
1914 if (!command) {
1915 return WERR_NOMEM;
1918 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1920 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1922 if ( is_disk_op )
1923 become_root();
1925 if ( (ret = smbrun(command, NULL)) == 0 ) {
1926 /* Tell everyone we updated smb.conf. */
1927 message_send_all(smbd_messaging_context(),
1928 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1931 if ( is_disk_op )
1932 unbecome_root();
1934 /********* END SeDiskOperatorPrivilege BLOCK *********/
1936 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1938 if ( ret != 0 )
1939 return WERR_ACCESS_DENIED;
1941 /* Delete the SD in the database. */
1942 delete_share_security(lp_servicename(params->service));
1944 lp_killservice(params->service);
1946 return WERR_OK;
1949 /*******************************************************************
1950 _srvsvc_NetShareDelSticky
1951 ********************************************************************/
1953 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1954 struct srvsvc_NetShareDelSticky *r)
1956 struct srvsvc_NetShareDel q;
1958 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1960 q.in.server_unc = r->in.server_unc;
1961 q.in.share_name = r->in.share_name;
1962 q.in.reserved = r->in.reserved;
1964 return _srvsvc_NetShareDel(p, &q);
1967 /*******************************************************************
1968 _srvsvc_NetRemoteTOD
1969 ********************************************************************/
1971 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1972 struct srvsvc_NetRemoteTOD *r)
1974 struct srvsvc_NetRemoteTODInfo *tod;
1975 struct tm *t;
1976 time_t unixdate = time(NULL);
1978 /* We do this call first as if we do it *after* the gmtime call
1979 it overwrites the pointed-to values. JRA */
1981 uint32 zone = get_time_zone(unixdate)/60;
1983 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1985 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1986 return WERR_NOMEM;
1988 *r->out.info = tod;
1990 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1992 t = gmtime(&unixdate);
1994 /* set up the */
1995 init_srvsvc_NetRemoteTODInfo(tod,
1996 unixdate,
1998 t->tm_hour,
1999 t->tm_min,
2000 t->tm_sec,
2002 zone,
2003 10000,
2004 t->tm_mday,
2005 t->tm_mon + 1,
2006 1900+t->tm_year,
2007 t->tm_wday);
2009 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2011 return WERR_OK;
2014 /***********************************************************************************
2015 _srvsvc_NetGetFileSecurity
2016 Win9x NT tools get security descriptor.
2017 ***********************************************************************************/
2019 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2020 struct srvsvc_NetGetFileSecurity *r)
2022 SEC_DESC *psd = NULL;
2023 size_t sd_size;
2024 DATA_BLOB null_pw;
2025 char *filename_in = NULL;
2026 char *filename = NULL;
2027 char *qualname = NULL;
2028 SMB_STRUCT_STAT st;
2029 NTSTATUS nt_status;
2030 WERROR werr;
2031 struct current_user user;
2032 connection_struct *conn = NULL;
2033 bool became_user = False;
2034 TALLOC_CTX *ctx = p->mem_ctx;
2035 struct sec_desc_buf *sd_buf;
2037 ZERO_STRUCT(st);
2039 werr = WERR_OK;
2041 qualname = talloc_strdup(ctx, r->in.share);
2042 if (!qualname) {
2043 werr = WERR_ACCESS_DENIED;
2044 goto error_exit;
2047 /* Null password is ok - we are already an authenticated user... */
2048 null_pw = data_blob_null;
2050 get_current_user(&user, p);
2052 become_root();
2053 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2054 unbecome_root();
2056 if (conn == NULL) {
2057 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2058 qualname));
2059 werr = ntstatus_to_werror(nt_status);
2060 goto error_exit;
2063 if (!become_user(conn, conn->vuid)) {
2064 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2065 werr = WERR_ACCESS_DENIED;
2066 goto error_exit;
2068 became_user = True;
2070 filename_in = talloc_strdup(ctx, r->in.file);
2071 if (!filename_in) {
2072 werr = WERR_ACCESS_DENIED;
2073 goto error_exit;
2076 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2077 if (!NT_STATUS_IS_OK(nt_status)) {
2078 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2079 filename));
2080 werr = WERR_ACCESS_DENIED;
2081 goto error_exit;
2084 nt_status = check_name(conn, filename);
2085 if (!NT_STATUS_IS_OK(nt_status)) {
2086 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2087 filename));
2088 werr = WERR_ACCESS_DENIED;
2089 goto error_exit;
2092 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2093 (OWNER_SECURITY_INFORMATION
2094 |GROUP_SECURITY_INFORMATION
2095 |DACL_SECURITY_INFORMATION), &psd);
2097 if (!NT_STATUS_IS_OK(nt_status)) {
2098 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2099 filename));
2100 werr = ntstatus_to_werror(nt_status);
2101 goto error_exit;
2104 sd_size = ndr_size_security_descriptor(psd, 0);
2106 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2107 if (!sd_buf) {
2108 werr = WERR_NOMEM;
2109 goto error_exit;
2112 sd_buf->sd_size = sd_size;
2113 sd_buf->sd = psd;
2115 *r->out.sd_buf = sd_buf;
2117 psd->dacl->revision = NT4_ACL_REVISION;
2119 unbecome_user();
2120 close_cnum(conn, user.vuid);
2121 return werr;
2123 error_exit:
2125 if (became_user)
2126 unbecome_user();
2128 if (conn)
2129 close_cnum(conn, user.vuid);
2131 return werr;
2134 /***********************************************************************************
2135 _srvsvc_NetSetFileSecurity
2136 Win9x NT tools set security descriptor.
2137 ***********************************************************************************/
2139 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2140 struct srvsvc_NetSetFileSecurity *r)
2142 char *filename_in = NULL;
2143 char *filename = NULL;
2144 char *qualname = NULL;
2145 DATA_BLOB null_pw;
2146 files_struct *fsp = NULL;
2147 SMB_STRUCT_STAT st;
2148 NTSTATUS nt_status;
2149 WERROR werr;
2150 struct current_user user;
2151 connection_struct *conn = NULL;
2152 bool became_user = False;
2153 TALLOC_CTX *ctx = p->mem_ctx;
2155 ZERO_STRUCT(st);
2157 werr = WERR_OK;
2159 qualname = talloc_strdup(ctx, r->in.share);
2160 if (!qualname) {
2161 werr = WERR_ACCESS_DENIED;
2162 goto error_exit;
2165 /* Null password is ok - we are already an authenticated user... */
2166 null_pw = data_blob_null;
2168 get_current_user(&user, p);
2170 become_root();
2171 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2172 unbecome_root();
2174 if (conn == NULL) {
2175 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2176 werr = ntstatus_to_werror(nt_status);
2177 goto error_exit;
2180 if (!become_user(conn, conn->vuid)) {
2181 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2182 werr = WERR_ACCESS_DENIED;
2183 goto error_exit;
2185 became_user = True;
2187 filename_in = talloc_strdup(ctx, r->in.file);
2188 if (!filename_in) {
2189 werr = WERR_ACCESS_DENIED;
2190 goto error_exit;
2193 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2194 if (!NT_STATUS_IS_OK(nt_status)) {
2195 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2196 werr = WERR_ACCESS_DENIED;
2197 goto error_exit;
2200 nt_status = check_name(conn, filename);
2201 if (!NT_STATUS_IS_OK(nt_status)) {
2202 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2203 werr = WERR_ACCESS_DENIED;
2204 goto error_exit;
2207 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2209 if ( !NT_STATUS_IS_OK(nt_status) ) {
2210 /* Perhaps it is a directory */
2211 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2212 nt_status = open_directory(conn, NULL, filename, &st,
2213 FILE_READ_ATTRIBUTES,
2214 FILE_SHARE_READ|FILE_SHARE_WRITE,
2215 FILE_OPEN,
2217 FILE_ATTRIBUTE_DIRECTORY,
2218 NULL, &fsp);
2220 if ( !NT_STATUS_IS_OK(nt_status) ) {
2221 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2222 werr = ntstatus_to_werror(nt_status);
2223 goto error_exit;
2227 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2228 r->in.securityinformation,
2229 r->in.sd_buf->sd);
2231 if (!NT_STATUS_IS_OK(nt_status) ) {
2232 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2233 werr = WERR_ACCESS_DENIED;
2234 goto error_exit;
2237 close_file(fsp, NORMAL_CLOSE);
2238 unbecome_user();
2239 close_cnum(conn, user.vuid);
2240 return werr;
2242 error_exit:
2244 if(fsp) {
2245 close_file(fsp, NORMAL_CLOSE);
2248 if (became_user) {
2249 unbecome_user();
2252 if (conn) {
2253 close_cnum(conn, user.vuid);
2256 return werr;
2259 /***********************************************************************************
2260 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2261 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2262 These disks would the disks listed by this function.
2263 Users could then create shares relative to these disks. Watch out for moving these disks around.
2264 "Nigel Williams" <nigel@veritas.com>.
2265 ***********************************************************************************/
2267 static const char *server_disks[] = {"C:"};
2269 static uint32 get_server_disk_count(void)
2271 return sizeof(server_disks)/sizeof(server_disks[0]);
2274 static uint32 init_server_disk_enum(uint32 *resume)
2276 uint32 server_disk_count = get_server_disk_count();
2278 /*resume can be an offset into the list for now*/
2280 if(*resume & 0x80000000)
2281 *resume = 0;
2283 if(*resume > server_disk_count)
2284 *resume = server_disk_count;
2286 return server_disk_count - *resume;
2289 static const char *next_server_disk_enum(uint32 *resume)
2291 const char *disk;
2293 if(init_server_disk_enum(resume) == 0)
2294 return NULL;
2296 disk = server_disks[*resume];
2298 (*resume)++;
2300 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2302 return disk;
2305 /********************************************************************
2306 _srvsvc_NetDiskEnum
2307 ********************************************************************/
2309 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2310 struct srvsvc_NetDiskEnum *r)
2312 uint32 i;
2313 const char *disk_name;
2314 TALLOC_CTX *ctx = p->mem_ctx;
2315 WERROR werr;
2316 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2318 werr = WERR_OK;
2320 *r->out.totalentries = init_server_disk_enum(&resume);
2322 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2323 MAX_SERVER_DISK_ENTRIES);
2324 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2326 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2328 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2330 r->out.info->count++;
2332 /*copy disk name into a unicode string*/
2334 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2335 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2338 /* add a terminating null string. Is this there if there is more data to come? */
2340 r->out.info->count++;
2342 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2343 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2345 if (r->out.resume_handle) {
2346 *r->out.resume_handle = resume;
2349 return werr;
2352 /********************************************************************
2353 _srvsvc_NetNameValidate
2354 ********************************************************************/
2356 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2357 struct srvsvc_NetNameValidate *r)
2359 switch (r->in.name_type) {
2360 case 0x9:
2361 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2362 strlen_m(r->in.name)))
2364 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2365 r->in.name));
2366 return WERR_INVALID_NAME;
2368 break;
2370 default:
2371 return WERR_UNKNOWN_LEVEL;
2374 return WERR_OK;
2377 /********************************************************************
2378 ********************************************************************/
2380 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2382 return WERR_ACCESS_DENIED;
2386 /********************************************************************
2387 ********************************************************************/
2389 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2391 p->rng_fault_state = True;
2392 return WERR_NOT_SUPPORTED;
2395 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2397 p->rng_fault_state = True;
2398 return WERR_NOT_SUPPORTED;
2401 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2403 p->rng_fault_state = True;
2404 return WERR_NOT_SUPPORTED;
2407 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2409 p->rng_fault_state = True;
2410 return WERR_NOT_SUPPORTED;
2413 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2415 p->rng_fault_state = True;
2416 return WERR_NOT_SUPPORTED;
2419 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2421 p->rng_fault_state = True;
2422 return WERR_NOT_SUPPORTED;
2425 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2427 p->rng_fault_state = True;
2428 return WERR_NOT_SUPPORTED;
2431 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2433 p->rng_fault_state = True;
2434 return WERR_NOT_SUPPORTED;
2437 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2439 p->rng_fault_state = True;
2440 return WERR_NOT_SUPPORTED;
2443 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2445 p->rng_fault_state = True;
2446 return WERR_NOT_SUPPORTED;
2449 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2451 p->rng_fault_state = True;
2452 return WERR_NOT_SUPPORTED;
2455 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2457 p->rng_fault_state = True;
2458 return WERR_NOT_SUPPORTED;
2461 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2463 p->rng_fault_state = True;
2464 return WERR_NOT_SUPPORTED;
2467 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2469 p->rng_fault_state = True;
2470 return WERR_NOT_SUPPORTED;
2473 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2475 p->rng_fault_state = True;
2476 return WERR_NOT_SUPPORTED;
2479 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2481 p->rng_fault_state = True;
2482 return WERR_NOT_SUPPORTED;
2485 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2487 p->rng_fault_state = True;
2488 return WERR_NOT_SUPPORTED;
2491 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2493 p->rng_fault_state = True;
2494 return WERR_NOT_SUPPORTED;
2497 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2499 p->rng_fault_state = True;
2500 return WERR_NOT_SUPPORTED;
2503 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2505 p->rng_fault_state = True;
2506 return WERR_NOT_SUPPORTED;
2509 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2511 p->rng_fault_state = True;
2512 return WERR_NOT_SUPPORTED;
2515 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2517 p->rng_fault_state = True;
2518 return WERR_NOT_SUPPORTED;
2521 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2523 p->rng_fault_state = True;
2524 return WERR_NOT_SUPPORTED;
2527 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2529 p->rng_fault_state = True;
2530 return WERR_NOT_SUPPORTED;
2533 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2535 p->rng_fault_state = True;
2536 return WERR_NOT_SUPPORTED;
2539 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2541 p->rng_fault_state = True;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2547 p->rng_fault_state = True;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2553 p->rng_fault_state = True;
2554 return WERR_NOT_SUPPORTED;
2557 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2559 p->rng_fault_state = True;
2560 return WERR_NOT_SUPPORTED;
2563 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;
2569 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2571 p->rng_fault_state = True;
2572 return WERR_NOT_SUPPORTED;
2575 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2577 p->rng_fault_state = True;
2578 return WERR_NOT_SUPPORTED;
2581 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2583 p->rng_fault_state = True;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2589 p->rng_fault_state = True;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2595 p->rng_fault_state = True;
2596 return WERR_NOT_SUPPORTED;