Update WHATSNEW entry for pre3
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blobf10f3f205dcd2d1873826e422e7e3c7aaa9f0d9a
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 struct sec_desc_buf *sd_buf = NULL;
383 size_t sd_size = 0;
384 TALLOC_CTX *ctx = p->mem_ctx;
385 char *remark = talloc_strdup(ctx, lp_comment(snum));;
387 if (remark) {
388 remark = standard_sub_conn(ctx, p->conn, 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 init_srvsvc_NetShareInfo502(r, net_name,
404 get_share_type(snum),
405 remark ? remark : "",
407 (uint32_t)-1,
409 path ? path : "",
411 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 = standard_sub_conn(p->mem_ctx, p->conn, remark);
426 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
429 /***************************************************************************
430 Fill in a share info level 1005 structure.
431 ***************************************************************************/
433 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
435 uint32_t dfs_flags = 0;
437 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
438 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
441 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
443 init_srvsvc_NetShareInfo1005(r, dfs_flags);
446 /***************************************************************************
447 Fill in a share info level 1006 structure.
448 ***************************************************************************/
450 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
452 init_srvsvc_NetShareInfo1006(r, (uint32_t)-1);
455 /***************************************************************************
456 Fill in a share info level 1007 structure.
457 ***************************************************************************/
459 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
461 uint32 flags = 0;
463 init_srvsvc_NetShareInfo1007(r, flags, "");
466 /*******************************************************************
467 Fill in a share info level 1501 structure.
468 ********************************************************************/
470 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
472 SEC_DESC *sd;
473 size_t sd_size;
474 TALLOC_CTX *ctx = p->mem_ctx;
476 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
478 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
481 /*******************************************************************
482 True if it ends in '$'.
483 ********************************************************************/
485 static bool is_hidden_share(int snum)
487 const char *net_name = lp_servicename(snum);
489 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
492 /*******************************************************************
493 Fill in a share info structure.
494 ********************************************************************/
496 static WERROR init_srv_share_info_ctr(pipes_struct *p,
497 struct srvsvc_NetShareInfoCtr *info_ctr,
498 uint32_t *resume_handle_p,
499 uint32_t *total_entries,
500 bool all_shares)
502 int num_entries = 0;
503 int alloc_entries = 0;
504 int num_services = 0;
505 int snum;
506 TALLOC_CTX *ctx = p->mem_ctx;
507 int i = 0;
508 int valid_share_count = 0;
509 union srvsvc_NetShareCtr ctr;
510 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
512 DEBUG(5,("init_srv_share_info_ctr\n"));
514 /* Ensure all the usershares are loaded. */
515 become_root();
516 load_usershare_shares();
517 load_registry_shares();
518 num_services = lp_numservices();
519 unbecome_root();
521 /* Count the number of entries. */
522 for (snum = 0; snum < num_services; snum++) {
523 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
524 num_entries++;
528 if (!num_entries || (resume_handle >= num_entries)) {
529 return WERR_OK;
532 /* Calculate alloc entries. */
533 alloc_entries = num_entries - resume_handle;
534 switch (info_ctr->level) {
535 case 0:
536 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
537 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
539 ctr.ctr0->count = alloc_entries;
540 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
541 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
543 for (snum = 0; snum < num_services; snum++) {
544 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
545 (resume_handle <= (i + valid_share_count++)) ) {
546 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
550 break;
552 case 1:
553 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
554 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
556 ctr.ctr1->count = alloc_entries;
557 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
558 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
560 for (snum = 0; snum < num_services; snum++) {
561 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
562 (resume_handle <= (i + valid_share_count++)) ) {
563 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
567 break;
569 case 2:
570 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
571 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
573 ctr.ctr2->count = alloc_entries;
574 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
575 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
577 for (snum = 0; snum < num_services; snum++) {
578 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
579 (resume_handle <= (i + valid_share_count++)) ) {
580 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
584 break;
586 case 501:
587 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
588 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
590 ctr.ctr501->count = alloc_entries;
591 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
592 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
594 for (snum = 0; snum < num_services; snum++) {
595 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
596 (resume_handle <= (i + valid_share_count++)) ) {
597 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
601 break;
603 case 502:
604 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
605 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
607 ctr.ctr502->count = alloc_entries;
608 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
609 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
611 for (snum = 0; snum < num_services; snum++) {
612 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
613 (resume_handle <= (i + valid_share_count++)) ) {
614 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
618 break;
620 case 1004:
621 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
622 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
624 ctr.ctr1004->count = alloc_entries;
625 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
626 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
628 for (snum = 0; snum < num_services; snum++) {
629 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
630 (resume_handle <= (i + valid_share_count++)) ) {
631 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
635 break;
637 case 1005:
638 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
639 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
641 ctr.ctr1005->count = alloc_entries;
642 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
643 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
645 for (snum = 0; snum < num_services; snum++) {
646 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
647 (resume_handle <= (i + valid_share_count++)) ) {
648 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
652 break;
654 case 1006:
655 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
656 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
658 ctr.ctr1006->count = alloc_entries;
659 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
660 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
662 for (snum = 0; snum < num_services; snum++) {
663 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
664 (resume_handle <= (i + valid_share_count++)) ) {
665 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
669 break;
671 case 1007:
672 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
673 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
675 ctr.ctr1007->count = alloc_entries;
676 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
677 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
679 for (snum = 0; snum < num_services; snum++) {
680 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
681 (resume_handle <= (i + valid_share_count++)) ) {
682 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
686 break;
688 case 1501:
689 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
690 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
692 ctr.ctr1501->count = alloc_entries;
693 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
694 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
696 for (snum = 0; snum < num_services; snum++) {
697 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
698 (resume_handle <= (i + valid_share_count++)) ) {
699 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
703 break;
705 default:
706 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
707 info_ctr->level));
708 return WERR_UNKNOWN_LEVEL;
711 *total_entries = alloc_entries;
712 if (resume_handle_p) {
713 if (all_shares) {
714 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
715 } else {
716 *resume_handle_p = num_entries;
720 info_ctr->ctr = ctr;
722 return WERR_OK;
725 /*******************************************************************
726 fill in a sess info level 0 structure.
727 ********************************************************************/
729 static WERROR init_srv_sess_info_0(pipes_struct *p,
730 struct srvsvc_NetSessCtr0 *ctr0,
731 uint32_t *resume_handle_p,
732 uint32_t *total_entries)
734 struct sessionid *session_list;
735 uint32_t num_entries = 0;
736 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
737 *total_entries = list_sessions(p->mem_ctx, &session_list);
739 DEBUG(5,("init_srv_sess_info_0\n"));
741 if (ctr0 == NULL) {
742 if (resume_handle_p) {
743 *resume_handle_p = 0;
745 return WERR_OK;
748 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
750 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
751 ctr0->array,
752 struct srvsvc_NetSessInfo0,
753 num_entries+1);
754 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
756 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
757 session_list[resume_handle].remote_machine);
758 num_entries++;
761 ctr0->count = num_entries;
763 if (resume_handle_p) {
764 if (*resume_handle_p >= *total_entries) {
765 *resume_handle_p = 0;
766 } else {
767 *resume_handle_p = resume_handle;
771 return WERR_OK;
774 /*******************************************************************
775 ********************************************************************/
777 static void sess_file_fn( const struct share_mode_entry *e,
778 const char *sharepath, const char *fname,
779 void *data )
781 struct sess_file_count *sess = (struct sess_file_count *)data;
783 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
784 sess->count++;
787 return;
790 /*******************************************************************
791 ********************************************************************/
793 static int net_count_files( uid_t uid, struct server_id pid )
795 struct sess_file_count s_file_cnt;
797 s_file_cnt.count = 0;
798 s_file_cnt.uid = uid;
799 s_file_cnt.pid = pid;
801 share_mode_forall( sess_file_fn, &s_file_cnt );
803 return s_file_cnt.count;
806 /*******************************************************************
807 fill in a sess info level 1 structure.
808 ********************************************************************/
810 static WERROR init_srv_sess_info_1(pipes_struct *p,
811 struct srvsvc_NetSessCtr1 *ctr1,
812 uint32_t *resume_handle_p,
813 uint32_t *total_entries)
815 struct sessionid *session_list;
816 uint32_t num_entries = 0;
817 time_t now = time(NULL);
818 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
820 ZERO_STRUCTP(ctr1);
822 if (ctr1 == NULL) {
823 if (resume_handle_p) {
824 *resume_handle_p = 0;
826 return WERR_OK;
829 *total_entries = list_sessions(p->mem_ctx, &session_list);
831 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
832 uint32 num_files;
833 uint32 connect_time;
834 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
835 bool guest;
837 if ( !pw ) {
838 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
839 session_list[resume_handle].username));
840 continue;
843 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
844 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
845 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
847 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
848 ctr1->array,
849 struct srvsvc_NetSessInfo1,
850 num_entries+1);
851 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
853 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
854 session_list[resume_handle].remote_machine,
855 session_list[resume_handle].username,
856 num_files,
857 connect_time,
859 guest);
860 num_entries++;
863 ctr1->count = num_entries;
865 if (resume_handle_p) {
866 if (*resume_handle_p >= *total_entries) {
867 *resume_handle_p = 0;
868 } else {
869 *resume_handle_p = resume_handle;
873 return WERR_OK;
876 /*******************************************************************
877 fill in a conn info level 0 structure.
878 ********************************************************************/
880 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
881 uint32_t *resume_handle_p,
882 uint32_t *total_entries)
884 uint32_t num_entries = 0;
885 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
887 DEBUG(5,("init_srv_conn_info_0\n"));
889 if (ctr0 == NULL) {
890 if (resume_handle_p) {
891 *resume_handle_p = 0;
893 return WERR_OK;
896 *total_entries = 1;
898 ZERO_STRUCTP(ctr0);
900 for (; resume_handle < *total_entries && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
902 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
903 ctr0->array,
904 struct srvsvc_NetConnInfo0,
905 num_entries+1);
906 if (!ctr0->array) {
907 return WERR_NOMEM;
910 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
911 (*total_entries));
913 /* move on to creating next connection */
914 num_entries++;
917 ctr0->count = num_entries;
918 *total_entries = num_entries;
920 if (resume_handle_p) {
921 if (*resume_handle_p >= *total_entries) {
922 *resume_handle_p = 0;
923 } else {
924 *resume_handle_p = resume_handle;
928 return WERR_OK;
931 /*******************************************************************
932 fill in a conn info level 1 structure.
933 ********************************************************************/
935 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
936 uint32_t *resume_handle_p,
937 uint32_t *total_entries)
939 uint32_t num_entries = 0;
940 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
942 DEBUG(5,("init_srv_conn_info_1\n"));
944 if (ctr1 == NULL) {
945 if (resume_handle_p) {
946 *resume_handle_p = 0;
948 return WERR_OK;
951 *total_entries = 1;
953 ZERO_STRUCTP(ctr1);
955 for (; (resume_handle < *total_entries) && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
957 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
958 ctr1->array,
959 struct srvsvc_NetConnInfo1,
960 num_entries+1);
961 if (!ctr1->array) {
962 return WERR_NOMEM;
965 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
966 (*total_entries),
967 0x3,
971 "dummy_user",
972 "IPC$");
974 /* move on to creating next connection */
975 num_entries++;
978 ctr1->count = num_entries;
979 *total_entries = num_entries;
981 if (resume_handle_p) {
982 if (*resume_handle_p >= *total_entries) {
983 *resume_handle_p = 0;
984 } else {
985 *resume_handle_p = resume_handle;
989 return WERR_OK;
992 /*******************************************************************
993 _srvsvc_NetFileEnum
994 *******************************************************************/
996 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
997 struct srvsvc_NetFileEnum *r)
999 TALLOC_CTX *ctx = NULL;
1000 struct srvsvc_NetFileCtr3 *ctr3;
1001 uint32_t resume_hnd = 0;
1002 WERROR werr;
1004 switch (r->in.info_ctr->level) {
1005 case 3:
1006 break;
1007 default:
1008 return WERR_UNKNOWN_LEVEL;
1011 ctx = talloc_tos();
1012 ctr3 = r->in.info_ctr->ctr.ctr3;
1013 if (!ctr3) {
1014 goto done;
1017 /* TODO -- Windows enumerates
1018 (b) active pipes
1019 (c) open directories and files */
1021 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1022 if (!W_ERROR_IS_OK(werr)) {
1023 goto done;
1026 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1027 if (!W_ERROR_IS_OK(werr)) {
1028 goto done;
1031 *r->out.totalentries = ctr3->count;
1032 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1033 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1035 werr = WERR_OK;
1037 done:
1038 return werr;
1041 /*******************************************************************
1042 _srvsvc_NetSrvGetInfo
1043 ********************************************************************/
1045 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1046 struct srvsvc_NetSrvGetInfo *r)
1048 WERROR status = WERR_OK;
1050 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1052 if (!pipe_access_check(p)) {
1053 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1054 return WERR_ACCESS_DENIED;
1057 switch (r->in.level) {
1059 /* Technically level 102 should only be available to
1060 Administrators but there isn't anything super-secret
1061 here, as most of it is made up. */
1063 case 102: {
1064 struct srvsvc_NetSrvInfo102 *info102;
1066 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1067 if (!info102) {
1068 return WERR_NOMEM;
1071 init_srvsvc_NetSrvInfo102(info102,
1072 PLATFORM_ID_NT,
1073 global_myname(),
1074 lp_major_announce_version(),
1075 lp_minor_announce_version(),
1076 lp_default_server_announce(),
1077 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1078 0xffffffff, /* users */
1079 0xf, /* disc */
1080 0, /* hidden */
1081 240, /* announce */
1082 3000, /* announce delta */
1083 100000, /* licenses */
1084 "c:\\"); /* user path */
1085 r->out.info->info102 = info102;
1086 break;
1088 case 101: {
1089 struct srvsvc_NetSrvInfo101 *info101;
1091 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1092 if (!info101) {
1093 return WERR_NOMEM;
1096 init_srvsvc_NetSrvInfo101(info101,
1097 PLATFORM_ID_NT,
1098 global_myname(),
1099 lp_major_announce_version(),
1100 lp_minor_announce_version(),
1101 lp_default_server_announce(),
1102 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1103 r->out.info->info101 = info101;
1104 break;
1106 case 100: {
1107 struct srvsvc_NetSrvInfo100 *info100;
1109 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1110 if (!info100) {
1111 return WERR_NOMEM;
1114 init_srvsvc_NetSrvInfo100(info100,
1115 PLATFORM_ID_NT,
1116 global_myname());
1117 r->out.info->info100 = info100;
1119 break;
1121 default:
1122 status = WERR_UNKNOWN_LEVEL;
1123 break;
1126 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1128 return status;
1131 /*******************************************************************
1132 _srvsvc_NetSrvSetInfo
1133 ********************************************************************/
1135 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1136 struct srvsvc_NetSrvSetInfo *r)
1138 WERROR status = WERR_OK;
1140 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1142 /* Set up the net server set info structure. */
1144 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1146 return status;
1149 /*******************************************************************
1150 _srvsvc_NetConnEnum
1151 ********************************************************************/
1153 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1154 struct srvsvc_NetConnEnum *r)
1156 WERROR werr;
1158 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1160 switch (r->in.info_ctr->level) {
1161 case 0:
1162 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1163 r->in.resume_handle,
1164 r->out.totalentries);
1165 break;
1166 case 1:
1167 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1168 r->in.resume_handle,
1169 r->out.totalentries);
1170 break;
1171 default:
1172 return WERR_UNKNOWN_LEVEL;
1175 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1177 return werr;
1180 /*******************************************************************
1181 _srvsvc_NetSessEnum
1182 ********************************************************************/
1184 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1185 struct srvsvc_NetSessEnum *r)
1187 WERROR werr;
1189 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1191 switch (r->in.info_ctr->level) {
1192 case 0:
1193 werr = init_srv_sess_info_0(p,
1194 r->in.info_ctr->ctr.ctr0,
1195 r->in.resume_handle,
1196 r->out.totalentries);
1197 break;
1198 case 1:
1199 werr = init_srv_sess_info_1(p,
1200 r->in.info_ctr->ctr.ctr1,
1201 r->in.resume_handle,
1202 r->out.totalentries);
1203 break;
1204 default:
1205 return WERR_UNKNOWN_LEVEL;
1208 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1210 return werr;
1213 /*******************************************************************
1214 _srvsvc_NetSessDel
1215 ********************************************************************/
1217 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1218 struct srvsvc_NetSessDel *r)
1220 struct sessionid *session_list;
1221 struct current_user user;
1222 int num_sessions, snum;
1223 const char *username;
1224 const char *machine;
1225 bool not_root = False;
1226 WERROR werr;
1228 username = r->in.user;
1229 machine = r->in.client;
1231 /* strip leading backslashes if any */
1232 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1233 machine += 2;
1236 num_sessions = list_sessions(p->mem_ctx, &session_list);
1238 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1240 werr = WERR_ACCESS_DENIED;
1242 get_current_user(&user, p);
1244 /* fail out now if you are not root or not a domain admin */
1246 if ((user.ut.uid != sec_initial_uid()) &&
1247 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1249 goto done;
1252 for (snum = 0; snum < num_sessions; snum++) {
1254 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1255 strequal(session_list[snum].remote_machine, machine)) {
1257 NTSTATUS ntstat;
1259 if (user.ut.uid != sec_initial_uid()) {
1260 not_root = True;
1261 become_root();
1264 ntstat = messaging_send(smbd_messaging_context(),
1265 session_list[snum].pid,
1266 MSG_SHUTDOWN, &data_blob_null);
1268 if (NT_STATUS_IS_OK(ntstat))
1269 werr = WERR_OK;
1271 if (not_root)
1272 unbecome_root();
1276 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1278 done:
1280 return werr;
1283 /*******************************************************************
1284 _srvsvc_NetShareEnumAll
1285 ********************************************************************/
1287 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1288 struct srvsvc_NetShareEnumAll *r)
1290 WERROR werr;
1292 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1294 if (!pipe_access_check(p)) {
1295 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1296 return WERR_ACCESS_DENIED;
1299 /* Create the list of shares for the response. */
1300 werr = init_srv_share_info_ctr(p,
1301 r->in.info_ctr,
1302 r->in.resume_handle,
1303 r->out.totalentries,
1304 true);
1306 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1308 return werr;
1311 /*******************************************************************
1312 _srvsvc_NetShareEnum
1313 ********************************************************************/
1315 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1316 struct srvsvc_NetShareEnum *r)
1318 WERROR werr;
1320 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1322 if (!pipe_access_check(p)) {
1323 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1324 return WERR_ACCESS_DENIED;
1327 /* Create the list of shares for the response. */
1328 werr = init_srv_share_info_ctr(p,
1329 r->in.info_ctr,
1330 r->in.resume_handle,
1331 r->out.totalentries,
1332 false);
1334 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1336 return werr;
1339 /*******************************************************************
1340 _srvsvc_NetShareGetInfo
1341 ********************************************************************/
1343 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1344 struct srvsvc_NetShareGetInfo *r)
1346 WERROR status = WERR_OK;
1347 fstring share_name;
1348 int snum;
1349 union srvsvc_NetShareInfo *info = r->out.info;
1351 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1353 fstrcpy(share_name, r->in.share_name);
1355 snum = find_service(share_name);
1356 if (snum < 0) {
1357 return WERR_INVALID_NAME;
1360 switch (r->in.level) {
1361 case 0:
1362 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1363 W_ERROR_HAVE_NO_MEMORY(info->info0);
1364 init_srv_share_info_0(p, info->info0, snum);
1365 break;
1366 case 1:
1367 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1368 W_ERROR_HAVE_NO_MEMORY(info->info1);
1369 init_srv_share_info_1(p, info->info1, snum);
1370 break;
1371 case 2:
1372 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1373 W_ERROR_HAVE_NO_MEMORY(info->info2);
1374 init_srv_share_info_2(p, info->info2, snum);
1375 break;
1376 case 501:
1377 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1378 W_ERROR_HAVE_NO_MEMORY(info->info501);
1379 init_srv_share_info_501(p, info->info501, snum);
1380 break;
1381 case 502:
1382 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1383 W_ERROR_HAVE_NO_MEMORY(info->info502);
1384 init_srv_share_info_502(p, info->info502, snum);
1385 break;
1386 case 1004:
1387 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1388 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1389 init_srv_share_info_1004(p, info->info1004, snum);
1390 break;
1391 case 1005:
1392 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1393 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1394 init_srv_share_info_1005(p, info->info1005, snum);
1395 break;
1396 case 1006:
1397 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1398 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1399 init_srv_share_info_1006(p, info->info1006, snum);
1400 break;
1401 case 1007:
1402 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1403 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1404 init_srv_share_info_1007(p, info->info1007, snum);
1405 break;
1406 case 1501:
1407 init_srv_share_info_1501(p, info->info1501, snum);
1408 break;
1409 default:
1410 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1411 r->in.level));
1412 status = WERR_UNKNOWN_LEVEL;
1413 break;
1416 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1418 return status;
1421 /*******************************************************************
1422 Check a given DOS pathname is valid for a share.
1423 ********************************************************************/
1425 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1427 char *ptr = NULL;
1429 if (!dos_pathname) {
1430 return NULL;
1433 ptr = talloc_strdup(ctx, dos_pathname);
1434 if (!ptr) {
1435 return NULL;
1437 /* Convert any '\' paths to '/' */
1438 unix_format(ptr);
1439 ptr = unix_clean_name(ctx, ptr);
1440 if (!ptr) {
1441 return NULL;
1444 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1445 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1446 ptr += 2;
1448 /* Only absolute paths allowed. */
1449 if (*ptr != '/')
1450 return NULL;
1452 return ptr;
1455 /*******************************************************************
1456 _srvsvc_NetShareSetInfo. Modify share details.
1457 ********************************************************************/
1459 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1460 struct srvsvc_NetShareSetInfo *r)
1462 struct current_user user;
1463 char *command = NULL;
1464 char *share_name = NULL;
1465 char *comment = NULL;
1466 const char *pathname = NULL;
1467 int type;
1468 int snum;
1469 int ret;
1470 char *path = NULL;
1471 SEC_DESC *psd = NULL;
1472 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1473 bool is_disk_op = False;
1474 int max_connections = 0;
1475 TALLOC_CTX *ctx = p->mem_ctx;
1476 union srvsvc_NetShareInfo *info = r->in.info;
1478 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1480 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1481 if (!share_name) {
1482 return WERR_NOMEM;
1485 if (r->out.parm_error) {
1486 *r->out.parm_error = 0;
1489 if ( strequal(share_name,"IPC$")
1490 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1491 || strequal(share_name,"global") )
1493 return WERR_ACCESS_DENIED;
1496 snum = find_service(share_name);
1498 /* Does this share exist ? */
1499 if (snum < 0)
1500 return WERR_NET_NAME_NOT_FOUND;
1502 /* No change to printer shares. */
1503 if (lp_print_ok(snum))
1504 return WERR_ACCESS_DENIED;
1506 get_current_user(&user,p);
1508 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1510 /* fail out now if you are not root and not a disk op */
1512 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1513 return WERR_ACCESS_DENIED;
1515 switch (r->in.level) {
1516 case 1:
1517 pathname = talloc_strdup(ctx, lp_pathname(snum));
1518 comment = talloc_strdup(ctx, info->info1->comment);
1519 type = info->info1->type;
1520 psd = NULL;
1521 break;
1522 case 2:
1523 comment = talloc_strdup(ctx, info->info2->comment);
1524 pathname = info->info2->path;
1525 type = info->info2->type;
1526 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1527 0 : info->info2->max_users;
1528 psd = NULL;
1529 break;
1530 #if 0
1531 /* not supported on set but here for completeness */
1532 case 501:
1533 comment = talloc_strdup(ctx, info->info501->comment);
1534 type = info->info501->type;
1535 psd = NULL;
1536 break;
1537 #endif
1538 case 502:
1539 comment = talloc_strdup(ctx, info->info502->comment);
1540 pathname = info->info502->path;
1541 type = info->info502->type;
1542 psd = info->info502->sd_buf.sd;
1543 map_generic_share_sd_bits(psd);
1544 break;
1545 case 1004:
1546 pathname = talloc_strdup(ctx, lp_pathname(snum));
1547 comment = talloc_strdup(ctx, info->info1004->comment);
1548 type = STYPE_DISKTREE;
1549 break;
1550 case 1005:
1551 /* XP re-sets the csc policy even if it wasn't changed by the
1552 user, so we must compare it to see if it's what is set in
1553 smb.conf, so that we can contine other ops like setting
1554 ACLs on a share */
1555 if (((info->info1005->dfs_flags &
1556 SHARE_1005_CSC_POLICY_MASK) >>
1557 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1558 return WERR_OK;
1559 else {
1560 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1561 return WERR_ACCESS_DENIED;
1563 case 1006:
1564 case 1007:
1565 return WERR_ACCESS_DENIED;
1566 case 1501:
1567 pathname = talloc_strdup(ctx, lp_pathname(snum));
1568 comment = talloc_strdup(ctx, lp_comment(snum));
1569 psd = info->info1501->sd;
1570 map_generic_share_sd_bits(psd);
1571 type = STYPE_DISKTREE;
1572 break;
1573 default:
1574 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1575 r->in.level));
1576 return WERR_UNKNOWN_LEVEL;
1579 /* We can only modify disk shares. */
1580 if (type != STYPE_DISKTREE)
1581 return WERR_ACCESS_DENIED;
1583 if (comment == NULL) {
1584 return WERR_NOMEM;
1587 /* Check if the pathname is valid. */
1588 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1589 return WERR_OBJECT_PATH_INVALID;
1591 /* Ensure share name, pathname and comment don't contain '"' characters. */
1592 string_replace(share_name, '"', ' ');
1593 string_replace(path, '"', ' ');
1594 string_replace(comment, '"', ' ');
1596 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1597 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1599 /* Only call modify function if something changed. */
1601 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1602 || (lp_max_connections(snum) != max_connections)) {
1603 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1604 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1605 return WERR_ACCESS_DENIED;
1608 command = talloc_asprintf(p->mem_ctx,
1609 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1610 lp_change_share_cmd(),
1611 get_dyn_CONFIGFILE(),
1612 share_name,
1613 path,
1614 comment ? comment : "",
1615 max_connections);
1616 if (!command) {
1617 return WERR_NOMEM;
1620 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1622 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1624 if (is_disk_op)
1625 become_root();
1627 if ( (ret = smbrun(command, NULL)) == 0 ) {
1628 /* Tell everyone we updated smb.conf. */
1629 message_send_all(smbd_messaging_context(),
1630 MSG_SMB_CONF_UPDATED, NULL, 0,
1631 NULL);
1634 if ( is_disk_op )
1635 unbecome_root();
1637 /********* END SeDiskOperatorPrivilege BLOCK *********/
1639 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1640 command, ret ));
1642 TALLOC_FREE(command);
1644 if ( ret != 0 )
1645 return WERR_ACCESS_DENIED;
1646 } else {
1647 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1648 share_name ));
1651 /* Replace SD if changed. */
1652 if (psd) {
1653 SEC_DESC *old_sd;
1654 size_t sd_size;
1656 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1658 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1659 if (!set_share_security(share_name, psd))
1660 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1661 share_name ));
1665 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1667 return WERR_OK;
1670 /*******************************************************************
1671 _srvsvc_NetShareAdd.
1672 Call 'add_share_command "sharename" "pathname"
1673 "comment" "max connections = "
1674 ********************************************************************/
1676 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1677 struct srvsvc_NetShareAdd *r)
1679 struct current_user user;
1680 char *command = NULL;
1681 char *share_name = NULL;
1682 char *comment = NULL;
1683 char *pathname = NULL;
1684 int type;
1685 int snum;
1686 int ret;
1687 char *path;
1688 SEC_DESC *psd = NULL;
1689 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1690 bool is_disk_op;
1691 int max_connections = 0;
1692 TALLOC_CTX *ctx = p->mem_ctx;
1694 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1696 *r->out.parm_error = 0;
1698 get_current_user(&user,p);
1700 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1702 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1703 return WERR_ACCESS_DENIED;
1705 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1706 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1707 return WERR_ACCESS_DENIED;
1710 switch (r->in.level) {
1711 case 0:
1712 /* No path. Not enough info in a level 0 to do anything. */
1713 return WERR_ACCESS_DENIED;
1714 case 1:
1715 /* Not enough info in a level 1 to do anything. */
1716 return WERR_ACCESS_DENIED;
1717 case 2:
1718 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1719 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1720 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1721 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1722 0 : r->in.info->info2->max_users;
1723 type = r->in.info->info2->type;
1724 break;
1725 case 501:
1726 /* No path. Not enough info in a level 501 to do anything. */
1727 return WERR_ACCESS_DENIED;
1728 case 502:
1729 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1730 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1731 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1732 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1733 0 : r->in.info->info502->max_users;
1734 type = r->in.info->info502->type;
1735 psd = r->in.info->info502->sd_buf.sd;
1736 map_generic_share_sd_bits(psd);
1737 break;
1739 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1741 case 1004:
1742 case 1005:
1743 case 1006:
1744 case 1007:
1745 return WERR_ACCESS_DENIED;
1746 case 1501:
1747 /* DFS only level. */
1748 return WERR_ACCESS_DENIED;
1749 default:
1750 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1751 r->in.level));
1752 return WERR_UNKNOWN_LEVEL;
1755 /* check for invalid share names */
1757 if (!share_name || !validate_net_name(share_name,
1758 INVALID_SHARENAME_CHARS,
1759 strlen(share_name))) {
1760 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1761 share_name ? share_name : ""));
1762 return WERR_INVALID_NAME;
1765 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1766 || (lp_enable_asu_support() &&
1767 strequal(share_name,"ADMIN$"))) {
1768 return WERR_ACCESS_DENIED;
1771 snum = find_service(share_name);
1773 /* Share already exists. */
1774 if (snum >= 0) {
1775 return WERR_ALREADY_EXISTS;
1778 /* We can only add disk shares. */
1779 if (type != STYPE_DISKTREE) {
1780 return WERR_ACCESS_DENIED;
1783 /* Check if the pathname is valid. */
1784 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1785 return WERR_OBJECT_PATH_INVALID;
1788 /* Ensure share name, pathname and comment don't contain '"' characters. */
1789 string_replace(share_name, '"', ' ');
1790 string_replace(path, '"', ' ');
1791 if (comment) {
1792 string_replace(comment, '"', ' ');
1795 command = talloc_asprintf(ctx,
1796 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1797 lp_add_share_cmd(),
1798 get_dyn_CONFIGFILE(),
1799 share_name,
1800 path,
1801 comment ? comment : "",
1802 max_connections);
1803 if (!command) {
1804 return WERR_NOMEM;
1807 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1809 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1811 if ( is_disk_op )
1812 become_root();
1814 /* FIXME: use libnetconf here - gd */
1816 if ( (ret = smbrun(command, NULL)) == 0 ) {
1817 /* Tell everyone we updated smb.conf. */
1818 message_send_all(smbd_messaging_context(),
1819 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1822 if ( is_disk_op )
1823 unbecome_root();
1825 /********* END SeDiskOperatorPrivilege BLOCK *********/
1827 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1828 command, ret ));
1830 TALLOC_FREE(command);
1832 if ( ret != 0 )
1833 return WERR_ACCESS_DENIED;
1835 if (psd) {
1836 if (!set_share_security(share_name, psd)) {
1837 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1838 share_name ));
1843 * We don't call reload_services() here, the message will
1844 * cause this to be done before the next packet is read
1845 * from the client. JRA.
1848 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1850 return WERR_OK;
1853 /*******************************************************************
1854 _srvsvc_NetShareDel
1855 Call "delete share command" with the share name as
1856 a parameter.
1857 ********************************************************************/
1859 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1860 struct srvsvc_NetShareDel *r)
1862 struct current_user user;
1863 char *command = NULL;
1864 char *share_name = NULL;
1865 int ret;
1866 int snum;
1867 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1868 bool is_disk_op;
1869 struct share_params *params;
1870 TALLOC_CTX *ctx = p->mem_ctx;
1872 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1874 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1875 if (!share_name) {
1876 return WERR_NET_NAME_NOT_FOUND;
1878 if ( strequal(share_name,"IPC$")
1879 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1880 || strequal(share_name,"global") )
1882 return WERR_ACCESS_DENIED;
1885 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1886 return WERR_NO_SUCH_SHARE;
1889 snum = find_service(share_name);
1891 /* No change to printer shares. */
1892 if (lp_print_ok(snum))
1893 return WERR_ACCESS_DENIED;
1895 get_current_user(&user,p);
1897 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1899 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1900 return WERR_ACCESS_DENIED;
1902 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1903 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1904 return WERR_ACCESS_DENIED;
1907 command = talloc_asprintf(ctx,
1908 "%s \"%s\" \"%s\"",
1909 lp_delete_share_cmd(),
1910 get_dyn_CONFIGFILE(),
1911 lp_servicename(snum));
1912 if (!command) {
1913 return WERR_NOMEM;
1916 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1918 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1920 if ( is_disk_op )
1921 become_root();
1923 if ( (ret = smbrun(command, NULL)) == 0 ) {
1924 /* Tell everyone we updated smb.conf. */
1925 message_send_all(smbd_messaging_context(),
1926 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1929 if ( is_disk_op )
1930 unbecome_root();
1932 /********* END SeDiskOperatorPrivilege BLOCK *********/
1934 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1936 if ( ret != 0 )
1937 return WERR_ACCESS_DENIED;
1939 /* Delete the SD in the database. */
1940 delete_share_security(lp_servicename(params->service));
1942 lp_killservice(params->service);
1944 return WERR_OK;
1947 /*******************************************************************
1948 _srvsvc_NetShareDelSticky
1949 ********************************************************************/
1951 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1952 struct srvsvc_NetShareDelSticky *r)
1954 struct srvsvc_NetShareDel q;
1956 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1958 q.in.server_unc = r->in.server_unc;
1959 q.in.share_name = r->in.share_name;
1960 q.in.reserved = r->in.reserved;
1962 return _srvsvc_NetShareDel(p, &q);
1965 /*******************************************************************
1966 _srvsvc_NetRemoteTOD
1967 ********************************************************************/
1969 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1970 struct srvsvc_NetRemoteTOD *r)
1972 struct srvsvc_NetRemoteTODInfo *tod;
1973 struct tm *t;
1974 time_t unixdate = time(NULL);
1976 /* We do this call first as if we do it *after* the gmtime call
1977 it overwrites the pointed-to values. JRA */
1979 uint32 zone = get_time_zone(unixdate)/60;
1981 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1983 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1984 return WERR_NOMEM;
1986 *r->out.info = tod;
1988 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1990 t = gmtime(&unixdate);
1992 /* set up the */
1993 init_srvsvc_NetRemoteTODInfo(tod,
1994 unixdate,
1996 t->tm_hour,
1997 t->tm_min,
1998 t->tm_sec,
2000 zone,
2001 10000,
2002 t->tm_mday,
2003 t->tm_mon + 1,
2004 1900+t->tm_year,
2005 t->tm_wday);
2007 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2009 return WERR_OK;
2012 /***********************************************************************************
2013 _srvsvc_NetGetFileSecurity
2014 Win9x NT tools get security descriptor.
2015 ***********************************************************************************/
2017 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2018 struct srvsvc_NetGetFileSecurity *r)
2020 SEC_DESC *psd = NULL;
2021 size_t sd_size;
2022 DATA_BLOB null_pw;
2023 char *filename_in = NULL;
2024 char *filename = NULL;
2025 char *qualname = NULL;
2026 SMB_STRUCT_STAT st;
2027 NTSTATUS nt_status;
2028 WERROR werr;
2029 struct current_user user;
2030 connection_struct *conn = NULL;
2031 bool became_user = False;
2032 TALLOC_CTX *ctx = p->mem_ctx;
2033 struct sec_desc_buf *sd_buf;
2035 ZERO_STRUCT(st);
2037 werr = WERR_OK;
2039 qualname = talloc_strdup(ctx, r->in.share);
2040 if (!qualname) {
2041 werr = WERR_ACCESS_DENIED;
2042 goto error_exit;
2045 /* Null password is ok - we are already an authenticated user... */
2046 null_pw = data_blob_null;
2048 get_current_user(&user, p);
2050 become_root();
2051 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2052 unbecome_root();
2054 if (conn == NULL) {
2055 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2056 qualname));
2057 werr = ntstatus_to_werror(nt_status);
2058 goto error_exit;
2061 if (!become_user(conn, conn->vuid)) {
2062 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2063 werr = WERR_ACCESS_DENIED;
2064 goto error_exit;
2066 became_user = True;
2068 filename_in = talloc_strdup(ctx, r->in.file);
2069 if (!filename_in) {
2070 werr = WERR_ACCESS_DENIED;
2071 goto error_exit;
2074 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2075 if (!NT_STATUS_IS_OK(nt_status)) {
2076 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2077 filename));
2078 werr = WERR_ACCESS_DENIED;
2079 goto error_exit;
2082 nt_status = check_name(conn, filename);
2083 if (!NT_STATUS_IS_OK(nt_status)) {
2084 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2085 filename));
2086 werr = WERR_ACCESS_DENIED;
2087 goto error_exit;
2090 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2091 (OWNER_SECURITY_INFORMATION
2092 |GROUP_SECURITY_INFORMATION
2093 |DACL_SECURITY_INFORMATION), &psd);
2095 if (!NT_STATUS_IS_OK(nt_status)) {
2096 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2097 filename));
2098 werr = ntstatus_to_werror(nt_status);
2099 goto error_exit;
2102 sd_size = ndr_size_security_descriptor(psd, 0);
2104 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2105 if (!sd_buf) {
2106 werr = WERR_NOMEM;
2107 goto error_exit;
2110 sd_buf->sd_size = sd_size;
2111 sd_buf->sd = psd;
2113 *r->out.sd_buf = sd_buf;
2115 psd->dacl->revision = NT4_ACL_REVISION;
2117 unbecome_user();
2118 close_cnum(conn, user.vuid);
2119 return werr;
2121 error_exit:
2123 if (became_user)
2124 unbecome_user();
2126 if (conn)
2127 close_cnum(conn, user.vuid);
2129 return werr;
2132 /***********************************************************************************
2133 _srvsvc_NetSetFileSecurity
2134 Win9x NT tools set security descriptor.
2135 ***********************************************************************************/
2137 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2138 struct srvsvc_NetSetFileSecurity *r)
2140 char *filename_in = NULL;
2141 char *filename = NULL;
2142 char *qualname = NULL;
2143 DATA_BLOB null_pw;
2144 files_struct *fsp = NULL;
2145 SMB_STRUCT_STAT st;
2146 NTSTATUS nt_status;
2147 WERROR werr;
2148 struct current_user user;
2149 connection_struct *conn = NULL;
2150 bool became_user = False;
2151 TALLOC_CTX *ctx = p->mem_ctx;
2153 ZERO_STRUCT(st);
2155 werr = WERR_OK;
2157 qualname = talloc_strdup(ctx, r->in.share);
2158 if (!qualname) {
2159 werr = WERR_ACCESS_DENIED;
2160 goto error_exit;
2163 /* Null password is ok - we are already an authenticated user... */
2164 null_pw = data_blob_null;
2166 get_current_user(&user, p);
2168 become_root();
2169 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2170 unbecome_root();
2172 if (conn == NULL) {
2173 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2174 werr = ntstatus_to_werror(nt_status);
2175 goto error_exit;
2178 if (!become_user(conn, conn->vuid)) {
2179 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2180 werr = WERR_ACCESS_DENIED;
2181 goto error_exit;
2183 became_user = True;
2185 filename_in = talloc_strdup(ctx, r->in.file);
2186 if (!filename_in) {
2187 werr = WERR_ACCESS_DENIED;
2188 goto error_exit;
2191 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2192 if (!NT_STATUS_IS_OK(nt_status)) {
2193 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2194 werr = WERR_ACCESS_DENIED;
2195 goto error_exit;
2198 nt_status = check_name(conn, filename);
2199 if (!NT_STATUS_IS_OK(nt_status)) {
2200 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2201 werr = WERR_ACCESS_DENIED;
2202 goto error_exit;
2205 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2207 if ( !NT_STATUS_IS_OK(nt_status) ) {
2208 /* Perhaps it is a directory */
2209 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2210 nt_status = open_directory(conn, NULL, filename, &st,
2211 FILE_READ_ATTRIBUTES,
2212 FILE_SHARE_READ|FILE_SHARE_WRITE,
2213 FILE_OPEN,
2215 FILE_ATTRIBUTE_DIRECTORY,
2216 NULL, &fsp);
2218 if ( !NT_STATUS_IS_OK(nt_status) ) {
2219 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2220 werr = ntstatus_to_werror(nt_status);
2221 goto error_exit;
2225 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2226 r->in.securityinformation,
2227 r->in.sd_buf->sd);
2229 if (!NT_STATUS_IS_OK(nt_status) ) {
2230 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2231 werr = WERR_ACCESS_DENIED;
2232 goto error_exit;
2235 close_file(fsp, NORMAL_CLOSE);
2236 unbecome_user();
2237 close_cnum(conn, user.vuid);
2238 return werr;
2240 error_exit:
2242 if(fsp) {
2243 close_file(fsp, NORMAL_CLOSE);
2246 if (became_user) {
2247 unbecome_user();
2250 if (conn) {
2251 close_cnum(conn, user.vuid);
2254 return werr;
2257 /***********************************************************************************
2258 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2259 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2260 These disks would the disks listed by this function.
2261 Users could then create shares relative to these disks. Watch out for moving these disks around.
2262 "Nigel Williams" <nigel@veritas.com>.
2263 ***********************************************************************************/
2265 static const char *server_disks[] = {"C:"};
2267 static uint32 get_server_disk_count(void)
2269 return sizeof(server_disks)/sizeof(server_disks[0]);
2272 static uint32 init_server_disk_enum(uint32 *resume)
2274 uint32 server_disk_count = get_server_disk_count();
2276 /*resume can be an offset into the list for now*/
2278 if(*resume & 0x80000000)
2279 *resume = 0;
2281 if(*resume > server_disk_count)
2282 *resume = server_disk_count;
2284 return server_disk_count - *resume;
2287 static const char *next_server_disk_enum(uint32 *resume)
2289 const char *disk;
2291 if(init_server_disk_enum(resume) == 0)
2292 return NULL;
2294 disk = server_disks[*resume];
2296 (*resume)++;
2298 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2300 return disk;
2303 /********************************************************************
2304 _srvsvc_NetDiskEnum
2305 ********************************************************************/
2307 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2308 struct srvsvc_NetDiskEnum *r)
2310 uint32 i;
2311 const char *disk_name;
2312 TALLOC_CTX *ctx = p->mem_ctx;
2313 WERROR werr;
2314 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2316 werr = WERR_OK;
2318 *r->out.totalentries = init_server_disk_enum(&resume);
2320 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2321 MAX_SERVER_DISK_ENTRIES);
2322 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2324 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2326 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2328 r->out.info->count++;
2330 /*copy disk name into a unicode string*/
2332 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2333 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2336 /* add a terminating null string. Is this there if there is more data to come? */
2338 r->out.info->count++;
2340 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2341 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2343 if (r->out.resume_handle) {
2344 *r->out.resume_handle = resume;
2347 return werr;
2350 /********************************************************************
2351 _srvsvc_NetNameValidate
2352 ********************************************************************/
2354 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2355 struct srvsvc_NetNameValidate *r)
2357 switch (r->in.name_type) {
2358 case 0x9:
2359 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2360 strlen_m(r->in.name)))
2362 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2363 r->in.name));
2364 return WERR_INVALID_NAME;
2366 break;
2368 default:
2369 return WERR_UNKNOWN_LEVEL;
2372 return WERR_OK;
2375 /********************************************************************
2376 ********************************************************************/
2378 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2380 return WERR_ACCESS_DENIED;
2384 /********************************************************************
2385 ********************************************************************/
2387 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2389 p->rng_fault_state = True;
2390 return WERR_NOT_SUPPORTED;
2393 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2395 p->rng_fault_state = True;
2396 return WERR_NOT_SUPPORTED;
2399 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2401 p->rng_fault_state = True;
2402 return WERR_NOT_SUPPORTED;
2405 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2407 p->rng_fault_state = True;
2408 return WERR_NOT_SUPPORTED;
2411 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2413 p->rng_fault_state = True;
2414 return WERR_NOT_SUPPORTED;
2417 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2419 p->rng_fault_state = True;
2420 return WERR_NOT_SUPPORTED;
2423 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2425 p->rng_fault_state = True;
2426 return WERR_NOT_SUPPORTED;
2429 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2431 p->rng_fault_state = True;
2432 return WERR_NOT_SUPPORTED;
2435 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2437 p->rng_fault_state = True;
2438 return WERR_NOT_SUPPORTED;
2441 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2443 p->rng_fault_state = True;
2444 return WERR_NOT_SUPPORTED;
2447 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2449 p->rng_fault_state = True;
2450 return WERR_NOT_SUPPORTED;
2453 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2455 p->rng_fault_state = True;
2456 return WERR_NOT_SUPPORTED;
2459 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2461 p->rng_fault_state = True;
2462 return WERR_NOT_SUPPORTED;
2465 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2467 p->rng_fault_state = True;
2468 return WERR_NOT_SUPPORTED;
2471 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2473 p->rng_fault_state = True;
2474 return WERR_NOT_SUPPORTED;
2477 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2479 p->rng_fault_state = True;
2480 return WERR_NOT_SUPPORTED;
2483 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2485 p->rng_fault_state = True;
2486 return WERR_NOT_SUPPORTED;
2489 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2491 p->rng_fault_state = True;
2492 return WERR_NOT_SUPPORTED;
2495 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2497 p->rng_fault_state = True;
2498 return WERR_NOT_SUPPORTED;
2501 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2503 p->rng_fault_state = True;
2504 return WERR_NOT_SUPPORTED;
2507 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2509 p->rng_fault_state = True;
2510 return WERR_NOT_SUPPORTED;
2513 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2515 p->rng_fault_state = True;
2516 return WERR_NOT_SUPPORTED;
2519 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2521 p->rng_fault_state = True;
2522 return WERR_NOT_SUPPORTED;
2525 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2527 p->rng_fault_state = True;
2528 return WERR_NOT_SUPPORTED;
2531 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2533 p->rng_fault_state = True;
2534 return WERR_NOT_SUPPORTED;
2537 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2539 p->rng_fault_state = True;
2540 return WERR_NOT_SUPPORTED;
2543 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2545 p->rng_fault_state = True;
2546 return WERR_NOT_SUPPORTED;
2549 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2555 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2557 p->rng_fault_state = True;
2558 return WERR_NOT_SUPPORTED;
2561 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2563 p->rng_fault_state = True;
2564 return WERR_NOT_SUPPORTED;
2567 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2569 p->rng_fault_state = True;
2570 return WERR_NOT_SUPPORTED;
2573 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2575 p->rng_fault_state = True;
2576 return WERR_NOT_SUPPORTED;
2579 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2581 p->rng_fault_state = True;
2582 return WERR_NOT_SUPPORTED;
2585 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2587 p->rng_fault_state = True;
2588 return WERR_NOT_SUPPORTED;
2591 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2593 p->rng_fault_state = True;
2594 return WERR_NOT_SUPPORTED;