Use pidl for _srvsvc_NetSessEnum().
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_srvsvc_nt.c
blobc8f21b76bb5574241162dd26ac57aafa65d9cb29
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.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 /* This is the implementation of the srvsvc pipe. */
25 #include "includes.h"
27 extern const struct generic_mapping file_generic_mapping;
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /* Use for enumerating connections, pipes, & files */
34 struct file_enum_count {
35 TALLOC_CTX *ctx;
36 const char *username;
37 struct srvsvc_NetFileCtr3 *ctr3;
40 struct sess_file_count {
41 struct server_id pid;
42 uid_t uid;
43 int count;
46 /****************************************************************************
47 Count the entries belonging to a service in the connection db.
48 ****************************************************************************/
50 static int pipe_enum_fn( struct db_record *rec, void *p)
52 struct pipe_open_rec prec;
53 struct file_enum_count *fenum = (struct file_enum_count *)p;
54 struct srvsvc_NetFileInfo3 *f;
55 int i = fenum->ctr3->count;
56 char *fullpath = NULL;
57 const char *username;
59 if (rec->value.dsize != sizeof(struct pipe_open_rec))
60 return 0;
62 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
64 if ( !process_exists(prec.pid) ) {
65 return 0;
68 username = uidtoname(prec.uid);
70 if ((fenum->username != NULL)
71 && !strequal(username, fenum->username)) {
72 return 0;
75 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
76 if (!fullpath) {
77 return 1;
80 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
81 struct srvsvc_NetFileInfo3, i+1);
82 if ( !f ) {
83 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
84 return 1;
86 fenum->ctr3->array = f;
88 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
89 (uint32_t)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
90 (FILE_READ_DATA|FILE_WRITE_DATA),
92 fullpath,
93 username);
95 fenum->ctr3->count++;
97 return 0;
100 /*******************************************************************
101 ********************************************************************/
103 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
104 const char *username,
105 struct srvsvc_NetFileCtr3 **ctr3,
106 uint32_t resume )
108 struct file_enum_count fenum;
110 fenum.ctx = ctx;
111 fenum.username = username;
112 fenum.ctr3 = *ctr3;
114 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
115 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
116 "failed\n"));
117 return WERR_NOMEM;
120 *ctr3 = fenum.ctr3;
122 return WERR_OK;
125 /*******************************************************************
126 ********************************************************************/
128 static void enum_file_fn( const struct share_mode_entry *e,
129 const char *sharepath, const char *fname,
130 void *private_data )
132 struct file_enum_count *fenum =
133 (struct file_enum_count *)private_data;
135 struct srvsvc_NetFileInfo3 *f;
136 int i = fenum->ctr3->count;
137 files_struct fsp;
138 struct byte_range_lock *brl;
139 int num_locks = 0;
140 char *fullpath = NULL;
141 uint32 permissions;
142 const char *username;
144 /* If the pid was not found delete the entry from connections.tdb */
146 if ( !process_exists(e->pid) ) {
147 return;
150 username = uidtoname(e->uid);
152 if ((fenum->username != NULL)
153 && !strequal(username, fenum->username)) {
154 return;
157 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
158 struct srvsvc_NetFileInfo3, i+1);
159 if ( !f ) {
160 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
161 return;
163 fenum->ctr3->array = f;
165 /* need to count the number of locks on a file */
167 ZERO_STRUCT( fsp );
168 fsp.file_id = e->id;
170 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
171 num_locks = brl->num_locks;
172 TALLOC_FREE(brl);
175 if ( strcmp( fname, "." ) == 0 ) {
176 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
177 } else {
178 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
179 sharepath, fname );
181 if (!fullpath) {
182 return;
184 string_replace( fullpath, '/', '\\' );
186 /* mask out create (what ever that is) */
187 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
189 /* now fill in the srvsvc_NetFileInfo3 struct */
190 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
191 e->share_file_id,
192 permissions,
193 num_locks,
194 username,
195 fullpath);
196 fenum->ctr3->count++;
199 /*******************************************************************
200 ********************************************************************/
202 static WERROR net_enum_files(TALLOC_CTX *ctx,
203 const char *username,
204 struct srvsvc_NetFileCtr3 **ctr3,
205 uint32_t resume)
207 struct file_enum_count f_enum_cnt;
209 f_enum_cnt.ctx = ctx;
210 f_enum_cnt.username = username;
211 f_enum_cnt.ctr3 = *ctr3;
213 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
215 *ctr3 = f_enum_cnt.ctr3;
217 return WERR_OK;
220 /*******************************************************************
221 Utility function to get the 'type' of a share from an snum.
222 ********************************************************************/
223 static uint32 get_share_type(int snum)
225 /* work out the share type */
226 uint32 type = STYPE_DISKTREE;
228 if (lp_print_ok(snum))
229 type = STYPE_PRINTQ;
230 if (strequal(lp_fstype(snum), "IPC"))
231 type = STYPE_IPC;
232 if (lp_administrative_share(snum))
233 type |= STYPE_HIDDEN;
235 return type;
238 /*******************************************************************
239 Fill in a share info level 0 structure.
240 ********************************************************************/
242 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
244 const char *net_name = lp_servicename(snum);
246 init_srvsvc_NetShareInfo0(r, net_name);
249 /*******************************************************************
250 Fill in a share info level 1 structure.
251 ********************************************************************/
253 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
255 char *net_name = lp_servicename(snum);
256 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
258 if (remark) {
259 remark = standard_sub_conn(p->mem_ctx,
260 p->conn,
261 remark);
264 init_srvsvc_NetShareInfo1(r, net_name,
265 get_share_type(snum),
266 remark ? remark : "");
269 /*******************************************************************
270 Fill in a share info level 2 structure.
271 ********************************************************************/
273 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
275 char *remark = NULL;
276 char *path = NULL;
277 int max_connections = lp_max_connections(snum);
278 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
279 int count = 0;
280 char *net_name = lp_servicename(snum);
282 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
283 if (remark) {
284 remark = standard_sub_conn(p->mem_ctx,
285 p->conn,
286 remark);
288 path = talloc_asprintf(p->mem_ctx,
289 "C:%s", lp_pathname(snum));
291 if (path) {
293 * Change / to \\ so that win2k will see it as a valid path.
294 * This was added to enable use of browsing in win2k add
295 * share dialog.
298 string_replace(path, '/', '\\');
301 count = count_current_connections(net_name, false);
303 init_srvsvc_NetShareInfo2(r, net_name,
304 get_share_type(snum),
305 remark ? remark : "",
307 max_uses,
308 count,
309 path ? path : "",
310 "");
313 /*******************************************************************
314 Map any generic bits to file specific bits.
315 ********************************************************************/
317 static void map_generic_share_sd_bits(SEC_DESC *psd)
319 int i;
320 SEC_ACL *ps_dacl = NULL;
322 if (!psd)
323 return;
325 ps_dacl = psd->dacl;
326 if (!ps_dacl)
327 return;
329 for (i = 0; i < ps_dacl->num_aces; i++) {
330 SEC_ACE *psa = &ps_dacl->aces[i];
331 uint32 orig_mask = psa->access_mask;
333 se_map_generic(&psa->access_mask, &file_generic_mapping);
334 psa->access_mask |= orig_mask;
338 /*******************************************************************
339 Fill in a share info level 501 structure.
340 ********************************************************************/
342 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
344 const char *net_name = lp_servicename(snum);
345 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
347 if (remark) {
348 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
351 init_srvsvc_NetShareInfo501(r, net_name,
352 get_share_type(snum),
353 remark ? remark : "",
354 (lp_csc_policy(snum) << 4));
357 /*******************************************************************
358 Fill in a share info level 502 structure.
359 ********************************************************************/
361 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
363 const char *net_name = lp_servicename(snum);
364 char *path = NULL;
365 SEC_DESC *sd = NULL;
366 size_t sd_size = 0;
367 TALLOC_CTX *ctx = p->mem_ctx;
368 char *remark = talloc_strdup(ctx, lp_comment(snum));;
370 if (remark) {
371 remark = standard_sub_conn(ctx, p->conn, remark);
373 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
374 if (path) {
376 * Change / to \\ so that win2k will see it as a valid path. This was added to
377 * enable use of browsing in win2k add share dialog.
379 string_replace(path, '/', '\\');
382 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
384 init_srvsvc_NetShareInfo502(r, net_name,
385 get_share_type(snum),
386 remark ? remark : "",
388 0xffffffff,
390 path ? path : "",
393 sd);
396 /***************************************************************************
397 Fill in a share info level 1004 structure.
398 ***************************************************************************/
400 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
402 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
404 if (remark) {
405 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
408 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
411 /***************************************************************************
412 Fill in a share info level 1005 structure.
413 ***************************************************************************/
415 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
417 uint32_t dfs_flags = 0;
419 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
420 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
423 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
425 init_srvsvc_NetShareInfo1005(r, dfs_flags);
428 /***************************************************************************
429 Fill in a share info level 1006 structure.
430 ***************************************************************************/
432 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
434 init_srvsvc_NetShareInfo1006(r, 0xffffffff);
437 /***************************************************************************
438 Fill in a share info level 1007 structure.
439 ***************************************************************************/
441 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
443 uint32 flags = 0;
445 init_srvsvc_NetShareInfo1007(r, flags, "");
448 /*******************************************************************
449 Fill in a share info level 1501 structure.
450 ********************************************************************/
452 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
454 SEC_DESC *sd;
455 size_t sd_size;
456 TALLOC_CTX *ctx = p->mem_ctx;
458 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
460 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
463 /*******************************************************************
464 True if it ends in '$'.
465 ********************************************************************/
467 static bool is_hidden_share(int snum)
469 const char *net_name = lp_servicename(snum);
471 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
474 /*******************************************************************
475 Fill in a share info structure.
476 ********************************************************************/
478 static WERROR init_srv_share_info_ctr(pipes_struct *p,
479 struct srvsvc_NetShareInfoCtr *info_ctr,
480 uint32_t *resume_handle_p,
481 uint32_t *total_entries,
482 bool all_shares)
484 int num_entries = 0;
485 int alloc_entries = 0;
486 int num_services = 0;
487 int snum;
488 TALLOC_CTX *ctx = p->mem_ctx;
489 int i = 0;
490 int valid_share_count = 0;
491 union srvsvc_NetShareCtr ctr;
492 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
494 DEBUG(5,("init_srv_share_info_ctr\n"));
496 /* Ensure all the usershares are loaded. */
497 become_root();
498 load_usershare_shares();
499 load_registry_shares();
500 num_services = lp_numservices();
501 unbecome_root();
503 /* Count the number of entries. */
504 for (snum = 0; snum < num_services; snum++) {
505 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
506 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
507 num_entries++;
508 } else {
509 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
513 if (!num_entries || (resume_handle >= num_entries)) {
514 return WERR_OK;
517 /* Calculate alloc entries. */
518 alloc_entries = num_entries - resume_handle;
519 switch (info_ctr->level) {
520 case 0:
521 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
522 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
524 ctr.ctr0->count = alloc_entries;
525 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
526 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
528 for (snum = 0; snum < num_services; snum++) {
529 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
530 (resume_handle <= (i + valid_share_count++)) ) {
531 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
535 break;
537 case 1:
538 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
539 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
541 ctr.ctr1->count = alloc_entries;
542 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
543 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
545 for (snum = 0; snum < num_services; snum++) {
546 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
547 (resume_handle <= (i + valid_share_count++)) ) {
548 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
552 break;
554 case 2:
555 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
556 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
558 ctr.ctr2->count = alloc_entries;
559 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
560 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
562 for (snum = 0; snum < num_services; snum++) {
563 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
564 (resume_handle <= (i + valid_share_count++)) ) {
565 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
569 break;
571 case 501:
572 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
573 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
575 ctr.ctr501->count = alloc_entries;
576 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
577 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
579 for (snum = 0; snum < num_services; snum++) {
580 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
581 (resume_handle <= (i + valid_share_count++)) ) {
582 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
586 break;
588 case 502:
589 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
590 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
592 ctr.ctr502->count = alloc_entries;
593 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
594 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
596 for (snum = 0; snum < num_services; snum++) {
597 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
598 (resume_handle <= (i + valid_share_count++)) ) {
599 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
603 break;
605 case 1004:
606 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
607 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
609 ctr.ctr1004->count = alloc_entries;
610 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
611 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
613 for (snum = 0; snum < num_services; snum++) {
614 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
615 (resume_handle <= (i + valid_share_count++)) ) {
616 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
620 break;
622 case 1005:
623 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
624 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
626 ctr.ctr1005->count = alloc_entries;
627 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
628 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
630 for (snum = 0; snum < num_services; snum++) {
631 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
632 (resume_handle <= (i + valid_share_count++)) ) {
633 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
637 break;
639 case 1006:
640 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
641 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
643 ctr.ctr1006->count = alloc_entries;
644 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
645 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
647 for (snum = 0; snum < num_services; snum++) {
648 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
649 (resume_handle <= (i + valid_share_count++)) ) {
650 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
654 break;
656 case 1007:
657 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
658 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
660 ctr.ctr1007->count = alloc_entries;
661 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
662 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
664 for (snum = 0; snum < num_services; snum++) {
665 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
666 (resume_handle <= (i + valid_share_count++)) ) {
667 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
671 break;
673 case 1501:
674 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
675 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
677 ctr.ctr1501->count = alloc_entries;
678 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
679 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
681 for (snum = 0; snum < num_services; snum++) {
682 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
683 (resume_handle <= (i + valid_share_count++)) ) {
684 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
688 break;
690 default:
691 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
692 info_ctr->level));
693 return WERR_UNKNOWN_LEVEL;
696 *total_entries = alloc_entries;
697 if (resume_handle_p) {
698 if (all_shares) {
699 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
700 } else {
701 *resume_handle_p = num_entries;
705 info_ctr->ctr = ctr;
707 return WERR_OK;
710 /*******************************************************************
711 fill in a sess info level 0 structure.
712 ********************************************************************/
714 static WERROR init_srv_sess_info_0(pipes_struct *p,
715 struct srvsvc_NetSessCtr0 *ctr0,
716 uint32_t *resume_handle_p,
717 uint32_t *total_entries)
719 struct sessionid *session_list;
720 uint32_t num_entries = 0;
721 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
722 *total_entries = list_sessions(p->mem_ctx, &session_list);
724 DEBUG(5,("init_srv_sess_info_0\n"));
726 if (ctr0 == NULL) {
727 if (resume_handle_p) {
728 *resume_handle_p = 0;
730 return WERR_OK;
733 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
735 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
736 ctr0->array,
737 struct srvsvc_NetSessInfo0,
738 num_entries+1);
739 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
741 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
742 session_list[resume_handle].remote_machine);
743 num_entries++;
746 ctr0->count = num_entries;
748 if (resume_handle_p) {
749 if (*resume_handle_p >= *total_entries) {
750 *resume_handle_p = 0;
751 } else {
752 *resume_handle_p = resume_handle;
756 return WERR_OK;
759 /*******************************************************************
760 ********************************************************************/
762 static void sess_file_fn( const struct share_mode_entry *e,
763 const char *sharepath, const char *fname,
764 void *data )
766 struct sess_file_count *sess = (struct sess_file_count *)data;
768 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
769 sess->count++;
772 return;
775 /*******************************************************************
776 ********************************************************************/
778 static int net_count_files( uid_t uid, struct server_id pid )
780 struct sess_file_count s_file_cnt;
782 s_file_cnt.count = 0;
783 s_file_cnt.uid = uid;
784 s_file_cnt.pid = pid;
786 share_mode_forall( sess_file_fn, &s_file_cnt );
788 return s_file_cnt.count;
791 /*******************************************************************
792 fill in a sess info level 1 structure.
793 ********************************************************************/
795 static WERROR init_srv_sess_info_1(pipes_struct *p,
796 struct srvsvc_NetSessCtr1 *ctr1,
797 uint32_t *resume_handle_p,
798 uint32_t *total_entries)
800 struct sessionid *session_list;
801 uint32_t num_entries = 0;
802 time_t now = time(NULL);
803 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
805 ZERO_STRUCTP(ctr1);
807 if (ctr1 == NULL) {
808 if (resume_handle_p) {
809 *resume_handle_p = 0;
811 return WERR_OK;
814 *total_entries = list_sessions(p->mem_ctx, &session_list);
816 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
817 uint32 num_files;
818 uint32 connect_time;
819 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
820 bool guest;
822 if ( !pw ) {
823 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
824 session_list[resume_handle].username));
825 continue;
828 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
829 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
830 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
832 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
833 ctr1->array,
834 struct srvsvc_NetSessInfo1,
835 num_entries+1);
836 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
838 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
839 session_list[resume_handle].remote_machine,
840 session_list[resume_handle].username,
841 num_files,
842 connect_time,
844 guest);
845 num_entries++;
848 ctr1->count = num_entries;
850 if (resume_handle_p) {
851 if (*resume_handle_p >= *total_entries) {
852 *resume_handle_p = 0;
853 } else {
854 *resume_handle_p = resume_handle;
858 return WERR_OK;
861 /*******************************************************************
862 fill in a conn info level 0 structure.
863 ********************************************************************/
865 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
866 uint32_t *resume_handle_p,
867 uint32_t *total_entries)
869 uint32_t num_entries = 0;
870 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
872 DEBUG(5,("init_srv_conn_info_0\n"));
874 if (ctr0 == NULL) {
875 if (resume_handle_p) {
876 *resume_handle_p = 0;
878 return WERR_OK;
881 *total_entries = 1;
883 ZERO_STRUCTP(ctr0);
885 for (; resume_handle < *total_entries && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
887 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
888 ctr0->array,
889 struct srvsvc_NetConnInfo0,
890 num_entries+1);
891 if (!ctr0->array) {
892 return WERR_NOMEM;
895 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
896 (*total_entries));
898 /* move on to creating next connection */
899 num_entries++;
902 ctr0->count = num_entries;
903 *total_entries = num_entries;
905 if (resume_handle_p) {
906 if (*resume_handle_p >= *total_entries) {
907 *resume_handle_p = 0;
908 } else {
909 *resume_handle_p = resume_handle;
913 return WERR_OK;
916 /*******************************************************************
917 fill in a conn info level 1 structure.
918 ********************************************************************/
920 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
921 uint32_t *resume_handle_p,
922 uint32_t *total_entries)
924 uint32_t num_entries = 0;
925 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
927 DEBUG(5,("init_srv_conn_info_1\n"));
929 if (ctr1 == NULL) {
930 if (resume_handle_p) {
931 *resume_handle_p = 0;
933 return WERR_OK;
936 *total_entries = 1;
938 ZERO_STRUCTP(ctr1);
940 for (; (resume_handle < *total_entries) && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
942 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
943 ctr1->array,
944 struct srvsvc_NetConnInfo1,
945 num_entries+1);
946 if (!ctr1->array) {
947 return WERR_NOMEM;
950 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
951 (*total_entries),
952 0x3,
956 "dummy_user",
957 "IPC$");
959 /* move on to creating next connection */
960 num_entries++;
963 ctr1->count = num_entries;
964 *total_entries = num_entries;
966 if (resume_handle_p) {
967 if (*resume_handle_p >= *total_entries) {
968 *resume_handle_p = 0;
969 } else {
970 *resume_handle_p = resume_handle;
974 return WERR_OK;
977 /*******************************************************************
978 _srvsvc_NetFileEnum
979 *******************************************************************/
981 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
982 struct srvsvc_NetFileEnum *r)
984 TALLOC_CTX *ctx = NULL;
985 struct srvsvc_NetFileCtr3 *ctr3;
986 uint32_t resume_hnd = 0;
987 WERROR werr;
989 switch (r->in.info_ctr->level) {
990 case 3:
991 break;
992 default:
993 return WERR_UNKNOWN_LEVEL;
996 ctx = talloc_tos();
997 ctr3 = r->in.info_ctr->ctr.ctr3;
998 if (!ctr3) {
999 werr = WERR_INVALID_PARAM;
1000 goto done;
1003 /* TODO -- Windows enumerates
1004 (b) active pipes
1005 (c) open directories and files */
1007 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1008 if (!W_ERROR_IS_OK(werr)) {
1009 goto done;
1012 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1013 if (!W_ERROR_IS_OK(werr)) {
1014 goto done;
1017 *r->out.totalentries = ctr3->count;
1018 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1019 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1021 werr = WERR_OK;
1023 done:
1024 return werr;
1027 /*******************************************************************
1028 _srvsvc_NetSrvGetInfo
1029 ********************************************************************/
1031 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1032 struct srvsvc_NetSrvGetInfo *r)
1034 WERROR status = WERR_OK;
1036 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1038 if (!pipe_access_check(p)) {
1039 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1040 return WERR_ACCESS_DENIED;
1043 switch (r->in.level) {
1045 /* Technically level 102 should only be available to
1046 Administrators but there isn't anything super-secret
1047 here, as most of it is made up. */
1049 case 102: {
1050 struct srvsvc_NetSrvInfo102 *info102;
1052 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1053 if (!info102) {
1054 return WERR_NOMEM;
1057 init_srvsvc_NetSrvInfo102(info102,
1058 PLATFORM_ID_NT,
1059 global_myname(),
1060 lp_major_announce_version(),
1061 lp_minor_announce_version(),
1062 lp_default_server_announce(),
1063 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1064 0xffffffff, /* users */
1065 0xf, /* disc */
1066 0, /* hidden */
1067 240, /* announce */
1068 3000, /* announce delta */
1069 100000, /* licenses */
1070 "c:\\"); /* user path */
1071 r->out.info->info102 = info102;
1072 break;
1074 case 101: {
1075 struct srvsvc_NetSrvInfo101 *info101;
1077 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1078 if (!info101) {
1079 return WERR_NOMEM;
1082 init_srvsvc_NetSrvInfo101(info101,
1083 PLATFORM_ID_NT,
1084 global_myname(),
1085 lp_major_announce_version(),
1086 lp_minor_announce_version(),
1087 lp_default_server_announce(),
1088 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1089 r->out.info->info101 = info101;
1090 break;
1092 case 100: {
1093 struct srvsvc_NetSrvInfo100 *info100;
1095 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1096 if (!info100) {
1097 return WERR_NOMEM;
1100 init_srvsvc_NetSrvInfo100(info100,
1101 PLATFORM_ID_NT,
1102 global_myname());
1103 r->out.info->info100 = info100;
1105 break;
1107 default:
1108 status = WERR_UNKNOWN_LEVEL;
1109 break;
1112 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1114 return status;
1117 /*******************************************************************
1118 _srvsvc_NetSrvSetInfo
1119 ********************************************************************/
1121 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1122 struct srvsvc_NetSrvSetInfo *r)
1124 WERROR status = WERR_OK;
1126 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1128 /* Set up the net server set info structure. */
1130 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1132 return status;
1135 /*******************************************************************
1136 _srvsvc_NetConnEnum
1137 ********************************************************************/
1139 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1140 struct srvsvc_NetConnEnum *r)
1142 WERROR werr;
1144 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1146 switch (r->in.info_ctr->level) {
1147 case 0:
1148 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1149 r->in.resume_handle,
1150 r->out.totalentries);
1151 break;
1152 case 1:
1153 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1154 r->in.resume_handle,
1155 r->out.totalentries);
1156 break;
1157 default:
1158 return WERR_UNKNOWN_LEVEL;
1161 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1163 return werr;
1166 /*******************************************************************
1167 _srvsvc_NetSessEnum
1168 ********************************************************************/
1170 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1171 struct srvsvc_NetSessEnum *r)
1173 WERROR werr;
1175 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1177 switch (r->in.info_ctr->level) {
1178 case 0:
1179 werr = init_srv_sess_info_0(p,
1180 r->in.info_ctr->ctr.ctr0,
1181 r->in.resume_handle,
1182 r->out.totalentries);
1183 break;
1184 case 1:
1185 werr = init_srv_sess_info_1(p,
1186 r->in.info_ctr->ctr.ctr1,
1187 r->in.resume_handle,
1188 r->out.totalentries);
1189 break;
1190 default:
1191 return WERR_UNKNOWN_LEVEL;
1194 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1196 return werr;
1199 /*******************************************************************
1200 _srvsvc_NetSessDel
1201 ********************************************************************/
1203 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1204 struct srvsvc_NetSessDel *r)
1206 struct sessionid *session_list;
1207 struct current_user user;
1208 int num_sessions, snum;
1209 const char *username;
1210 const char *machine;
1211 bool not_root = False;
1212 WERROR werr;
1214 username = r->in.user;
1215 machine = r->in.client;
1217 /* strip leading backslashes if any */
1218 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1219 machine += 2;
1222 num_sessions = list_sessions(p->mem_ctx, &session_list);
1224 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1226 werr = WERR_ACCESS_DENIED;
1228 get_current_user(&user, p);
1230 /* fail out now if you are not root or not a domain admin */
1232 if ((user.ut.uid != sec_initial_uid()) &&
1233 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1235 goto done;
1238 for (snum = 0; snum < num_sessions; snum++) {
1240 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1241 strequal(session_list[snum].remote_machine, machine)) {
1243 NTSTATUS ntstat;
1245 if (user.ut.uid != sec_initial_uid()) {
1246 not_root = True;
1247 become_root();
1250 ntstat = messaging_send(smbd_messaging_context(),
1251 session_list[snum].pid,
1252 MSG_SHUTDOWN, &data_blob_null);
1254 if (NT_STATUS_IS_OK(ntstat))
1255 werr = WERR_OK;
1257 if (not_root)
1258 unbecome_root();
1262 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1264 done:
1266 return werr;
1269 /*******************************************************************
1270 _srvsvc_NetShareEnumAll
1271 ********************************************************************/
1273 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1274 struct srvsvc_NetShareEnumAll *r)
1276 WERROR werr;
1278 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1280 if (!pipe_access_check(p)) {
1281 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1282 return WERR_ACCESS_DENIED;
1285 /* Create the list of shares for the response. */
1286 werr = init_srv_share_info_ctr(p,
1287 r->in.info_ctr,
1288 r->in.resume_handle,
1289 r->out.totalentries,
1290 true);
1292 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1294 return werr;
1297 /*******************************************************************
1298 _srvsvc_NetShareEnum
1299 ********************************************************************/
1301 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1302 struct srvsvc_NetShareEnum *r)
1304 WERROR werr;
1306 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1308 if (!pipe_access_check(p)) {
1309 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1310 return WERR_ACCESS_DENIED;
1313 /* Create the list of shares for the response. */
1314 werr = init_srv_share_info_ctr(p,
1315 r->in.info_ctr,
1316 r->in.resume_handle,
1317 r->out.totalentries,
1318 false);
1320 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1322 return werr;
1325 /*******************************************************************
1326 _srvsvc_NetShareGetInfo
1327 ********************************************************************/
1329 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1330 struct srvsvc_NetShareGetInfo *r)
1332 WERROR status = WERR_OK;
1333 fstring share_name;
1334 int snum;
1335 union srvsvc_NetShareInfo *info = r->out.info;
1337 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1339 fstrcpy(share_name, r->in.share_name);
1341 snum = find_service(share_name);
1342 if (snum < 0) {
1343 return WERR_INVALID_NAME;
1346 switch (r->in.level) {
1347 case 0:
1348 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1349 W_ERROR_HAVE_NO_MEMORY(info->info0);
1350 init_srv_share_info_0(p, info->info0, snum);
1351 break;
1352 case 1:
1353 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1354 W_ERROR_HAVE_NO_MEMORY(info->info1);
1355 init_srv_share_info_1(p, info->info1, snum);
1356 break;
1357 case 2:
1358 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1359 W_ERROR_HAVE_NO_MEMORY(info->info2);
1360 init_srv_share_info_2(p, info->info2, snum);
1361 break;
1362 case 501:
1363 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1364 W_ERROR_HAVE_NO_MEMORY(info->info501);
1365 init_srv_share_info_501(p, info->info501, snum);
1366 break;
1367 case 502:
1368 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1369 W_ERROR_HAVE_NO_MEMORY(info->info502);
1370 init_srv_share_info_502(p, info->info502, snum);
1371 break;
1372 case 1004:
1373 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1374 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1375 init_srv_share_info_1004(p, info->info1004, snum);
1376 break;
1377 case 1005:
1378 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1379 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1380 init_srv_share_info_1005(p, info->info1005, snum);
1381 break;
1382 case 1006:
1383 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1384 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1385 init_srv_share_info_1006(p, info->info1006, snum);
1386 break;
1387 case 1007:
1388 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1389 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1390 init_srv_share_info_1007(p, info->info1007, snum);
1391 break;
1392 case 1501:
1393 init_srv_share_info_1501(p, info->info1501, snum);
1394 break;
1395 default:
1396 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1397 r->in.level));
1398 status = WERR_UNKNOWN_LEVEL;
1399 break;
1402 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1404 return status;
1407 /*******************************************************************
1408 Check a given DOS pathname is valid for a share.
1409 ********************************************************************/
1411 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1413 char *ptr = NULL;
1415 if (!dos_pathname) {
1416 return NULL;
1419 ptr = talloc_strdup(ctx, dos_pathname);
1420 if (!ptr) {
1421 return NULL;
1423 /* Convert any '\' paths to '/' */
1424 unix_format(ptr);
1425 ptr = unix_clean_name(ctx, ptr);
1426 if (!ptr) {
1427 return NULL;
1430 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1431 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1432 ptr += 2;
1434 /* Only absolute paths allowed. */
1435 if (*ptr != '/')
1436 return NULL;
1438 return ptr;
1441 /*******************************************************************
1442 _srvsvc_NetShareSetInfo. Modify share details.
1443 ********************************************************************/
1445 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1446 struct srvsvc_NetShareSetInfo *r)
1448 struct current_user user;
1449 char *command = NULL;
1450 char *share_name = NULL;
1451 char *comment = NULL;
1452 const char *pathname = NULL;
1453 int type;
1454 int snum;
1455 int ret;
1456 char *path = NULL;
1457 SEC_DESC *psd = NULL;
1458 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1459 bool is_disk_op = False;
1460 int max_connections = 0;
1461 TALLOC_CTX *ctx = p->mem_ctx;
1462 union srvsvc_NetShareInfo *info = r->in.info;
1464 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1466 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1467 if (!share_name) {
1468 return WERR_NOMEM;
1471 *r->out.parm_error = 0;
1473 if ( strequal(share_name,"IPC$")
1474 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1475 || strequal(share_name,"global") )
1477 return WERR_ACCESS_DENIED;
1480 snum = find_service(share_name);
1482 /* Does this share exist ? */
1483 if (snum < 0)
1484 return WERR_NET_NAME_NOT_FOUND;
1486 /* No change to printer shares. */
1487 if (lp_print_ok(snum))
1488 return WERR_ACCESS_DENIED;
1490 get_current_user(&user,p);
1492 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1494 /* fail out now if you are not root and not a disk op */
1496 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1497 return WERR_ACCESS_DENIED;
1499 switch (r->in.level) {
1500 case 1:
1501 pathname = talloc_strdup(ctx, lp_pathname(snum));
1502 comment = talloc_strdup(ctx, info->info2->comment);
1503 type = info->info2->type;
1504 psd = NULL;
1505 break;
1506 case 2:
1507 comment = talloc_strdup(ctx, info->info2->comment);
1508 pathname = info->info2->path;
1509 type = info->info2->type;
1510 max_connections = (info->info2->max_users == 0xffffffff) ?
1511 0 : info->info2->max_users;
1512 psd = NULL;
1513 break;
1514 #if 0
1515 /* not supported on set but here for completeness */
1516 case 501:
1517 comment = talloc_strdup(ctx, info->info501->comment);
1518 type = info->info501->type;
1519 psd = NULL;
1520 break;
1521 #endif
1522 case 502:
1523 comment = talloc_strdup(ctx, info->info502->comment);
1524 pathname = info->info502->path;
1525 type = info->info502->type;
1526 psd = info->info502->sd;
1527 map_generic_share_sd_bits(psd);
1528 break;
1529 case 1004:
1530 pathname = talloc_strdup(ctx, lp_pathname(snum));
1531 comment = talloc_strdup(ctx, info->info1004->comment);
1532 type = STYPE_DISKTREE;
1533 break;
1534 case 1005:
1535 /* XP re-sets the csc policy even if it wasn't changed by the
1536 user, so we must compare it to see if it's what is set in
1537 smb.conf, so that we can contine other ops like setting
1538 ACLs on a share */
1539 if (((info->info1005->dfs_flags &
1540 SHARE_1005_CSC_POLICY_MASK) >>
1541 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1542 return WERR_OK;
1543 else {
1544 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1545 return WERR_ACCESS_DENIED;
1547 case 1006:
1548 case 1007:
1549 return WERR_ACCESS_DENIED;
1550 case 1501:
1551 pathname = talloc_strdup(ctx, lp_pathname(snum));
1552 comment = talloc_strdup(ctx, lp_comment(snum));
1553 psd = info->info1501->sd;
1554 map_generic_share_sd_bits(psd);
1555 type = STYPE_DISKTREE;
1556 break;
1557 default:
1558 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1559 r->in.level));
1560 return WERR_UNKNOWN_LEVEL;
1563 /* We can only modify disk shares. */
1564 if (type != STYPE_DISKTREE)
1565 return WERR_ACCESS_DENIED;
1567 /* Check if the pathname is valid. */
1568 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1569 return WERR_OBJECT_PATH_INVALID;
1571 /* Ensure share name, pathname and comment don't contain '"' characters. */
1572 string_replace(share_name, '"', ' ');
1573 string_replace(path, '"', ' ');
1574 if (comment) {
1575 string_replace(comment, '"', ' ');
1578 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1579 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1581 /* Only call modify function if something changed. */
1583 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1584 || (lp_max_connections(snum) != max_connections)) {
1585 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1586 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1587 return WERR_ACCESS_DENIED;
1590 command = talloc_asprintf(p->mem_ctx,
1591 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1592 lp_change_share_cmd(),
1593 get_dyn_CONFIGFILE(),
1594 share_name,
1595 path,
1596 comment ? comment : "",
1597 max_connections);
1598 if (!command) {
1599 return WERR_NOMEM;
1602 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1604 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1606 if (is_disk_op)
1607 become_root();
1609 if ( (ret = smbrun(command, NULL)) == 0 ) {
1610 /* Tell everyone we updated smb.conf. */
1611 message_send_all(smbd_messaging_context(),
1612 MSG_SMB_CONF_UPDATED, NULL, 0,
1613 NULL);
1616 if ( is_disk_op )
1617 unbecome_root();
1619 /********* END SeDiskOperatorPrivilege BLOCK *********/
1621 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1622 command, ret ));
1624 TALLOC_FREE(command);
1626 if ( ret != 0 )
1627 return WERR_ACCESS_DENIED;
1628 } else {
1629 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1630 share_name ));
1633 /* Replace SD if changed. */
1634 if (psd) {
1635 SEC_DESC *old_sd;
1636 size_t sd_size;
1638 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1640 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1641 if (!set_share_security(share_name, psd))
1642 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1643 share_name ));
1647 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1649 return WERR_OK;
1652 /*******************************************************************
1653 _srvsvc_NetShareAdd.
1654 Call 'add_share_command "sharename" "pathname"
1655 "comment" "max connections = "
1656 ********************************************************************/
1658 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1659 struct srvsvc_NetShareAdd *r)
1661 struct current_user user;
1662 char *command = NULL;
1663 char *share_name = NULL;
1664 char *comment = NULL;
1665 char *pathname = NULL;
1666 int type;
1667 int snum;
1668 int ret;
1669 char *path;
1670 SEC_DESC *psd = NULL;
1671 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1672 bool is_disk_op;
1673 int max_connections = 0;
1674 TALLOC_CTX *ctx = p->mem_ctx;
1676 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1678 *r->out.parm_error = 0;
1680 get_current_user(&user,p);
1682 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1684 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1685 return WERR_ACCESS_DENIED;
1687 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1688 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1689 return WERR_ACCESS_DENIED;
1692 switch (r->in.level) {
1693 case 0:
1694 /* No path. Not enough info in a level 0 to do anything. */
1695 return WERR_ACCESS_DENIED;
1696 case 1:
1697 /* Not enough info in a level 1 to do anything. */
1698 return WERR_ACCESS_DENIED;
1699 case 2:
1700 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1701 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1702 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1703 max_connections = (r->in.info->info2->max_users == 0xffffffff) ?
1704 0 : r->in.info->info2->max_users;
1705 type = r->in.info->info2->type;
1706 break;
1707 case 501:
1708 /* No path. Not enough info in a level 501 to do anything. */
1709 return WERR_ACCESS_DENIED;
1710 case 502:
1711 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1712 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1713 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1714 max_connections = (r->in.info->info502->max_users == 0xffffffff) ?
1715 0 : r->in.info->info502->max_users;
1716 type = r->in.info->info502->type;
1717 psd = r->in.info->info502->sd;
1718 map_generic_share_sd_bits(psd);
1719 break;
1721 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1723 case 1004:
1724 case 1005:
1725 case 1006:
1726 case 1007:
1727 return WERR_ACCESS_DENIED;
1728 case 1501:
1729 /* DFS only level. */
1730 return WERR_ACCESS_DENIED;
1731 default:
1732 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1733 r->in.level));
1734 return WERR_UNKNOWN_LEVEL;
1737 /* check for invalid share names */
1739 if (!share_name || !validate_net_name(share_name,
1740 INVALID_SHARENAME_CHARS,
1741 strlen(share_name))) {
1742 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1743 share_name ? share_name : ""));
1744 return WERR_INVALID_NAME;
1747 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1748 || (lp_enable_asu_support() &&
1749 strequal(share_name,"ADMIN$"))) {
1750 return WERR_ACCESS_DENIED;
1753 snum = find_service(share_name);
1755 /* Share already exists. */
1756 if (snum >= 0) {
1757 return WERR_ALREADY_EXISTS;
1760 /* We can only add disk shares. */
1761 if (type != STYPE_DISKTREE) {
1762 return WERR_ACCESS_DENIED;
1765 /* Check if the pathname is valid. */
1766 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1767 return WERR_OBJECT_PATH_INVALID;
1770 /* Ensure share name, pathname and comment don't contain '"' characters. */
1771 string_replace(share_name, '"', ' ');
1772 string_replace(path, '"', ' ');
1773 if (comment) {
1774 string_replace(comment, '"', ' ');
1777 command = talloc_asprintf(ctx,
1778 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1779 lp_add_share_cmd(),
1780 get_dyn_CONFIGFILE(),
1781 share_name,
1782 path,
1783 comment ? comment : "",
1784 max_connections);
1785 if (!command) {
1786 return WERR_NOMEM;
1789 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1791 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1793 if ( is_disk_op )
1794 become_root();
1796 /* FIXME: use libnetconf here - gd */
1798 if ( (ret = smbrun(command, NULL)) == 0 ) {
1799 /* Tell everyone we updated smb.conf. */
1800 message_send_all(smbd_messaging_context(),
1801 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1804 if ( is_disk_op )
1805 unbecome_root();
1807 /********* END SeDiskOperatorPrivilege BLOCK *********/
1809 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1810 command, ret ));
1812 TALLOC_FREE(command);
1814 if ( ret != 0 )
1815 return WERR_ACCESS_DENIED;
1817 if (psd) {
1818 if (!set_share_security(share_name, psd)) {
1819 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1820 share_name ));
1825 * We don't call reload_services() here, the message will
1826 * cause this to be done before the next packet is read
1827 * from the client. JRA.
1830 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1832 return WERR_OK;
1835 /*******************************************************************
1836 _srvsvc_NetShareDel
1837 Call "delete share command" with the share name as
1838 a parameter.
1839 ********************************************************************/
1841 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1842 struct srvsvc_NetShareDel *r)
1844 struct current_user user;
1845 char *command = NULL;
1846 char *share_name = NULL;
1847 int ret;
1848 int snum;
1849 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1850 bool is_disk_op;
1851 struct share_params *params;
1852 TALLOC_CTX *ctx = p->mem_ctx;
1854 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1856 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1857 if (!share_name) {
1858 return WERR_NET_NAME_NOT_FOUND;
1860 if ( strequal(share_name,"IPC$")
1861 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1862 || strequal(share_name,"global") )
1864 return WERR_ACCESS_DENIED;
1867 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1868 return WERR_NO_SUCH_SHARE;
1871 snum = find_service(share_name);
1873 /* No change to printer shares. */
1874 if (lp_print_ok(snum))
1875 return WERR_ACCESS_DENIED;
1877 get_current_user(&user,p);
1879 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1881 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1882 return WERR_ACCESS_DENIED;
1884 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1885 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1886 return WERR_ACCESS_DENIED;
1889 command = talloc_asprintf(ctx,
1890 "%s \"%s\" \"%s\"",
1891 lp_delete_share_cmd(),
1892 get_dyn_CONFIGFILE(),
1893 lp_servicename(snum));
1894 if (!command) {
1895 return WERR_NOMEM;
1898 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1900 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1902 if ( is_disk_op )
1903 become_root();
1905 if ( (ret = smbrun(command, NULL)) == 0 ) {
1906 /* Tell everyone we updated smb.conf. */
1907 message_send_all(smbd_messaging_context(),
1908 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1911 if ( is_disk_op )
1912 unbecome_root();
1914 /********* END SeDiskOperatorPrivilege BLOCK *********/
1916 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1918 if ( ret != 0 )
1919 return WERR_ACCESS_DENIED;
1921 /* Delete the SD in the database. */
1922 delete_share_security(lp_servicename(params->service));
1924 lp_killservice(params->service);
1926 return WERR_OK;
1929 /*******************************************************************
1930 _srvsvc_NetShareDelSticky
1931 ********************************************************************/
1933 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1934 struct srvsvc_NetShareDelSticky *r)
1936 struct srvsvc_NetShareDel q;
1938 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1940 q.in.server_unc = r->in.server_unc;
1941 q.in.share_name = r->in.share_name;
1942 q.in.reserved = r->in.reserved;
1944 return _srvsvc_NetShareDel(p, &q);
1947 /*******************************************************************
1948 _srvsvc_NetRemoteTOD
1949 ********************************************************************/
1951 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1952 struct srvsvc_NetRemoteTOD *r)
1954 struct srvsvc_NetRemoteTODInfo *tod;
1955 struct tm *t;
1956 time_t unixdate = time(NULL);
1958 /* We do this call first as if we do it *after* the gmtime call
1959 it overwrites the pointed-to values. JRA */
1961 uint32 zone = get_time_zone(unixdate)/60;
1963 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1965 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1966 return WERR_NOMEM;
1968 *r->out.info = tod;
1970 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1972 t = gmtime(&unixdate);
1974 /* set up the */
1975 init_srvsvc_NetRemoteTODInfo(tod,
1976 unixdate,
1978 t->tm_hour,
1979 t->tm_min,
1980 t->tm_sec,
1982 zone,
1983 10000,
1984 t->tm_mday,
1985 t->tm_mon + 1,
1986 1900+t->tm_year,
1987 t->tm_wday);
1989 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1991 return WERR_OK;
1994 /***********************************************************************************
1995 _srvsvc_NetGetFileSecurity
1996 Win9x NT tools get security descriptor.
1997 ***********************************************************************************/
1999 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2000 struct srvsvc_NetGetFileSecurity *r)
2002 SEC_DESC *psd = NULL;
2003 size_t sd_size;
2004 DATA_BLOB null_pw;
2005 char *filename_in = NULL;
2006 char *filename = NULL;
2007 char *qualname = NULL;
2008 SMB_STRUCT_STAT st;
2009 NTSTATUS nt_status;
2010 WERROR werr;
2011 struct current_user user;
2012 connection_struct *conn = NULL;
2013 bool became_user = False;
2014 TALLOC_CTX *ctx = p->mem_ctx;
2015 struct sec_desc_buf *sd_buf;
2017 ZERO_STRUCT(st);
2019 werr = WERR_OK;
2021 qualname = talloc_strdup(ctx, r->in.share);
2022 if (!qualname) {
2023 werr = WERR_ACCESS_DENIED;
2024 goto error_exit;
2027 /* Null password is ok - we are already an authenticated user... */
2028 null_pw = data_blob_null;
2030 get_current_user(&user, p);
2032 become_root();
2033 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2034 unbecome_root();
2036 if (conn == NULL) {
2037 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2038 qualname));
2039 werr = ntstatus_to_werror(nt_status);
2040 goto error_exit;
2043 if (!become_user(conn, conn->vuid)) {
2044 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2045 werr = WERR_ACCESS_DENIED;
2046 goto error_exit;
2048 became_user = True;
2050 filename_in = talloc_strdup(ctx, r->in.file);
2051 if (!filename_in) {
2052 werr = WERR_ACCESS_DENIED;
2053 goto error_exit;
2056 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2057 if (!NT_STATUS_IS_OK(nt_status)) {
2058 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2059 filename));
2060 werr = WERR_ACCESS_DENIED;
2061 goto error_exit;
2064 nt_status = check_name(conn, filename);
2065 if (!NT_STATUS_IS_OK(nt_status)) {
2066 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2067 filename));
2068 werr = WERR_ACCESS_DENIED;
2069 goto error_exit;
2072 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2073 (OWNER_SECURITY_INFORMATION
2074 |GROUP_SECURITY_INFORMATION
2075 |DACL_SECURITY_INFORMATION), &psd);
2077 if (!NT_STATUS_IS_OK(nt_status)) {
2078 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2079 filename));
2080 werr = ntstatus_to_werror(nt_status);
2081 goto error_exit;
2084 sd_size = ndr_size_security_descriptor(psd, 0);
2086 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2087 if (!sd_buf) {
2088 werr = WERR_NOMEM;
2089 goto error_exit;
2092 sd_buf->sd_size = sd_size;
2093 sd_buf->sd = psd;
2095 *r->out.sd_buf = sd_buf;
2097 psd->dacl->revision = NT4_ACL_REVISION;
2099 unbecome_user();
2100 close_cnum(conn, user.vuid);
2101 return werr;
2103 error_exit:
2105 if (became_user)
2106 unbecome_user();
2108 if (conn)
2109 close_cnum(conn, user.vuid);
2111 return werr;
2114 /***********************************************************************************
2115 _srvsvc_NetSetFileSecurity
2116 Win9x NT tools set security descriptor.
2117 ***********************************************************************************/
2119 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2120 struct srvsvc_NetSetFileSecurity *r)
2122 char *filename_in = NULL;
2123 char *filename = NULL;
2124 char *qualname = NULL;
2125 DATA_BLOB null_pw;
2126 files_struct *fsp = NULL;
2127 SMB_STRUCT_STAT st;
2128 NTSTATUS nt_status;
2129 WERROR werr;
2130 struct current_user user;
2131 connection_struct *conn = NULL;
2132 bool became_user = False;
2133 TALLOC_CTX *ctx = p->mem_ctx;
2135 ZERO_STRUCT(st);
2137 werr = WERR_OK;
2139 qualname = talloc_strdup(ctx, r->in.share);
2140 if (!qualname) {
2141 werr = WERR_ACCESS_DENIED;
2142 goto error_exit;
2145 /* Null password is ok - we are already an authenticated user... */
2146 null_pw = data_blob_null;
2148 get_current_user(&user, p);
2150 become_root();
2151 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2152 unbecome_root();
2154 if (conn == NULL) {
2155 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2156 werr = ntstatus_to_werror(nt_status);
2157 goto error_exit;
2160 if (!become_user(conn, conn->vuid)) {
2161 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2162 werr = WERR_ACCESS_DENIED;
2163 goto error_exit;
2165 became_user = True;
2167 filename_in = talloc_strdup(ctx, r->in.file);
2168 if (!filename_in) {
2169 werr = WERR_ACCESS_DENIED;
2170 goto error_exit;
2173 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2174 if (!NT_STATUS_IS_OK(nt_status)) {
2175 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2176 werr = WERR_ACCESS_DENIED;
2177 goto error_exit;
2180 nt_status = check_name(conn, filename);
2181 if (!NT_STATUS_IS_OK(nt_status)) {
2182 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2183 werr = WERR_ACCESS_DENIED;
2184 goto error_exit;
2187 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2189 if ( !NT_STATUS_IS_OK(nt_status) ) {
2190 /* Perhaps it is a directory */
2191 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2192 nt_status = open_directory(conn, NULL, filename, &st,
2193 FILE_READ_ATTRIBUTES,
2194 FILE_SHARE_READ|FILE_SHARE_WRITE,
2195 FILE_OPEN,
2197 FILE_ATTRIBUTE_DIRECTORY,
2198 NULL, &fsp);
2200 if ( !NT_STATUS_IS_OK(nt_status) ) {
2201 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2202 werr = ntstatus_to_werror(nt_status);
2203 goto error_exit;
2207 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2208 r->in.securityinformation,
2209 r->in.sd_buf->sd);
2211 if (!NT_STATUS_IS_OK(nt_status) ) {
2212 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2213 werr = WERR_ACCESS_DENIED;
2214 goto error_exit;
2217 close_file(fsp, NORMAL_CLOSE);
2218 unbecome_user();
2219 close_cnum(conn, user.vuid);
2220 return werr;
2222 error_exit:
2224 if(fsp) {
2225 close_file(fsp, NORMAL_CLOSE);
2228 if (became_user) {
2229 unbecome_user();
2232 if (conn) {
2233 close_cnum(conn, user.vuid);
2236 return werr;
2239 /***********************************************************************************
2240 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2241 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2242 These disks would the disks listed by this function.
2243 Users could then create shares relative to these disks. Watch out for moving these disks around.
2244 "Nigel Williams" <nigel@veritas.com>.
2245 ***********************************************************************************/
2247 static const char *server_disks[] = {"C:"};
2249 static uint32 get_server_disk_count(void)
2251 return sizeof(server_disks)/sizeof(server_disks[0]);
2254 static uint32 init_server_disk_enum(uint32 *resume)
2256 uint32 server_disk_count = get_server_disk_count();
2258 /*resume can be an offset into the list for now*/
2260 if(*resume & 0x80000000)
2261 *resume = 0;
2263 if(*resume > server_disk_count)
2264 *resume = server_disk_count;
2266 return server_disk_count - *resume;
2269 static const char *next_server_disk_enum(uint32 *resume)
2271 const char *disk;
2273 if(init_server_disk_enum(resume) == 0)
2274 return NULL;
2276 disk = server_disks[*resume];
2278 (*resume)++;
2280 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2282 return disk;
2285 /********************************************************************
2286 _srvsvc_NetDiskEnum
2287 ********************************************************************/
2289 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2290 struct srvsvc_NetDiskEnum *r)
2292 uint32 i;
2293 const char *disk_name;
2294 TALLOC_CTX *ctx = p->mem_ctx;
2295 WERROR werr;
2296 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2298 werr = WERR_OK;
2300 *r->out.totalentries = init_server_disk_enum(&resume);
2302 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2303 MAX_SERVER_DISK_ENTRIES);
2304 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2306 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2308 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2310 r->out.info->count++;
2312 /*copy disk name into a unicode string*/
2314 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2315 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2318 /* add a terminating null string. Is this there if there is more data to come? */
2320 r->out.info->count++;
2322 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2323 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2325 if (r->out.resume_handle) {
2326 *r->out.resume_handle = resume;
2329 return werr;
2332 /********************************************************************
2333 _srvsvc_NetNameValidate
2334 ********************************************************************/
2336 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2337 struct srvsvc_NetNameValidate *r)
2339 switch (r->in.name_type) {
2340 case 0x9:
2341 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2342 strlen_m(r->in.name)))
2344 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2345 r->in.name));
2346 return WERR_INVALID_NAME;
2348 break;
2350 default:
2351 return WERR_UNKNOWN_LEVEL;
2354 return WERR_OK;
2357 /********************************************************************
2358 ********************************************************************/
2360 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2362 return WERR_ACCESS_DENIED;
2366 /********************************************************************
2367 ********************************************************************/
2369 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2371 p->rng_fault_state = True;
2372 return WERR_NOT_SUPPORTED;
2375 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2377 p->rng_fault_state = True;
2378 return WERR_NOT_SUPPORTED;
2381 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2383 p->rng_fault_state = True;
2384 return WERR_NOT_SUPPORTED;
2387 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2389 p->rng_fault_state = True;
2390 return WERR_NOT_SUPPORTED;
2393 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2395 p->rng_fault_state = True;
2396 return WERR_NOT_SUPPORTED;
2399 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2401 p->rng_fault_state = True;
2402 return WERR_NOT_SUPPORTED;
2405 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2407 p->rng_fault_state = True;
2408 return WERR_NOT_SUPPORTED;
2411 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2413 p->rng_fault_state = True;
2414 return WERR_NOT_SUPPORTED;
2417 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2419 p->rng_fault_state = True;
2420 return WERR_NOT_SUPPORTED;
2423 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2425 p->rng_fault_state = True;
2426 return WERR_NOT_SUPPORTED;
2429 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2431 p->rng_fault_state = True;
2432 return WERR_NOT_SUPPORTED;
2435 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2437 p->rng_fault_state = True;
2438 return WERR_NOT_SUPPORTED;
2441 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2443 p->rng_fault_state = True;
2444 return WERR_NOT_SUPPORTED;
2447 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2449 p->rng_fault_state = True;
2450 return WERR_NOT_SUPPORTED;
2453 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2455 p->rng_fault_state = True;
2456 return WERR_NOT_SUPPORTED;
2459 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2461 p->rng_fault_state = True;
2462 return WERR_NOT_SUPPORTED;
2465 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2467 p->rng_fault_state = True;
2468 return WERR_NOT_SUPPORTED;
2471 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2473 p->rng_fault_state = True;
2474 return WERR_NOT_SUPPORTED;
2477 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2479 p->rng_fault_state = True;
2480 return WERR_NOT_SUPPORTED;
2483 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2485 p->rng_fault_state = True;
2486 return WERR_NOT_SUPPORTED;
2489 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2491 p->rng_fault_state = True;
2492 return WERR_NOT_SUPPORTED;
2495 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2497 p->rng_fault_state = True;
2498 return WERR_NOT_SUPPORTED;
2501 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2503 p->rng_fault_state = True;
2504 return WERR_NOT_SUPPORTED;
2507 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2509 p->rng_fault_state = True;
2510 return WERR_NOT_SUPPORTED;
2513 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2515 p->rng_fault_state = True;
2516 return WERR_NOT_SUPPORTED;
2519 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2521 p->rng_fault_state = True;
2522 return WERR_NOT_SUPPORTED;
2525 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2527 p->rng_fault_state = True;
2528 return WERR_NOT_SUPPORTED;
2531 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2533 p->rng_fault_state = True;
2534 return WERR_NOT_SUPPORTED;
2537 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2539 p->rng_fault_state = True;
2540 return WERR_NOT_SUPPORTED;
2543 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2545 p->rng_fault_state = True;
2546 return WERR_NOT_SUPPORTED;
2549 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2555 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2557 p->rng_fault_state = True;
2558 return WERR_NOT_SUPPORTED;
2561 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2563 p->rng_fault_state = True;
2564 return WERR_NOT_SUPPORTED;
2567 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2569 p->rng_fault_state = True;
2570 return WERR_NOT_SUPPORTED;
2573 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2575 p->rng_fault_state = True;
2576 return WERR_NOT_SUPPORTED;